├── .gitignore ├── Category ├── AVAsset │ ├── AVAsset+JKRVideoSize.h │ └── AVAsset+JKRVideoSize.m ├── AppDelegate │ ├── AppDelegate+JKRADPage.h │ ├── AppDelegate+JKRADPage.m │ ├── AppDelegate+JKRConfigNavigation.h │ ├── AppDelegate+JKRConfigNavigation.m │ ├── AppDelegate+JKRRootViewController.h │ └── AppDelegate+JKRRootViewController.m ├── KVO │ ├── NSObject+JKR_Observer.h │ └── NSObject+JKR_Observer.m ├── NSDate │ ├── NSDate+JKRDate.h │ └── NSDate+JKRDate.m ├── NSObject │ ├── NSObject+JKRTryMethod.h │ ├── NSObject+JKRTryMethod.m │ ├── NSObject+JKR_RunTime.h │ └── NSObject+JKR_RunTime.m ├── NSString │ ├── NSAttributedString+JKRSize.h │ ├── NSAttributedString+JKRSize.m │ ├── NSString+JKRFile.h │ ├── NSString+JKRFile.m │ ├── NSString+JKRFilter.h │ ├── NSString+JKRFilter.m │ ├── NSString+JKRMD5.h │ ├── NSString+JKRMD5.m │ ├── NSString+JKRRegular.h │ ├── NSString+JKRRegular.m │ ├── NSString+JKRSize.h │ ├── NSString+JKRSize.m │ ├── NSString+URLComponents.h │ └── NSString+URLComponents.m ├── NSURL │ ├── NSURL+JKRFileSize.h │ ├── NSURL+JKRFileSize.m │ ├── NSURL+JKRVideo.h │ └── NSURL+JKRVideo.m ├── PHAsset │ ├── PHAsset+JKRMovieURL.h │ └── PHAsset+JKRMovieURL.m ├── UIColor │ ├── UIColor+JKRColor.h │ └── UIColor+JKRColor.m ├── UIGestureRecognizer │ ├── UIGestureRecognizer+JKRTouch.h │ └── UIGestureRecognizer+JKRTouch.m ├── UIImage │ ├── UIImage+JKRBlur.h │ ├── UIImage+JKRBlur.m │ ├── UIImage+JKRImage.h │ ├── UIImage+JKRImage.m │ ├── UIImage+JKRRender.h │ ├── UIImage+JKRRender.m │ ├── UIImage+JKR_MessageImage.h │ ├── UIImage+JKR_MessageImage.m │ ├── UIImageView+JKRImagesAnimation.h │ └── UIImageView+JKRImagesAnimation.m ├── UINavigationBar │ ├── UINavigationBar+JKRBottomLine.h │ └── UINavigationBar+JKRBottomLine.m ├── UINavigationController │ ├── UINavigationController+JKRBackButton.h │ ├── UINavigationController+JKRBackButton.m │ ├── UINavigationController+JKRStatusBar.h │ └── UINavigationController+JKRStatusBar.m ├── UIResponder │ ├── UIView+JKR_HitTest.h │ └── UIView+JKR_HitTest.m ├── UITableView │ ├── UITableView+JKREmptyView.h │ └── UITableView+JKREmptyView.m ├── UITextField │ ├── UITextField+JKRFilter.h │ └── UITextField+JKRFilter.m ├── UITextView │ ├── UITextView+JKRPlaceHolder.h │ └── UITextView+JKRPlaceHolder.m ├── UIView │ ├── UIView+JKRFrame.h │ ├── UIView+JKRFrame.m │ ├── UIView+JKRSnap.h │ ├── UIView+JKRSnap.m │ ├── UIView+JKRTapGestureRecognizer.h │ ├── UIView+JKRTapGestureRecognizer.m │ ├── UIView+JKRTouch.h │ ├── UIView+JKRTouch.m │ ├── UIView+JKRViewController.h │ └── UIView+JKRViewController.m └── UIViewController │ ├── UIViewController+JKRStatusBarStyle.h │ └── UIViewController+JKRStatusBarStyle.m └── JKRCategoryDemo ├── JKRCategoryDemo.xcodeproj ├── project.pbxproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── JKRCategoryDemo.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── JKRCategoryDemo ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── ahud1.imageset │ │ ├── Contents.json │ │ ├── ahud1@2x.png │ │ └── ahud1@3x.png │ ├── ahud10.imageset │ │ ├── Contents.json │ │ ├── ahud10@2x.png │ │ └── ahud10@3x.png │ ├── ahud11.imageset │ │ ├── Contents.json │ │ ├── ahud11@2x.png │ │ └── ahud11@3x.png │ ├── ahud12.imageset │ │ ├── Contents.json │ │ ├── ahud12@2x.png │ │ └── ahud12@3x.png │ ├── ahud2.imageset │ │ ├── Contents.json │ │ ├── ahud2@2x.png │ │ └── ahud2@3x.png │ ├── ahud3.imageset │ │ ├── Contents.json │ │ ├── ahud3@2x.png │ │ └── ahud3@3x.png │ ├── ahud4.imageset │ │ ├── Contents.json │ │ ├── ahud4@2x.png │ │ └── ahud4@3x.png │ ├── ahud5.imageset │ │ ├── Contents.json │ │ ├── ahud5@2x.png │ │ └── ahud5@3x.png │ ├── ahud6.imageset │ │ ├── Contents.json │ │ ├── ahud6@2x.png │ │ └── ahud6@3x.png │ ├── ahud7.imageset │ │ ├── Contents.json │ │ ├── ahud7@2x.png │ │ └── ahud7@3x.png │ ├── ahud8.imageset │ │ ├── Contents.json │ │ ├── ahud8@2x.png │ │ └── ahud8@3x.png │ ├── ahud9.imageset │ │ ├── Contents.json │ │ ├── ahud9@2x.png │ │ └── ahud9@3x.png │ ├── contentItemDefault.imageset │ │ ├── Contents.json │ │ ├── contentItemDefault@2x.png │ │ └── contentItemDefault@3x.png │ └── timg.imageset │ │ ├── Contents.json │ │ └── timg.png ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── Prefix.h ├── ViewController.h ├── ViewController.m └── main.m ├── JKRCategoryDemoTests ├── Info.plist └── JKRCategoryDemoTests.m ├── JKRCategoryDemoUITests ├── Info.plist └── JKRCategoryDemoUITests.m ├── Podfile ├── Podfile.lock └── Pods ├── Manifest.lock ├── Pods.xcodeproj └── project.pbxproj └── Target Support Files └── Pods-JKRCategoryDemo ├── Pods-JKRCategoryDemo-acknowledgements.markdown ├── Pods-JKRCategoryDemo-acknowledgements.plist ├── Pods-JKRCategoryDemo-dummy.m ├── Pods-JKRCategoryDemo-frameworks.sh ├── Pods-JKRCategoryDemo-resources.sh ├── Pods-JKRCategoryDemo.debug.xcconfig └── Pods-JKRCategoryDemo.release.xcconfig /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | .DS_Store 22 | *.moved-aside 23 | *.xcuserstate 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | # CocoaPods 32 | # 33 | # We recommend against adding the Pods directory to your .gitignore. However 34 | # you should judge for yourself, the pros and cons are mentioned at: 35 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 36 | # 37 | # Pods/ 38 | 39 | # Carthage 40 | # 41 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 42 | # Carthage/Checkouts 43 | 44 | Carthage/Build 45 | 46 | # fastlane 47 | # 48 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 49 | # screenshots whenever they are needed. 50 | # For more information about the recommended setup visit: 51 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 52 | 53 | fastlane/report.xml 54 | fastlane/screenshots 55 | 56 | #Code Injection 57 | # 58 | # After new code Injection tools there's a generated folder /iOSInjectionProject 59 | # https://github.com/johnno1962/injectionforxcode 60 | 61 | iOSInjectionProject/ 62 | -------------------------------------------------------------------------------- /Category/AVAsset/AVAsset+JKRVideoSize.h: -------------------------------------------------------------------------------- 1 | // 2 | // AVAsset+JKRVideoSize.h 3 | // BaoJiDianJing 4 | // 5 | // Created by Lucky on 2018/5/19. 6 | // Copyright © 2018年 KaiHei. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AVAsset (JKRVideoSize) 12 | 13 | /// 获取视频图像尺寸 14 | - (CGSize)videoSize; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Category/AVAsset/AVAsset+JKRVideoSize.m: -------------------------------------------------------------------------------- 1 | // 2 | // AVAsset+JKRVideoSize.m 3 | // BaoJiDianJing 4 | // 5 | // Created by Lucky on 2018/5/19. 6 | // Copyright © 2018年 KaiHei. All rights reserved. 7 | // 8 | 9 | #import "AVAsset+JKRVideoSize.h" 10 | 11 | @implementation AVAsset (JKRVideoSize) 12 | 13 | - (CGSize)videoSize { 14 | NSArray *array = self.tracks; 15 | CGSize videoSize = CGSizeZero; 16 | 17 | for (AVAssetTrack *track in array) { 18 | if ([track.mediaType isEqualToString:AVMediaTypeVideo]) { 19 | videoSize = track.naturalSize; 20 | } 21 | } 22 | return videoSize; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Category/AppDelegate/AppDelegate+JKRADPage.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate+JKRADPage.h 3 | // ZHYQ 4 | // 5 | // Created by Joker on 15/3/15. 6 | // Copyright © 2015年 Joker. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | //#import "JKRADPage.h" 11 | 12 | /** 13 | 配置广告页 14 | */ 15 | @interface AppDelegate (JKRADPage) 16 | 17 | - (void)jkr_configADPage; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Category/AppDelegate/AppDelegate+JKRADPage.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate+JKRADPage.m 3 | // ZHYQ 4 | // 5 | // Created by Joker on 15/3/15. 6 | // Copyright © 2015年 Joker. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate+JKRADPage.h" 10 | 11 | @implementation AppDelegate (JKRADPage) 12 | 13 | - (void)jkr_configADPage { 14 | // JKRADPage *adView = [[JKRADPage alloc] initWithFrame:self.window.bounds]; 15 | // [adView show]; 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Category/AppDelegate/AppDelegate+JKRConfigNavigation.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate+JKRConfigNavigation.h 3 | // RongCloudDemo 4 | // 5 | // Created by Lucky on 2017/5/4. 6 | // Copyright © 2017年 KaiHei. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate (JKRConfigNavigation) 12 | 13 | - (void)jkr_configNavigation; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Category/AppDelegate/AppDelegate+JKRConfigNavigation.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate+JKRConfigNavigation.m 3 | // RongCloudDemo 4 | // 5 | // Created by Lucky on 2017/5/4. 6 | // Copyright © 2017年 KaiHei. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate+JKRConfigNavigation.h" 10 | #import "UIColor+JKRColor.h" 11 | 12 | @implementation AppDelegate (JKRConfigNavigation) 13 | 14 | - (void)jkr_configNavigation { 15 | // UINavigationBar *navigationBar = [UINavigationBar appearanceWhenContainedInInstancesOfClasses:@[[JKRNavigationController class]]]; 16 | UINavigationBar *navigationBar = [UINavigationBar appearanceWhenContainedInInstancesOfClasses:@[[UINavigationController class]]]; 17 | navigationBar.barTintColor = [UIColor jkr_colorWithHexString:@"000000"]; // 设置顶栏背景色,不会被模糊,最直接有效的设置顶栏背景色方法 18 | navigationBar.tintColor = [UIColor whiteColor]; 19 | 20 | //设置中间title文字的字体和颜色 21 | NSMutableDictionary *titleTextAttributesDictionary = [NSMutableDictionary dictionary]; 22 | titleTextAttributesDictionary[NSForegroundColorAttributeName] = [UIColor whiteColor]; 23 | titleTextAttributesDictionary[NSFontAttributeName] = [UIFont systemFontOfSize:16]; 24 | navigationBar.titleTextAttributes = titleTextAttributesDictionary; 25 | 26 | // 设置左右按钮BarButtonItem文字的字体和颜色 27 | // UIBarButtonItem *barButtonItem = [UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[JKRNavigationController class]]]; 28 | UIBarButtonItem *barButtonItem = [UIBarButtonItem appearance]; 29 | // 默认状态下的字体和颜色 30 | NSMutableDictionary *normalBarButtonItemAttributesDictionary = [NSMutableDictionary dictionary]; 31 | normalBarButtonItemAttributesDictionary[NSForegroundColorAttributeName] = [UIColor whiteColor]; 32 | normalBarButtonItemAttributesDictionary[NSFontAttributeName] = [UIFont systemFontOfSize:16]; 33 | [barButtonItem setTitleTextAttributes:normalBarButtonItemAttributesDictionary forState:UIControlStateNormal]; 34 | // 高亮状态下的字体和颜色 35 | NSMutableDictionary *highLightBarButtomItemAttributesDictionary = [NSMutableDictionary dictionary]; 36 | highLightBarButtomItemAttributesDictionary[NSForegroundColorAttributeName] = [UIColor whiteColor]; 37 | highLightBarButtomItemAttributesDictionary[NSFontAttributeName] = [UIFont systemFontOfSize:16]; 38 | [barButtonItem setTitleTextAttributes:highLightBarButtomItemAttributesDictionary forState:UIControlStateHighlighted]; 39 | // 禁用状态下的字体和颜色 40 | NSMutableDictionary *disableBarButtonItemAttributesDictionary = [NSMutableDictionary dictionary]; 41 | disableBarButtonItemAttributesDictionary[NSForegroundColorAttributeName] = [UIColor lightGrayColor]; 42 | disableBarButtonItemAttributesDictionary[NSFontAttributeName] = [UIFont systemFontOfSize:16]; 43 | [barButtonItem setTitleTextAttributes:disableBarButtonItemAttributesDictionary forState:UIControlStateDisabled]; 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /Category/AppDelegate/AppDelegate+JKRRootViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate+JKRRootViewController.h 3 | // ZHYQ 4 | // 5 | // Created by Joker on 14/3/15. 6 | // Copyright © 2014年 Joker. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | /** 12 | 配置根控制器 13 | */ 14 | @interface AppDelegate (JKRRootViewController) 15 | 16 | - (void)jkr_configRootViewController; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Category/AppDelegate/AppDelegate+JKRRootViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate+JKRRootViewController.m 3 | // ZHYQ 4 | // 5 | // Created by Joker on 14/3/15. 6 | // Copyright © 2014年 Joker. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate+JKRRootViewController.h" 10 | 11 | @implementation AppDelegate (JKRRootViewController) 12 | 13 | - (void)jkr_configRootViewController { 14 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 15 | UITabBarController *rootViewController = [UITabBarController new]; 16 | self.window.rootViewController = rootViewController; 17 | [self.window makeKeyAndVisible]; 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Category/KVO/NSObject+JKR_Observer.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+JKR_Observer.h 3 | // JKRUIViewDemo 4 | // 5 | // Created by Lucky on 16/7/16. 6 | // Copyright © 2016年 Lucky. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | typedef void (^changeBlock)(id newValue); 13 | 14 | @interface NSObject (JKR_Observer) 15 | 16 | /// 给当前对象快速添加一个监听并在block中响应,默认是NSKeyValueObservingOptionNew 17 | - (void)jkr_addObserver:(NSObject *)object forKeyPath:(NSString *)keyPath change:(changeBlock)change; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Category/KVO/NSObject+JKR_Observer.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+JKR_Observer.m 3 | // JKRUIViewDemo 4 | // 5 | // Created by Lucky on 16/7/16. 6 | // Copyright © 2016年 Lucky. All rights reserved. 7 | // 8 | 9 | #import "NSObject+JKR_Observer.h" 10 | 11 | @interface NSObject () 12 | 13 | @property NSMutableDictionary *jkr_observer_blocks; 14 | @property NSMutableArray *jkr_observer_keyPaths; 15 | @property NSObject *jkr_observer_observerdObject; 16 | 17 | @end 18 | 19 | @implementation NSObject (JKR_Observer) 20 | 21 | - (void)jkr_addObserver:(NSObject *)object forKeyPath:(NSString *)keyPath change:(changeBlock)change { 22 | NSLog(@"%@ 添加监听者 %@ 被监听的值:%@", self, object, keyPath); 23 | static dispatch_once_t onceToken; 24 | dispatch_once(&onceToken, ^{ 25 | method_exchangeImplementations(class_getInstanceMethod([object class], NSSelectorFromString(@"dealloc")), class_getInstanceMethod([self class], @selector(jkr_dealloc))); 26 | }); 27 | [self addObserver:object forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:(__bridge void * _Nullable)([NSString stringWithFormat:@"%zd", self.jkr_observer_blocks.count])]; 28 | [self.jkr_observer_blocks setObject:change forKey:[NSString stringWithFormat:@"%zd", self.jkr_observer_blocks.count]]; 29 | 30 | NSMutableArray *keyPaths = [object valueForKey:@"jkr_observer_keyPaths"]; 31 | [keyPaths addObject:keyPath]; 32 | object.jkr_observer_observerdObject = self; 33 | } 34 | 35 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 36 | NSLog(@"监听者:%@ 监听到被监听者 %@ 的值 %@ 改变", self, object, keyPath); 37 | NSString *key = (__bridge NSString *)(context); 38 | NSMutableDictionary *dict = [object valueForKey:@"jkr_observer_blocks"]; 39 | if (!dict) return; 40 | changeBlock block = [dict valueForKey:key]; 41 | if (block) { 42 | id newValue = [change valueForKey:NSKeyValueChangeNewKey]; 43 | block(newValue); 44 | } 45 | } 46 | 47 | - (void)setJkr_observer_blocks:(NSMutableDictionary *)jkr_observer_blocks { 48 | objc_setAssociatedObject(self, "jkr_observer_blocks", jkr_observer_blocks, OBJC_ASSOCIATION_RETAIN); 49 | } 50 | 51 | - (NSMutableDictionary *)jkr_observer_blocks { 52 | NSMutableDictionary *blocks = objc_getAssociatedObject(self, "jkr_observer_blocks"); 53 | if (!blocks) { 54 | blocks = [NSMutableDictionary dictionary]; 55 | objc_setAssociatedObject(self, "jkr_observer_blocks", blocks, OBJC_ASSOCIATION_RETAIN); 56 | } 57 | return blocks; 58 | } 59 | 60 | - (void)setJkr_observer_keyPaths:(NSMutableArray *)jkr_observer_keyPaths { 61 | objc_setAssociatedObject(self, "jkr_observer_keyPaths", jkr_observer_keyPaths, OBJC_ASSOCIATION_RETAIN); 62 | } 63 | 64 | - (NSMutableArray *)jkr_observer_keyPaths { 65 | NSMutableArray *keyPaths = objc_getAssociatedObject(self, "jkr_observer_keyPaths"); 66 | if (!keyPaths) { 67 | keyPaths = [NSMutableArray array]; 68 | objc_setAssociatedObject(self, "jkr_observer_keyPaths", keyPaths, OBJC_ASSOCIATION_RETAIN); 69 | } 70 | return keyPaths; 71 | } 72 | 73 | - (NSObject *)jkr_observer_observerdObject { 74 | return objc_getAssociatedObject(self, "jkr_observer_observerdObject"); 75 | } 76 | 77 | - (void)setJkr_observer_observerdObject:(NSObject *)jkr_observer_observerdObject { 78 | objc_setAssociatedObject(self, "jkr_observer_observerdObject", jkr_observer_observerdObject, OBJC_ASSOCIATION_ASSIGN); 79 | } 80 | 81 | - (void)jkr_dealloc { 82 | NSMutableArray *paths = self.jkr_observer_keyPaths; 83 | if (paths.count) { 84 | [paths enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 85 | NSLog(@"被监听者 %@ 移除监听者 %@ 被移除的监听值 %@", self.jkr_observer_observerdObject, self, obj); 86 | [self.jkr_observer_observerdObject removeObserver:self forKeyPath:paths[idx]]; 87 | }]; 88 | } 89 | NSLog(@"dealloc"); 90 | [self jkr_dealloc]; 91 | } 92 | 93 | @end 94 | -------------------------------------------------------------------------------- /Category/NSDate/NSDate+JKRDate.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+JKRDate.h 3 | // CALayerDemo 4 | // 5 | // Created by Lucky on 2017/6/14. 6 | // Copyright © 2017年 Lucky. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSDate (JKRDate) 12 | 13 | @property (nonatomic, assign, readonly) NSInteger year; ///< 年 14 | @property (nonatomic, assign, readonly) NSInteger month; ///< 月 15 | @property (nonatomic, assign, readonly) NSInteger day; ///< 日 16 | @property (nonatomic, assign, readonly) NSInteger hour; ///< 时 17 | @property (nonatomic, assign, readonly) NSInteger minute; ///< 分 18 | @property (nonatomic, assign, readonly) NSInteger second; ///< 秒 19 | 20 | /// 时间字符串 yyyy-MM-dd HH:mm:ss 21 | - (NSString *)string; 22 | /// 时间字符串 自定义格式 23 | - (NSString *)stringWithFormatString:(NSString *)string; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Category/NSDate/NSDate+JKRDate.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+JKRDate.m 3 | // CALayerDemo 4 | // 5 | // Created by Lucky on 2017/6/14. 6 | // Copyright © 2017年 Lucky. All rights reserved. 7 | // 8 | 9 | #import "NSDate+JKRDate.h" 10 | 11 | @implementation NSDate (JKRDate) 12 | 13 | - (NSInteger)year { 14 | NSCalendar *calendar = [NSCalendar currentCalendar]; 15 | NSUInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; 16 | NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:self]; 17 | return [dateComponent year]; 18 | } 19 | 20 | - (NSInteger)month { 21 | NSCalendar *calendar = [NSCalendar currentCalendar]; 22 | NSUInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; 23 | NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:self]; 24 | return [dateComponent month]; 25 | } 26 | 27 | - (NSInteger)day { 28 | NSCalendar *calendar = [NSCalendar currentCalendar]; 29 | NSUInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; 30 | NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:self]; 31 | return [dateComponent day]; 32 | } 33 | 34 | - (NSInteger)hour { 35 | NSCalendar *calendar = [NSCalendar currentCalendar]; 36 | NSUInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; 37 | NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:self]; 38 | return [dateComponent hour]; 39 | } 40 | 41 | - (NSInteger)minute { 42 | NSCalendar *calendar = [NSCalendar currentCalendar]; 43 | NSUInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; 44 | NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:self]; 45 | return [dateComponent minute]; 46 | } 47 | 48 | - (NSInteger)second { 49 | NSCalendar *calendar = [NSCalendar currentCalendar]; 50 | NSUInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; 51 | NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:self]; 52 | return [dateComponent second]; 53 | } 54 | 55 | - (NSString *)string { 56 | return [self stringWithFormatString:@"yyyy-MM-dd HH:mm:ss"]; 57 | } 58 | 59 | - (NSString *)stringWithFormatString:(NSString *)string { 60 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 61 | [dateFormatter setDateFormat:string]; 62 | return [dateFormatter stringFromDate:self]; 63 | } 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /Category/NSObject/NSObject+JKRTryMethod.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+JKRTryMethod.h 3 | // LuckyRocket 4 | // 5 | // Created by Joker on 2018/11/4. 6 | // Copyright © 2018 Joker. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface NSObject (JKRTryMethod) 14 | 15 | - (void)jkr_tryWithBlock:(nullable void(^)(void))block catchBlock:(nullable void(^)(NSException *exception))catchBlock finallyBlock:(nullable void(^)(void))finallyBlock; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /Category/NSObject/NSObject+JKRTryMethod.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+JKRTryMethod.m 3 | // LuckyRocket 4 | // 5 | // Created by Joker on 2018/11/4. 6 | // Copyright © 2018 Joker. All rights reserved. 7 | // 8 | 9 | #import "NSObject+JKRTryMethod.h" 10 | 11 | @implementation NSObject (JKRTryMethod) 12 | 13 | - (void)jkr_tryWithBlock:(void (^)(void))block catchBlock:(void (^)(NSException * _Nonnull))catchBlock finallyBlock:(void (^)(void))finallyBlock { 14 | @try { 15 | if (block) block(); 16 | } @catch (NSException *exception) { 17 | if (catchBlock) catchBlock(exception); 18 | } @finally { 19 | if (finallyBlock) finallyBlock(); 20 | } 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Category/NSObject/NSObject+JKR_RunTime.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+JKR_RunTime.h 3 | // JKRDemo 4 | // 5 | // Created by Lucky on 16/2/12. 6 | // Copyright © 2016年 Lucky. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSObject (JKR_RunTime) 12 | 13 | /// 返回对象属性列表 14 | - (NSArray *)jkr_ivarList; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Category/NSObject/NSObject+JKR_RunTime.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+JKR_RunTime.m 3 | // JKRDemo 4 | // 5 | // Created by Lucky on 16/2/12. 6 | // Copyright © 2016年 Lucky. All rights reserved. 7 | // 8 | 9 | #import "NSObject+JKR_RunTime.h" 10 | #import 11 | 12 | @implementation NSObject (JKR_RunTime) 13 | 14 | - (NSArray *)jkr_ivarList { 15 | NSMutableArray *result = [NSMutableArray array]; 16 | 17 | unsigned int outCount = 0; 18 | Ivar *ivars = class_copyIvarList([self class], &outCount); 19 | for (unsigned int i = 0; i < outCount; i++) { 20 | Ivar ivar = ivars[i]; 21 | const char *ivarName = ivar_getName(ivar); 22 | const char *ivarEndoer = ivar_getTypeEncoding(ivar); 23 | NSString *name = [NSString stringWithUTF8String:ivarName]; 24 | NSString *type = [NSString stringWithUTF8String:ivarEndoer]; 25 | if ([type hasPrefix:@"@\""]) { 26 | type = [type substringFromIndex:2]; 27 | } 28 | if ([type hasSuffix:@"\""]) { 29 | type = [type substringToIndex:type.length - 1]; 30 | } 31 | //type = [type substringWithRange:NSMakeRange(2, type.length - 3)]; 32 | name = [name substringFromIndex:1]; 33 | NSString *value = [NSString stringWithFormat:@"%@ : %@", name, type]; 34 | [result addObject:value]; 35 | } 36 | free(ivars); 37 | return result; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Category/NSString/NSAttributedString+JKRSize.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSAttributedString+JKRSize.h 3 | // JKRCategoryDemo 4 | // 5 | // Created by Joker on 2017/10/3. 6 | // Copyright © 2018 Joker. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSAttributedString (JKRSize) 12 | 13 | /// 根据宽度返回带格式字符串的高度,只支持同一字体尺寸的字符串 14 | - (CGSize)jkr_sizeWithWidth:(CGFloat)width; 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /Category/NSString/NSAttributedString+JKRSize.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSAttributedString+JKRSize.m 3 | // JKRCategoryDemo 4 | // 5 | // Created by Joker on 2017/10/3. 6 | // Copyright © 2018 Joker. All rights reserved. 7 | // 8 | 9 | #import "NSAttributedString+JKRSize.h" 10 | 11 | @implementation NSAttributedString (JKRSize) 12 | 13 | - (CGSize)jkr_sizeWithWidth:(CGFloat)width { 14 | if (self.string.length == 0) return CGSizeZero; 15 | return [self.string boundingRectWithSize:CGSizeMake(width > 0 ? width : [UIScreen mainScreen].bounds.size.width, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:[self attributesAtIndex:0 effectiveRange:NULL] context:nil].size; 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Category/NSString/NSString+JKRFile.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+JKRFile.h 3 | // Lucky 4 | // 5 | // Created by Lucky on 2014/08/02. 6 | // Copyright © 2014年 Lucky. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (JKRFile) 12 | 13 | /// 获取当前字符串路径下文件夹内文件总大小 14 | - (NSString *)jkr_documentFileSize; 15 | /// 清空当前字符串路径下的文件夹 16 | - (BOOL)jkr_clearDocument; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Category/NSString/NSString+JKRFile.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+JKRFile.m 3 | // Lucky 4 | // 5 | // Created by Lucky on 2014/08/02. 6 | // Copyright © 2018年 Lucky. All rights reserved. 7 | // 8 | 9 | #import "NSString+JKRFile.h" 10 | 11 | @implementation NSString (JKRFile) 12 | 13 | - (NSString *)jkr_documentFileSize { 14 | NSArray *subPathArr = [[NSFileManager defaultManager] subpathsAtPath:self]; 15 | NSString *filePath = nil; 16 | NSInteger totleSize = 0; 17 | for (NSString *subPath in subPathArr) { 18 | filePath =[self stringByAppendingPathComponent:subPath]; 19 | BOOL isDirectory = NO; 20 | BOOL isExist = [[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&isDirectory]; 21 | if (!isExist || isDirectory || [filePath containsString:@".DS"]){ 22 | continue; 23 | } 24 | NSDictionary *dict = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil]; 25 | NSInteger size = [dict[@"NSFileSize"] integerValue]; 26 | totleSize += size; 27 | } 28 | NSString *totleStr = nil; 29 | if (totleSize > 1000 * 1000){ 30 | totleStr = [NSString stringWithFormat:@"%.2fM",totleSize / 1000.00f /1000.00f]; 31 | }else if (totleSize > 1000){ 32 | totleStr = [NSString stringWithFormat:@"%.2fKB",totleSize / 1000.00f ]; 33 | }else{ 34 | totleStr = [NSString stringWithFormat:@"%.2fB",totleSize / 1.00f]; 35 | } 36 | return totleStr; 37 | } 38 | 39 | - (BOOL)jkr_clearDocument { 40 | NSArray *subPathArr = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:self error:nil]; 41 | NSString *filePath = nil; 42 | NSError *error = nil; 43 | for (NSString *subPath in subPathArr) { 44 | filePath = [self stringByAppendingPathComponent:subPath]; 45 | [[NSFileManager defaultManager] removeItemAtPath:filePath error:&error]; 46 | if (error) { 47 | return NO; 48 | } 49 | } 50 | return YES; 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /Category/NSString/NSString+JKRFilter.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+JKRSubNumber.h 3 | // JKRCategoryDemo 4 | // 5 | // Created by Joker on 2016/10/2. 6 | // Copyright © 2018 Joker. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (JKRFilter) 12 | 13 | /// 截取金钱字符串,保留最多4位小数切去末尾0, 1984.110033 => 1984.11 78,688.200 => 78,688.2 14 | - (NSString *)jkr_filter_subNumberStringWithDecimals:(NSInteger)decimals; 15 | /// 过滤字符串中的emoji表情 16 | - (NSString *)jkr_filter_emoji; 17 | 18 | @end 19 | 20 | -------------------------------------------------------------------------------- /Category/NSString/NSString+JKRFilter.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+JKRSubNumber.m 3 | // JKRCategoryDemo 4 | // 5 | // Created by Joker on 2016/10/2. 6 | // Copyright © 2018 Joker. All rights reserved. 7 | // 8 | 9 | #import "NSString+JKRFilter.h" 10 | 11 | @implementation NSString (JKRFilter) 12 | 13 | - (NSString *)jkr_filter_subNumberStringWithDecimals:(NSInteger)decimals { 14 | if (!self || ![self containsString:@"."] || decimals < 0 || decimals > 10) return self; 15 | BOOL hasComma = [self containsString:@","]; 16 | NSString *subCommaString; 17 | if (hasComma) { 18 | hasComma = YES; 19 | subCommaString = [self stringByReplacingOccurrencesOfString:@"," withString:@""]; 20 | } else { 21 | subCommaString = self; 22 | } 23 | NSString *formatString = [NSString stringWithFormat:@"%%.%zdf", decimals]; 24 | NSInteger formatMultiplier = pow(10, decimals); 25 | NSString *subfloatString = [NSString stringWithFormat:formatString, floor((subCommaString.doubleValue) * formatMultiplier) / formatMultiplier]; 26 | NSString *ms = [NSString stringWithString:subfloatString]; 27 | subNumberString(&ms); 28 | if (hasComma) { 29 | if ([ms containsString:@"."]) { 30 | NSRange dRange = [ms rangeOfString:@"."]; 31 | NSString *fString = [ms substringWithRange:NSMakeRange(0, dRange.location)]; 32 | NSString *bString = [ms substringWithRange:NSMakeRange(dRange.location + 1, ms.length - dRange.location - 1)]; 33 | NSString *rString; 34 | NSMutableString *mFString = [NSMutableString stringWithString:fString]; 35 | for (NSInteger i = 0; (i + 1) * 3 + i < mFString.length; i++) { 36 | [mFString insertString:@"," atIndex:mFString.length - ((i + 1) * 3 + i)]; 37 | } 38 | rString = [NSString stringWithFormat:@"%@.%@", mFString, bString]; 39 | return rString; 40 | } else { 41 | NSString *fString = ms; 42 | NSString *rString; 43 | NSMutableString *mFString = [NSMutableString stringWithString:fString]; 44 | for (NSInteger i = 0; (i + 1) * 3 + i < mFString.length; i++) { 45 | [mFString insertString:@"," atIndex:mFString.length - ((i + 1) * 3 + i)]; 46 | } 47 | rString = [NSString stringWithFormat:@"%@", mFString]; 48 | return rString; 49 | } 50 | } 51 | return ms; 52 | } 53 | 54 | static inline void subNumberString(NSString **string) { 55 | NSString *ms = *string; 56 | while ([ms hasSuffix:@"0"] && ms.length > 0) { 57 | ms = [ms substringToIndex:ms.length - 1]; 58 | } 59 | if ([ms hasSuffix:@"."]) { 60 | ms = [ms substringToIndex:ms.length - 1]; 61 | } 62 | *string = ms; 63 | } 64 | 65 | - (NSString *)jkr_filter_emoji { 66 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[^\\u0020-\\u007E\\u00A0-\\u00BE\\u2E80-\\uA4CF\\uF900-\\uFAFF\\uFE30-\\uFE4F\\uFF00-\\uFFEF\\u0080-\\u009F\\u2000-\\u201f\r\n]" options:NSRegularExpressionCaseInsensitive error:nil]; 67 | NSString *modifiedString = [regex stringByReplacingMatchesInString:self options:0 range:NSMakeRange(0, [self length]) withTemplate:@""]; 68 | return modifiedString; 69 | } 70 | 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /Category/NSString/NSString+JKRMD5.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+JKRMD5.h 3 | // JKRBaseProject 4 | // 5 | // Created by Lucky on 2017/6/8. 6 | // Copyright © 2017年 Joker. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (JKRMD5) 12 | 13 | /// md5加密 14 | - (NSString *)jkr_md5String; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Category/NSString/NSString+JKRMD5.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+JKRMD5.m 3 | // JKRBaseProject 4 | // 5 | // Created by Lucky on 2017/6/8. 6 | // Copyright © 2017年 Joker. All rights reserved. 7 | // 8 | 9 | #import "NSString+JKRMD5.h" 10 | #import 11 | 12 | @implementation NSString (JKRMD5) 13 | 14 | - (NSString *)jkr_md5String { 15 | CC_MD5_CTX md5; 16 | CC_MD5_Init (&md5); 17 | CC_MD5_Update (&md5, [self UTF8String], (CC_LONG) [self length]); 18 | 19 | unsigned char digest[CC_MD5_DIGEST_LENGTH]; 20 | CC_MD5_Final (digest, &md5); 21 | NSString *s = [NSString stringWithFormat: @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", 22 | digest[0], digest[1], 23 | digest[2], digest[3], 24 | digest[4], digest[5], 25 | digest[6], digest[7], 26 | digest[8], digest[9], 27 | digest[10], digest[11], 28 | digest[12], digest[13], 29 | digest[14], digest[15]]; 30 | return s; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Category/NSString/NSString+JKRRegular.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+JKRRegular.h 3 | // JKRCategoryDemo 4 | // 5 | // Created by Joker on 2017/10/3. 6 | // Copyright © 2018 Joker. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (JKRRegular) 12 | 13 | /// 判断是否为手机号 14 | - (BOOL)jkr_regular_isPhoneNumber; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Category/NSString/NSString+JKRRegular.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+JKRRegular.m 3 | // JKRCategoryDemo 4 | // 5 | // Created by Joker on 2017/10/3. 6 | // Copyright © 2018 Joker. All rights reserved. 7 | // 8 | 9 | #import "NSString+JKRRegular.h" 10 | 11 | @implementation NSString (JKRRegular) 12 | 13 | - (BOOL)jkr_regular_isPhoneNumber { 14 | if (self.length < 11) return NO; 15 | // NSString *regular = @"^1\\d{10}$"; 非精确,只判断位数 16 | NSString *regular = @"^1(3[0-9]|4[579]|5[0-35-9]|7[0-35-8]|8[0-9])\\d{8}$"; 17 | NSPredicate *regextestMobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regular]; 18 | BOOL isValid = [regextestMobile evaluateWithObject:self]; 19 | return isValid; 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Category/NSString/NSString+JKRSize.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+JKRSize.m 3 | // JKRMVVMDemo 4 | // 5 | // Created by Lucky on 2017/4/27. 6 | // Copyright © 2017年 Lucky. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (JKRSize) 12 | 13 | /// 根据宽度和系统字体尺寸获取字符串的宽度,不传字体默认14号,不传宽度默认屏幕宽度 14 | - (CGSize)jkr_sizeWithWidth:(CGFloat)width fontSize:(CGFloat)fontSize; 15 | 16 | /// 根据宽度和字体获取字符串的宽度 17 | - (CGSize)jkr_sizeWithWidth:(CGFloat)width font:(UIFont *)font; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Category/NSString/NSString+JKRSize.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+JKRSize.m 3 | // JKRMVVMDemo 4 | // 5 | // Created by Lucky on 2017/4/27. 6 | // Copyright © 2017年 Lucky. All rights reserved. 7 | // 8 | 9 | #import "NSString+JKRSize.h" 10 | 11 | @implementation NSString (JKRSize) 12 | 13 | - (CGSize)jkr_sizeWithWidth:(CGFloat)width fontSize:(CGFloat)fontSize { 14 | if (fontSize == 0) fontSize = 14.f; 15 | return [self jkr_sizeWithWidth:width font:[UIFont systemFontOfSize:fontSize]]; 16 | } 17 | 18 | - (CGSize)jkr_sizeWithWidth:(CGFloat)width font:(UIFont *)font { 19 | if (self.length == 0) return CGSizeZero; 20 | return [self boundingRectWithSize:CGSizeMake(width > 0 ? width : [UIScreen mainScreen].bounds.size.width, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font ? font : [UIFont systemFontOfSize:14]} context:nil].size; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Category/NSString/NSString+URLComponents.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+URLComponents.h 3 | // URLDemo 4 | // 5 | // Created by Lucky on 2017/8/24. 6 | // Copyright © 2017年 Lucky. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (URLComponents) 12 | 13 | /// 返回URL格式字符串携带的参数 14 | - (NSDictionary *)jkr_urlStringGetURLComponents; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Category/NSString/NSString+URLComponents.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+URLComponents.m 3 | // URLDemo 4 | // 5 | // Created by Lucky on 2017/8/24. 6 | // Copyright © 2017年 Lucky. All rights reserved. 7 | // 8 | 9 | #import "NSString+URLComponents.h" 10 | 11 | @implementation NSString (URLComponents) 12 | 13 | - (NSDictionary *)jkr_urlStringGetURLComponents { 14 | if (self == nil || self.length == 0) return nil; 15 | NSURLComponents *urlComponents = [NSURLComponents componentsWithString:self]; 16 | NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; 17 | NSArray *queryItems = urlComponents.queryItems; 18 | for (NSURLQueryItem *item in queryItems) { 19 | if (item.name && item.value) { 20 | [dictionary setObject:item.value forKey:item.name]; 21 | } 22 | } 23 | return dictionary; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Category/NSURL/NSURL+JKRFileSize.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSURL+JKRFileSize.h 3 | // Lucky 4 | // 5 | // Created by Lucky on 2016/4/15. 6 | // Copyright © 2016年 Lucky. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSURL (JKRFileSize) 12 | 13 | /// 获取文件大小 14 | - (CGFloat)jkr_fileSize; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Category/NSURL/NSURL+JKRFileSize.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSURL+JKRFileSize.m 3 | // Lucky 4 | // 5 | // Created by Lucky on 2016/4/15. 6 | // Copyright © 2016年 Lucky. All rights reserved. 7 | // 8 | 9 | #import "NSURL+JKRFileSize.h" 10 | 11 | @implementation NSURL (JKRFileSize) 12 | 13 | - (CGFloat)jkr_fileSize { 14 | if (self && self.absoluteString.length > 0) { 15 | NSData *data = [NSData dataWithContentsOfURL:self]; 16 | if (data) { 17 | return [data length] / 1024.00 / 1024.00; 18 | } else { 19 | return 0.f; 20 | } 21 | } else { 22 | return 0.f; 23 | } 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Category/NSURL/NSURL+JKRVideo.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSURL+JKRVideo.h 3 | // BaoJiDianJing 4 | // 5 | // Created by Lucky on 2018/5/17. 6 | // Copyright © 2018年 KaiHei. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSURL (JKRVideo) 12 | 13 | /// 获取视频时长 14 | - (CGFloat)jkr_videoDuration; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Category/NSURL/NSURL+JKRVideo.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSURL+JKRVideo.m 3 | // BaoJiDianJing 4 | // 5 | // Created by Lucky on 2018/5/17. 6 | // Copyright © 2018年 KaiHei. All rights reserved. 7 | // 8 | 9 | #import "NSURL+JKRVideo.h" 10 | #import 11 | 12 | @implementation NSURL (JKRVideo) 13 | 14 | - (CGFloat)jkr_videoDuration { 15 | NSDictionary *opts = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:AVURLAssetPreferPreciseDurationAndTimingKey]; 16 | AVURLAsset *asset = [AVURLAsset URLAssetWithURL:self options:opts]; 17 | CMTime duration = asset.duration; 18 | float durationSeconds = CMTimeGetSeconds(duration); 19 | return durationSeconds; 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Category/PHAsset/PHAsset+JKRMovieURL.h: -------------------------------------------------------------------------------- 1 | // 2 | // PHAsset+JKRMovieURL.h 3 | // BaoJiDianJing 4 | // 5 | // Created by Lucky on 2018/5/14. 6 | // Copyright © 2018年 KaiHei. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PHAsset (JKRMovieURL) 12 | 13 | /// 获取视频URL 14 | - (NSURL *)jkr_movieURL; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Category/PHAsset/PHAsset+JKRMovieURL.m: -------------------------------------------------------------------------------- 1 | // 2 | // PHAsset+JKRMovieURL.m 3 | // BaoJiDianJing 4 | // 5 | // Created by Lucky on 2018/5/14. 6 | // Copyright © 2018年 KaiHei. All rights reserved. 7 | // 8 | 9 | #import "PHAsset+JKRMovieURL.h" 10 | 11 | @implementation PHAsset (JKRMovieURL) 12 | 13 | - (NSURL *)jkr_movieURL { 14 | __block NSURL *url = nil; 15 | 16 | dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); 17 | 18 | if (self.mediaType == PHAssetMediaTypeVideo) { 19 | PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init]; 20 | options.version = PHVideoRequestOptionsVersionOriginal; 21 | options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic; 22 | options.networkAccessAllowed = YES; 23 | 24 | PHImageManager *manager = [PHImageManager defaultManager]; 25 | [manager requestAVAssetForVideo:self options:options resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) { 26 | AVURLAsset *urlAsset = (AVURLAsset *)asset; 27 | url = urlAsset.URL; 28 | 29 | dispatch_semaphore_signal(semaphore); 30 | }]; 31 | } 32 | 33 | dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 34 | 35 | return url; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /Category/UIColor/UIColor+JKRColor.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+JKRColor.h 3 | // JKRColor 4 | // 5 | // Created by Lucky on 2016/8/14. 6 | // Copyright © 2016年 Lucky. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #define JKRColor(r,g,b,a) [UIColor jkr_colorWithRed:r green:g blue:b alpha:a] 12 | #define JKRColorHex(_hex_) [UIColor jkr_colorWithHexString:((__bridge NSString *)CFSTR(#_hex_))] 13 | #define JKRColorTest(x) JKRColor(x,x,x,1) 14 | #define JKRColorGray(x) ({\ 15 | NSInteger __color = (x);\ 16 | JKRColor(__color,__color,__color,1);\ 17 | })\ 18 | 19 | @interface UIColor (JKRColor) 20 | 21 | /// 通过hex返回颜色,支持四种格式:RGB、RGBA、RRGGBB、RRGGBBAA,根据传入自负长度自动判断用那种格式 22 | + (UIColor *)jkr_colorWithHexString:(NSString *)hexString; 23 | /// 通过rgba返回颜色,不需要除255 24 | + (UIColor *)jkr_colorWithRed:(NSUInteger)red green:(NSUInteger)green blue:(NSUInteger)blue alpha:(CGFloat)alpha; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Category/UIColor/UIColor+JKRColor.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+JKRColor.m 3 | // JKRColor 4 | // 5 | // Created by Lucky on 2016/8/14. 6 | // Copyright © 2016年 Lucky. All rights reserved. 7 | // 8 | 9 | #import "UIColor+JKRColor.h" 10 | 11 | @implementation UIColor (JKRColor) 12 | 13 | + (UIColor *)jkr_colorWithHexString:(NSString *)hexString { 14 | CGFloat r, g, b, a; 15 | if (hexStringToRGBA(hexString, &r, &g, &b, &a)) { 16 | return [UIColor colorWithRed:r green:g blue:b alpha:a]; 17 | } 18 | return nil; 19 | } 20 | 21 | + (UIColor *)jkr_colorWithRed:(NSUInteger)red green:(NSUInteger)green blue:(NSUInteger)blue alpha:(CGFloat)alpha{ 22 | return [UIColor colorWithRed:red / 255.f green:green / 255.f blue:blue / 255.f alpha:alpha]; 23 | } 24 | 25 | static inline NSUInteger hexStringToNSUInteger(NSString *str) { 26 | uint32_t result = 0; 27 | sscanf([str UTF8String], "%X", &result); 28 | return result; 29 | } 30 | 31 | static BOOL hexStringToRGBA(NSString *str, CGFloat *r, CGFloat *g, CGFloat *b, CGFloat *a) { 32 | str = [[str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString]; 33 | if ([str hasPrefix:@"#"]) { 34 | str = [str substringFromIndex:1]; 35 | } else if ([str hasPrefix:@"0X"]) { 36 | str = [str substringFromIndex:2]; 37 | } 38 | NSUInteger length = [str length]; 39 | // RGB RGBA RRGGBB RRGGBBAA 40 | if (length != 3 && length != 4 && length != 6 && length != 8) { 41 | return NO; 42 | } 43 | //RGB,RGBA,RRGGBB,RRGGBBAA 44 | if (length < 5) { 45 | *r = hexStringToNSUInteger([str substringWithRange:NSMakeRange(0, 1)]) / 255.f; 46 | *g = hexStringToNSUInteger([str substringWithRange:NSMakeRange(1, 1)]) / 255.f; 47 | *b = hexStringToNSUInteger([str substringWithRange:NSMakeRange(2, 1)]) / 255.f; 48 | if (length == 4) *a = hexStringToNSUInteger([str substringWithRange:NSMakeRange(3, 1)]) / 255.f; 49 | else *a = 1; 50 | } else { 51 | *r = hexStringToNSUInteger([str substringWithRange:NSMakeRange(0, 2)]) / 255.f; 52 | *g = hexStringToNSUInteger([str substringWithRange:NSMakeRange(2, 2)]) / 255.f; 53 | *b = hexStringToNSUInteger([str substringWithRange:NSMakeRange(4, 2)]) / 255.f; 54 | if (length == 8) *a = hexStringToNSUInteger([str substringWithRange:NSMakeRange(6, 2)]) / 255.f; 55 | else *a = 1.f; 56 | } 57 | return YES; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /Category/UIGestureRecognizer/UIGestureRecognizer+JKRTouch.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIGestureRecognizer+JKRTouch.h 3 | // JKRTouchDemo 4 | // 5 | // Created by Joker on 2016/12/31. 6 | // Copyright © 2016年 Lucky. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIGestureRecognizer (JKRTouch) 12 | 13 | /// 设置一个控件的不响应手势事件的区域 14 | @property (nonatomic, assign) BOOL unTouch; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Category/UIGestureRecognizer/UIGestureRecognizer+JKRTouch.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIGestureRecognizer+JKRTouch.m 3 | // JKRTouchDemo 4 | // 5 | // Created by Joker on 2016/12/31. 6 | // Copyright © 2016年 Lucky. All rights reserved. 7 | // 8 | 9 | #import "UIGestureRecognizer+JKRTouch.h" 10 | #import 11 | #import 12 | 13 | @interface UIGestureRecognizer () 14 | 15 | @end 16 | 17 | @implementation UIGestureRecognizer (JKRTouch) 18 | 19 | static const char * JKR_GESTURE_UN_TOUCH_KEY = "JKR_GESTURE_UN_TOUCH_KEY"; 20 | 21 | + (void)load { 22 | method_exchangeImplementations(class_getInstanceMethod([UIGestureRecognizer class], @selector(initWithTarget:action:)), class_getInstanceMethod([UIGestureRecognizer class], @selector(jkr_initWithTarget:action:))); 23 | } 24 | 25 | - (instancetype)jkr_initWithTarget:(id)target action:(SEL)action { 26 | UIGestureRecognizer *gestureRecognizer = [self jkr_initWithTarget:target action:action]; 27 | gestureRecognizer.delegate = self; 28 | return gestureRecognizer; 29 | } 30 | 31 | - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { 32 | return !self.unTouch; 33 | } 34 | 35 | - (BOOL)unTouch { 36 | return objc_getAssociatedObject(self, JKR_GESTURE_UN_TOUCH_KEY) ? [objc_getAssociatedObject(self, JKR_GESTURE_UN_TOUCH_KEY) boolValue] : NO; 37 | } 38 | 39 | - (void)setUnTouch:(BOOL)unTouch { 40 | objc_setAssociatedObject(self, JKR_GESTURE_UN_TOUCH_KEY, [NSNumber numberWithInt:unTouch], OBJC_ASSOCIATION_RETAIN_NONATOMIC); 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /Category/UIImage/UIImage+JKRBlur.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+JKRBlur.h 3 | // BaoJiDianJing 4 | // 5 | // Created by Lucky on 2018/6/5. 6 | // Copyright © 2018年 KaiHei. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIImage (JKRBlur) 12 | 13 | /// 高效果的模糊,低性能或模拟器可能会卡顿 14 | - (UIImage *)jkr_Blur; 15 | /// 地效果不完善的,速度快 16 | - (UIImage *)jkr_BlurWithBlur:(CGFloat)blur; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Category/UIImage/UIImage+JKRBlur.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+JKRBlur.m 3 | // BaoJiDianJing 4 | // 5 | // Created by Lucky on 2018/6/5. 6 | // Copyright © 2018年 KaiHei. All rights reserved. 7 | // 8 | 9 | #import "UIImage+JKRBlur.h" 10 | #import 11 | 12 | @implementation UIImage (JKRBlur) 13 | 14 | - (UIImage *)jkr_Blur { 15 | if (self == nil || [self isKindOfClass:[NSNull class]] || ![self isKindOfClass:[UIImage class]]) { 16 | return nil; 17 | } 18 | // return nil; 19 | if (TARGET_IPHONE_SIMULATOR) { 20 | return [self jkr_BlurWithBlur:1.0]; 21 | } else { 22 | CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"]; 23 | CIImage *ciImage = [[CIImage alloc] initWithImage:self]; 24 | [filter setValue:ciImage forKey:kCIInputImageKey]; 25 | [filter setValue:@(20.0) forKey:kCIInputRadiusKey]; 26 | CIImage *outImage = [filter valueForKey:kCIOutputImageKey]; 27 | CIContext *context = [CIContext contextWithOptions:nil]; 28 | CGImageRef cgImage = [context createCGImage:outImage fromRect:[ciImage extent]]; 29 | UIImage *result = [UIImage imageWithCGImage:cgImage]; 30 | CGImageRelease(cgImage); 31 | return result; 32 | } 33 | } 34 | 35 | - (UIImage *)jkr_BlurWithBlur:(CGFloat)blur { 36 | if (self == nil || [self isKindOfClass:[NSNull class]] || ![self isKindOfClass:[UIImage class]]) { 37 | return nil; 38 | } 39 | 40 | if (blur < 0.f || blur > 1.f) { 41 | blur = 0.5f; 42 | } 43 | int boxSize = (int)(blur * 40); 44 | boxSize = boxSize - (boxSize % 2) + 1; 45 | 46 | CGImageRef img = self.CGImage; 47 | 48 | vImage_Buffer inBuffer, outBuffer; 49 | vImage_Error error; 50 | 51 | void *pixelBuffer; 52 | CGDataProviderRef inProvider = CGImageGetDataProvider(img); 53 | CFDataRef inBitmapData = CGDataProviderCopyData(inProvider); 54 | 55 | inBuffer.width = CGImageGetWidth(img); 56 | inBuffer.height = CGImageGetHeight(img); 57 | inBuffer.rowBytes = CGImageGetBytesPerRow(img); 58 | inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData); 59 | 60 | pixelBuffer = malloc(CGImageGetBytesPerRow(img) * 61 | CGImageGetHeight(img)); 62 | 63 | if(pixelBuffer == NULL) { 64 | NSLog(@"No pixelbuffer"); 65 | return nil; 66 | } 67 | 68 | outBuffer.data = pixelBuffer; 69 | outBuffer.width = CGImageGetWidth(img); 70 | outBuffer.height = CGImageGetHeight(img); 71 | outBuffer.rowBytes = CGImageGetBytesPerRow(img); 72 | 73 | error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend); 74 | 75 | if (error) { 76 | NSLog(@"error from convolution %ld", error); 77 | return nil; 78 | } 79 | 80 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 81 | 82 | CGContextRef ctx = CGBitmapContextCreate( 83 | outBuffer.data, 84 | outBuffer.width, 85 | outBuffer.height, 86 | 8, 87 | outBuffer.rowBytes, 88 | colorSpace, 89 | kCGImageAlphaNoneSkipLast); 90 | CGImageRef imageRef = CGBitmapContextCreateImage (ctx); 91 | UIImage *returnImage = [UIImage imageWithCGImage:imageRef]; 92 | 93 | CGContextRelease(ctx); 94 | CGColorSpaceRelease(colorSpace); 95 | 96 | free(pixelBuffer); 97 | CFRelease(inBitmapData); 98 | 99 | CGColorSpaceRelease(colorSpace); 100 | CGImageRelease(imageRef); 101 | 102 | return returnImage; 103 | } 104 | 105 | @end 106 | -------------------------------------------------------------------------------- /Category/UIImage/UIImage+JKRImage.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+JKRImage.h 3 | // UINavDemo 4 | // 5 | // Created by Lucky on 2015/8/17. 6 | // Copyright © 2015年 Lucky. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIImage (JKRImage) 12 | 13 | /// 根据颜色获取1x1尺寸的图片 14 | /// @param color 图片颜色 15 | /// @return 图片 16 | + (UIImage *)jkr_imageWithColor:(UIColor *)color; 17 | 18 | /// 根据颜色获取图片 19 | /// @param color 图片颜色 20 | /// @param size 图片尺寸 21 | /// @return 图片 22 | + (UIImage *)jkr_imageWithColor:(UIColor *)color size:(CGSize)size; 23 | 24 | /// 画一条水平虚线 25 | /// @param totalLength 虚线总长度 26 | /// @param height 虚线高度 27 | /// @param perLength 虚心每一段实现的宽度 28 | /// @param intervalLength 虚线每一段空白间距 29 | /// @param lineColor 虚线的颜色 30 | /// @return 返回一张符合规定的虚线图片 31 | + (UIImage *)jkr_imaginaryLineWithTotalLength:(CGFloat)totalLength height:(CGFloat)height perLength:(CGFloat)perLength intervalLength:(CGFloat)intervalLength lineColor:(UIColor *)lineColor; 32 | 33 | /// 裁剪圆形图片加边框 34 | /// @param borderWidth borderWidth 边框宽度 35 | /// @param borderColor borderColor 边框颜色 36 | /// @return 裁剪后图片 37 | - (UIImage *)jkr_clipCircleImageWithBorder:(CGFloat)borderWidth withColor:(UIColor *)borderColor; 38 | 39 | /// 压缩图片到指定宽度,通过重新绘制 40 | /// @param width 新图片宽度尺寸 41 | /// @return 绘制后图片 42 | - (UIImage *)jkr_drawWithWidth:(CGFloat)width; 43 | 44 | /// 压缩图片 45 | /// 46 | /// 压缩单位byte,如果是byte需要乘以1024,如60K,如需要传 60 * 1024 47 | /// 48 | /// @param length 文件大小 单位byte 49 | /// @return 压缩后的文件 50 | - (NSData *)jkr_compressWithLength:(NSInteger)length; 51 | 52 | /// 通过修改r.g.b像素点来处理图片 53 | /// 54 | /// [_albumImage jkr_fliterImageWithFliterBlock:^(int *red, int *green, int *blue) { 55 | /// 56 | /// int gray = (*red + *green + *blue) / 3; 57 | /// 58 | /// *red = gray; 59 | /// 60 | /// *green = gray; 61 | /// 62 | /// *blue = gray; 63 | /// 64 | /// } success:^(UIImage *image) { 65 | /// 66 | /// [_pngImageV setImage:image]; 67 | /// 68 | /// }]; 69 | /// 70 | /// @param Fliterblock 具体像素点编辑 71 | /// @param success 返回编辑后的图片 72 | - (void)jkr_fliterImageWithFliterBlock:(void(^)(int *red, int *green, int *blue))Fliterblock success:(void(^)(UIImage *image))success; 73 | 74 | /// 处理相册图片方向不对的问题 75 | /// @return 方向正确的图片 76 | - (UIImage *)jkr_fixOrientation; 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /Category/UIImage/UIImage+JKRImage.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+JKRImage.m 3 | // UINavDemo 4 | // 5 | // Created by Lucky on 2015/8/17. 6 | // Copyright © 2015年 Lucky. All rights reserved. 7 | // 8 | 9 | #import "UIImage+JKRImage.h" 10 | #import 11 | 12 | @implementation UIImage (JKRImage) 13 | 14 | #pragma mark - 根据颜色获取一张图片 15 | + (UIImage *)jkr_imageWithColor:(UIColor *)color { 16 | return [self jkr_imageWithColor:color size:CGSizeMake(1, 1)]; 17 | } 18 | 19 | #pragma mark - 根据颜色和尺寸获取一张图片 20 | + (UIImage *)jkr_imageWithColor:(UIColor *)color size:(CGSize)size { 21 | if (!color || size.width <= 0 || size.height <= 0) return nil; 22 | CGRect rect = CGRectMake(0.f, 0.f, size.width, size.height); 23 | UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0); 24 | CGContextRef context = UIGraphicsGetCurrentContext(); 25 | CGContextSetFillColorWithColor(context, color.CGColor); 26 | CGContextFillRect(context, rect); 27 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 28 | UIGraphicsEndImageContext(); 29 | return image; 30 | } 31 | 32 | #pragma mark - 画一条水平虚线 33 | + (UIImage *)jkr_imaginaryLineWithTotalLength:(CGFloat)totalLength height:(CGFloat)height perLength:(CGFloat)perLength intervalLength:(CGFloat)intervalLength lineColor:(UIColor *)lineColor { 34 | CGSize size = CGSizeMake(totalLength, height); 35 | UIGraphicsBeginImageContextWithOptions(size, NO, 0); 36 | CGContextRef context = UIGraphicsGetCurrentContext(); 37 | if (!context) return nil; 38 | [lineColor setFill]; 39 | CGContextSetLineWidth(context, height); 40 | for (int i = 0; i < totalLength; i+= (intervalLength + intervalLength)) { 41 | CGContextMoveToPoint(context, i * (perLength + intervalLength), 0.5); 42 | CGContextAddLineToPoint(context, i * (perLength + intervalLength) + perLength, 0.5); 43 | } 44 | CGContextStrokePath(context); 45 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 46 | UIGraphicsEndImageContext(); 47 | return image; 48 | } 49 | 50 | #pragma mark - 图片截圆加边框 51 | - (UIImage *)jkr_clipCircleImageWithBorder:(CGFloat)borderWidth withColor:(UIColor *)borderColor { 52 | CGFloat dia; 53 | if (self.size.width >= self.size.height) { 54 | dia = self.size.height; 55 | } else { 56 | dia = self.size.width; 57 | } 58 | CGRect mframe = CGRectMake(0, 0, dia + borderWidth * 2, dia + borderWidth * 2); 59 | UIGraphicsBeginImageContextWithOptions(mframe.size, NO, 0.0f); 60 | UIBezierPath *pathCir = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, mframe.size.width, mframe.size.height)]; 61 | CGContextRef ctr = UIGraphicsGetCurrentContext(); 62 | [borderColor setFill]; 63 | CGContextAddPath(ctr, pathCir.CGPath); 64 | CGContextFillPath(ctr); 65 | UIBezierPath *pathClip = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(borderWidth, borderWidth, dia, dia)]; 66 | [pathClip addClip]; 67 | [self drawAtPoint:CGPointMake(borderWidth, borderWidth)]; 68 | UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 69 | UIGraphicsEndImageContext(); 70 | return newImage; 71 | } 72 | 73 | #pragma mark - 图片根据宽度重绘 74 | - (UIImage *)jkr_drawWithWidth:(CGFloat)width { 75 | if (width <= 0 || [self isKindOfClass:[NSNull class]] || self == nil) return nil; 76 | CGSize newSize = CGSizeMake(width, width * (self.size.height / self.size.width)); 77 | UIGraphicsBeginImageContext(newSize); 78 | [self drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)]; 79 | UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 80 | UIGraphicsEndImageContext(); 81 | return newImage; 82 | } 83 | 84 | 85 | - (NSData *)jkr_compressWithLength:(NSInteger)length { 86 | UIImage *image = [self copy]; 87 | CGFloat compression = 1; 88 | NSData *imageData = UIImageJPEGRepresentation(image, compression); 89 | NSUInteger fImageBytes = length; 90 | if (imageData.length <= fImageBytes) return imageData; 91 | CGFloat max = 1; 92 | CGFloat min = 0; 93 | compression = pow(2, -6); 94 | imageData = UIImageJPEGRepresentation(image, compression); 95 | if (imageData.length < fImageBytes) { 96 | for (int i = 0; i < 6; ++i) { 97 | compression = (max + min) / 2; 98 | imageData = UIImageJPEGRepresentation(image, compression); 99 | if (imageData.length < fImageBytes * 0.9) { 100 | min = compression; 101 | } else if (imageData.length > fImageBytes) { 102 | max = compression; 103 | } else { 104 | break; 105 | } 106 | } 107 | return imageData; 108 | } 109 | UIImage *resultImage = [UIImage imageWithData:imageData]; 110 | while (imageData.length > fImageBytes) { 111 | @autoreleasepool { 112 | CGFloat ratio = (CGFloat)fImageBytes / imageData.length; 113 | CGSize size = CGSizeMake((NSUInteger)(resultImage.size.width * sqrtf(ratio)), (NSUInteger)(resultImage.size.height * sqrtf(ratio))); 114 | resultImage = [self thumbnailForData:imageData maxPixelSize:MAX(size.width, size.height)]; 115 | imageData = UIImageJPEGRepresentation(resultImage, compression); 116 | } 117 | } 118 | return imageData; 119 | } 120 | 121 | - (UIImage *)thumbnailForData:(NSData *)data maxPixelSize:(NSUInteger)size { 122 | CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data); 123 | CGImageSourceRef source = CGImageSourceCreateWithDataProvider(provider, NULL); 124 | CGImageRef imageRef = CGImageSourceCreateThumbnailAtIndex(source, 0, (__bridge CFDictionaryRef) @{(NSString *)kCGImageSourceCreateThumbnailFromImageAlways : @YES, (NSString *)kCGImageSourceThumbnailMaxPixelSize : @(size), (NSString *)kCGImageSourceCreateThumbnailWithTransform : @YES,}); 125 | CFRelease(source); 126 | CFRelease(provider); 127 | if (!imageRef) return nil; 128 | UIImage *toReturn = [UIImage imageWithCGImage:imageRef]; 129 | CFRelease(imageRef); 130 | return toReturn; 131 | } 132 | 133 | #pragma mark - 图片编辑 134 | - (void)jkr_fliterImageWithFliterBlock:(void (^)(int *, int *, int *))Fliterblock success:(void (^)(UIImage *))success{ 135 | if ([self isKindOfClass:[NSNull class]] || self == nil) return; 136 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ 137 | CGImageRef imageRef = self.CGImage; 138 | // 图片宽度 139 | size_t width = CGImageGetWidth(imageRef); 140 | // 图片高度 141 | size_t height = CGImageGetHeight(imageRef); 142 | // 每个颜色值存储的字节数 143 | size_t bits = CGImageGetBitsPerComponent(imageRef); 144 | // 每行的字节数 145 | size_t bitsPerRow = CGImageGetBytesPerRow(imageRef); 146 | // 透明度 147 | int alphaInfo = CGImageGetAlphaInfo(imageRef); 148 | // colorSpace RGBA AGBR RGB: 颜色空间 149 | CGColorSpaceRef colorSpace = CGImageGetColorSpace(imageRef); 150 | // bitmap data provider:bitmap数据提供器 151 | CGDataProviderRef providerRef = CGImageGetDataProvider(imageRef); 152 | // bitmap data:bitmap数据 153 | CFDataRef dataRef = CGDataProviderCopyData(providerRef); 154 | // bitmap数据长度 155 | int length = (int)CFDataGetLength(dataRef); 156 | // 颜色通道字符格式数组 157 | Byte *pixelBuf = (UInt8 *)CFDataGetMutableBytePtr((CFMutableDataRef)dataRef); 158 | // 遍历颜色通道数据,4个一组,RGBA 159 | for (int i = 0; i < length; i+=4) { // i+=4因为4个一组:RGBA 160 | // 原始R序列号 161 | int offsetR = i; 162 | // 原始G序列号 163 | int offsetG = i + 1; 164 | // 原始B序列号 165 | int offsetB = i + 2; 166 | // 原始A序列号 167 | int offsetA = i + 3; 168 | // 原始R值 169 | int red = pixelBuf[offsetR]; 170 | // 原始G值 171 | int green = pixelBuf[offsetG]; 172 | // 原始B值 173 | int blue = pixelBuf[offsetB]; 174 | // 原始A值 175 | int alpha = pixelBuf[offsetA]; 176 | // 修改原始像素RGB数据 177 | Fliterblock(&red, &green, &blue); 178 | // 用修改的RGB数据替换原数据 179 | pixelBuf[offsetR] = red; 180 | pixelBuf[offsetG] = green; 181 | pixelBuf[offsetB] = blue; 182 | pixelBuf[offsetA] = alpha; 183 | } 184 | // bitmap生成上下文 185 | CGContextRef contextRef = CGBitmapContextCreate(pixelBuf, width, height, bits, bitsPerRow, colorSpace, alphaInfo); 186 | // 通过上下文生成图片 187 | CGImageRef backImageRef = CGBitmapContextCreateImage(contextRef); 188 | UIImage *backImage = [UIImage imageWithCGImage:backImageRef scale:[UIScreen mainScreen].scale orientation:self.imageOrientation]; 189 | // 内存释放 190 | CFRelease(dataRef); 191 | CFRelease(contextRef); 192 | CFRelease(backImageRef); 193 | dispatch_async(dispatch_get_main_queue(), ^{ 194 | success(backImage); 195 | }); 196 | }); 197 | } 198 | 199 | #pragma mark - 图片方向矫正 200 | - (UIImage *)jkr_fixOrientation { 201 | // No-op if the orientation is already correct 202 | if (self.imageOrientation == UIImageOrientationUp) return self; 203 | 204 | // We need to calculate the proper transformation to make the image upright. 205 | // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored. 206 | CGAffineTransform transform = CGAffineTransformIdentity; 207 | 208 | switch (self.imageOrientation) { 209 | case UIImageOrientationDown: 210 | case UIImageOrientationDownMirrored: 211 | transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height); 212 | transform = CGAffineTransformRotate(transform, M_PI); 213 | break; 214 | 215 | case UIImageOrientationLeft: 216 | case UIImageOrientationLeftMirrored: 217 | transform = CGAffineTransformTranslate(transform, self.size.width, 0); 218 | transform = CGAffineTransformRotate(transform, M_PI_2); 219 | break; 220 | 221 | case UIImageOrientationRight: 222 | case UIImageOrientationRightMirrored: 223 | transform = CGAffineTransformTranslate(transform, 0, self.size.height); 224 | transform = CGAffineTransformRotate(transform, -M_PI_2); 225 | break; 226 | default: 227 | break; 228 | } 229 | 230 | switch (self.imageOrientation) { 231 | case UIImageOrientationUpMirrored: 232 | case UIImageOrientationDownMirrored: 233 | transform = CGAffineTransformTranslate(transform, self.size.width, 0); 234 | transform = CGAffineTransformScale(transform, -1, 1); 235 | break; 236 | 237 | case UIImageOrientationLeftMirrored: 238 | case UIImageOrientationRightMirrored: 239 | transform = CGAffineTransformTranslate(transform, self.size.height, 0); 240 | transform = CGAffineTransformScale(transform, -1, 1); 241 | break; 242 | default: 243 | break; 244 | } 245 | 246 | // Now we draw the underlying CGImage into a new context, applying the transform 247 | // calculated above. 248 | CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height, 249 | CGImageGetBitsPerComponent(self.CGImage), 0, 250 | CGImageGetColorSpace(self.CGImage), 251 | CGImageGetBitmapInfo(self.CGImage)); 252 | CGContextConcatCTM(ctx, transform); 253 | switch (self.imageOrientation) { 254 | case UIImageOrientationLeft: 255 | case UIImageOrientationLeftMirrored: 256 | case UIImageOrientationRight: 257 | case UIImageOrientationRightMirrored: 258 | // Grr... 259 | CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage); 260 | break; 261 | 262 | default: 263 | CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage); 264 | break; 265 | } 266 | 267 | CGImageRef cgimg = CGBitmapContextCreateImage(ctx); 268 | UIImage *img = [UIImage imageWithCGImage:cgimg]; 269 | CGContextRelease(ctx); 270 | CGImageRelease(cgimg); 271 | return img; 272 | } 273 | 274 | @end 275 | -------------------------------------------------------------------------------- /Category/UIImage/UIImage+JKRRender.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+JKRRender.h 3 | // JKRImageDemo 4 | // 5 | // Created by Lucky on 14-3-4. 6 | // Copyright (c) 2014年 Lucky. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIImage (JKRRender) 12 | 13 | /// 不拉伸的图片 14 | + (instancetype)jkr_originalImageNamed:(NSString *)name; 15 | /// 中心拉伸的图片 16 | + (instancetype)jkr_stretchableImageNamed:(NSString *)name; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Category/UIImage/UIImage+JKRRender.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+JKRRender.h 3 | // JKRImageDemo 4 | // 5 | // Created by Lucky on 14-3-4. 6 | // Copyright (c) 2014年 Lucky. All rights reserved. 7 | // 8 | 9 | #import "UIImage+JKRRender.h" 10 | 11 | @implementation UIImage (JKRRender) 12 | 13 | + (instancetype)jkr_originalImageNamed:(NSString *)name { 14 | UIImage *image = [UIImage imageNamed:name]; 15 | return [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; 16 | } 17 | 18 | + (instancetype)jkr_stretchableImageNamed:(NSString *)name { 19 | UIImage *image = [UIImage imageNamed:name]; 20 | return [image stretchableImageWithLeftCapWidth:image.size.width * 0.5f topCapHeight:image.size.height * 0.5f]; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Category/UIImage/UIImage+JKR_MessageImage.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+JKR_MessageImage.h 3 | // MessageImageDemo 4 | // 5 | // Created by tronsis_ios on 16/10/12. 6 | // Copyright © 2016年 tronsis_ios. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIImage (JKR_MessageImage) 12 | 13 | @property (nonatomic) BOOL jkr_isDecoded; 14 | 15 | /** 16 | Message tip icon 17 | 18 | @param count message count 19 | @param imageSize imageSize 20 | @param tipRadius tipRadius 21 | @param tipTop topMargin 22 | @param tipRight rightMargin 23 | @param fontSize tipTextFontSize 24 | @param textColor tipTextColor 25 | @param tipColor tipBackgroundColor 26 | 27 | @return New image with tip count in the top-right corner 28 | */ 29 | - (instancetype)jkr_messageImageWithCount:(NSInteger)count imageSize:(CGSize)imageSize tipRadius:(CGFloat)tipRadius tipTop:(CGFloat)tipTop tipRight:(CGFloat)tipRight fontSize:(CGFloat)fontSize textColor:(UIColor *)textColor tipColor:(UIColor *)tipColor; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /Category/UIImage/UIImage+JKR_MessageImage.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+JKR_MessageImage.m 3 | // MessageImageDemo 4 | // 5 | // Created by tronsis_ios on 16/10/12. 6 | // Copyright © 2016年 tronsis_ios. All rights reserved. 7 | // 8 | 9 | #import "UIImage+JKR_MessageImage.h" 10 | #import 11 | 12 | @implementation UIImage (JKR_MessageImage) 13 | 14 | - (BOOL)jkr_isDecoded { 15 | if (self.images.count > 1) return YES; 16 | NSNumber *num = objc_getAssociatedObject(self, @selector(jkr_isDecoded)); 17 | return [num boolValue]; 18 | } 19 | 20 | - (void)setJkr_isDecoded:(BOOL)jkr_isDecoded { 21 | objc_setAssociatedObject(self, @selector(jkr_isDecoded), @(jkr_isDecoded), OBJC_ASSOCIATION_RETAIN_NONATOMIC); 22 | } 23 | 24 | - (instancetype)jkr_imageByDecoded { 25 | if (self.jkr_isDecoded) return self; 26 | CGImageRef imageRef = self.CGImage; 27 | if (!imageRef) return self; 28 | CGImageRef newImageRef = jkr_CGImageCreateDecodedCopy(imageRef, YES); 29 | if (!newImageRef) return self; 30 | UIImage *newImage = [[self.class alloc] initWithCGImage:newImageRef scale:self.scale orientation:self.imageOrientation]; 31 | CGImageRelease(newImageRef); 32 | if (!newImage) newImage = self; 33 | newImage.jkr_isDecoded = YES; 34 | return newImage; 35 | } 36 | 37 | CGColorSpaceRef jkr_CGColorSpaceGetDeviceRGB() { 38 | static CGColorSpaceRef space; 39 | static dispatch_once_t onceToken; 40 | dispatch_once(&onceToken, ^{ 41 | space = CGColorSpaceCreateDeviceRGB(); 42 | }); 43 | return space; 44 | } 45 | 46 | CGImageRef jkr_CGImageCreateDecodedCopy(CGImageRef imageRef, BOOL decodeForDisplay) { 47 | if (!imageRef) return NULL; 48 | size_t width = CGImageGetWidth(imageRef); 49 | size_t height = CGImageGetHeight(imageRef); 50 | if (width == 0 || height == 0) return NULL; 51 | if (decodeForDisplay) { 52 | CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef) & kCGBitmapAlphaInfoMask; 53 | BOOL hasAlpha = NO; 54 | if (alphaInfo == kCGImageAlphaPremultipliedFirst || alphaInfo == kCGImageAlphaPremultipliedLast || alphaInfo == kCGImageAlphaFirst || alphaInfo == kCGImageAlphaLast) hasAlpha = YES; 55 | CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Host; 56 | bitmapInfo |= hasAlpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst; 57 | CGContextRef context = CGBitmapContextCreate(NULL, width, height, 8, 0, jkr_CGColorSpaceGetDeviceRGB(), bitmapInfo); 58 | if (!context) return NULL; 59 | CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); 60 | CGImageRef newImage = CGBitmapContextCreateImage(context); 61 | CFRelease(context); 62 | return newImage; 63 | } else { 64 | CGColorSpaceRef space = CGImageGetColorSpace(imageRef); 65 | size_t bitsPerComponent = CGImageGetBitsPerComponent(imageRef); 66 | size_t bitsPerPixel = CGImageGetBitsPerPixel(imageRef); 67 | size_t bytesPerRow = CGImageGetBytesPerRow(imageRef); 68 | CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); 69 | if (bytesPerRow == 0 || width == 0 || height == 0) return NULL; 70 | CGDataProviderRef dataProvider = CGImageGetDataProvider(imageRef); 71 | if (!dataProvider) return NULL; 72 | CFDataRef data = CGDataProviderCopyData(dataProvider); // decode 73 | if (!data) return NULL; 74 | CGDataProviderRef newProvider = CGDataProviderCreateWithCFData(data); 75 | CFRelease(data); 76 | if (!newProvider) return NULL; 77 | CGImageRef newImage = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, space, bitmapInfo, newProvider, NULL, false, kCGRenderingIntentDefault); 78 | CFRelease(newProvider); 79 | return newImage; 80 | } 81 | } 82 | 83 | - (instancetype)jkr_messageImageWithCount:(NSInteger)count imageSize:(CGSize)imageSize tipRadius:(CGFloat)tipRadius tipTop:(CGFloat)tipTop tipRight:(CGFloat)tipRight fontSize:(CGFloat)fontSize textColor:(UIColor *)textColor tipColor:(UIColor *)tipColor{ 84 | UIImage *image = nil; 85 | size_t width = 0; 86 | if (count == 0) width = imageSize.width; 87 | else if (count < 10) width = imageSize.width + tipRight; 88 | else if (count < 100) width = imageSize.width + (8 * fontSize) / 13 + tipRight; 89 | else width = imageSize.width + (8 * fontSize) / 13 * 2 + tipRight; 90 | if (width < imageSize.width) width = imageSize.width; 91 | size_t height = imageSize.height + (count == 0 ? 0 : (tipTop > 0 ? tipTop : 0)); 92 | 93 | UIGraphicsBeginImageContextWithOptions(CGSizeMake(width, height), NO, 0); 94 | CGContextRef context = UIGraphicsGetCurrentContext(); 95 | if (!context) return nil; 96 | size_t circleCenterY = tipTop > 0 ? tipRadius : -tipTop + tipRadius; 97 | [self drawInRect:CGRectMake(0, count == 0 ? 0 : (tipTop > 0 ? tipTop : 0), imageSize.width, imageSize.height)]; 98 | if (count != 0) { 99 | size_t endX = 0; 100 | UIBezierPath *circle = [UIBezierPath bezierPath]; 101 | [circle addArcWithCenter:CGPointMake(imageSize.width + (tipRight - tipRadius), circleCenterY) radius:tipRadius startAngle:M_PI_2 endAngle:M_PI_2 * 3 clockwise:YES]; 102 | if (count >= 100) { 103 | endX = imageSize.width + (8 * fontSize) / 13 * 2 + tipRight - tipRadius; 104 | [circle addLineToPoint:CGPointMake(endX, circleCenterY - tipRadius)]; 105 | } else if (count >= 10) { 106 | endX = imageSize.width + (8 * fontSize) / 13 + tipRight - tipRadius; 107 | [circle addLineToPoint:CGPointMake(endX, circleCenterY - tipRadius)]; 108 | } else if (count > 0) { 109 | endX = imageSize.width + tipRight - tipRadius; 110 | } 111 | [circle addArcWithCenter:CGPointMake(endX, circleCenterY) radius:tipRadius startAngle:M_PI_2 * 3 endAngle:M_PI_2 clockwise:YES]; 112 | [tipColor ? tipColor : [UIColor redColor] setFill]; 113 | CGContextAddPath(context, circle.CGPath); 114 | CGContextFillPath(context); 115 | NSDictionary *dict = @{NSFontAttributeName : [UIFont systemFontOfSize:fontSize], NSForegroundColorAttributeName : textColor ? textColor : [UIColor whiteColor]}; 116 | NSString *countStr = nil; 117 | if (count < 100) countStr = [NSString stringWithFormat:@"%zd", count]; 118 | else countStr = @"99+"; 119 | size_t textY = 0; 120 | if (tipTop >= 0) textY = tipRadius - (fontSize) * 0.6; 121 | else textY = -tipTop + tipRadius - (fontSize) * 0.6; 122 | [countStr drawAtPoint:CGPointMake(imageSize.width + tipRight - tipRadius - ((8 * fontSize) / 13) * 0.5, textY) withAttributes:dict]; 123 | } 124 | image = UIGraphicsGetImageFromCurrentImageContext(); 125 | UIGraphicsEndImageContext(); 126 | image = [image jkr_imageByDecoded]; 127 | image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; 128 | return image; 129 | } 130 | 131 | 132 | @end 133 | -------------------------------------------------------------------------------- /Category/UIImage/UIImageView+JKRImagesAnimation.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImageView+JKRImagesAnimation.h 3 | // JKRCategoryDemo 4 | // 5 | // Created by Joker on 2018/10/24. 6 | // Copyright © 2018年 Joker. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIImageView (JKRImagesAnimation) 12 | 13 | - (void)jkr_startAnimationWithDuration:(NSTimeInterval)duration images:(NSArray *_Nonnull)images completion:(void (^ __nullable)(BOOL finished))completion; 14 | - (void)jkr_startRepeatAnimationWithDuration:(NSTimeInterval)duration images:(NSArray *_Nonnull)images; 15 | - (void)jkr_finishAnimation; 16 | - (BOOL)jkr_isPlayingAnimation; 17 | 18 | @end 19 | 20 | -------------------------------------------------------------------------------- /Category/UIImage/UIImageView+JKRImagesAnimation.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImageView+JKRImagesAnimation.m 3 | // JKRCategoryDemo 4 | // 5 | // Created by Joker on 2018/10/24. 6 | // Copyright © 2018年 Joker. All rights reserved. 7 | // 8 | 9 | #import "UIImageView+JKRImagesAnimation.h" 10 | #import 11 | 12 | @interface UIImageView () 13 | 14 | @property (nonatomic, strong) UIImage *preImage; 15 | @property (nonatomic, strong) dispatch_source_t timer; 16 | 17 | @end 18 | 19 | @implementation UIImageView (JKRImagesAnimation) 20 | 21 | - (void)jkr_startAnimationWithDuration:(NSTimeInterval)duration images:(NSArray *)images completion:(void (^)(BOOL))completion { 22 | if (!images || images.count < 2) return; 23 | [self jkr_finishAnimation]; 24 | CGFloat idx = duration / images.count; 25 | __block int i = 0; 26 | __weak typeof(self) weakSelf = self; 27 | self.preImage = self.image; 28 | self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue()); 29 | dispatch_source_set_timer(self.timer, DISPATCH_TIME_NOW, idx * NSEC_PER_SEC, 0 * NSEC_PER_SEC); 30 | dispatch_source_set_event_handler(self.timer, ^{ 31 | if (i >= images.count) { 32 | dispatch_source_cancel(weakSelf.timer); 33 | weakSelf.timer = nil; 34 | weakSelf.image = weakSelf.preImage; 35 | completion(YES); 36 | } else { 37 | weakSelf.image = images[i++]; 38 | } 39 | }); 40 | dispatch_resume(self.timer); 41 | } 42 | 43 | - (void)jkr_startRepeatAnimationWithDuration:(NSTimeInterval)duration images:(NSArray *)images { 44 | if (!images || images.count < 2) return; 45 | [self jkr_finishAnimation]; 46 | CGFloat idx = duration / images.count; 47 | __block int i = 0; 48 | __weak typeof(self) weakSelf = self; 49 | self.preImage = self.image; 50 | self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue()); 51 | dispatch_source_set_timer(self.timer, DISPATCH_TIME_NOW, idx * NSEC_PER_SEC, 0 * NSEC_PER_SEC); 52 | dispatch_source_set_event_handler(self.timer, ^{ 53 | if (i >= images.count) { 54 | i = 0; 55 | weakSelf.image = images[i++]; 56 | } else { 57 | weakSelf.image = images[i++]; 58 | } 59 | }); 60 | dispatch_resume(self.timer); 61 | } 62 | 63 | - (void)jkr_finishAnimation { 64 | if (!self.timer) return; 65 | dispatch_source_cancel(self.timer); 66 | self.timer = nil; 67 | self.image = self.preImage; 68 | } 69 | 70 | - (BOOL)jkr_isPlayingAnimation { 71 | return self.timer; 72 | } 73 | 74 | - (void)setPreImage:(UIImage *)preImage { 75 | objc_setAssociatedObject(self, @selector(preImage), preImage, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 76 | } 77 | 78 | - (UIImage *)preImage { 79 | return objc_getAssociatedObject(self, @selector(preImage)); 80 | } 81 | 82 | - (void)setTimer:(dispatch_source_t)timer { 83 | objc_setAssociatedObject(self, @selector(timer), timer, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 84 | } 85 | 86 | - (dispatch_source_t)timer { 87 | return objc_getAssociatedObject(self, @selector(timer)); 88 | } 89 | 90 | - (void)dealloc { 91 | [self jkr_finishAnimation]; 92 | } 93 | 94 | @end 95 | -------------------------------------------------------------------------------- /Category/UINavigationBar/UINavigationBar+JKRBottomLine.h: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationBar+JKRBottomLine.h 3 | // BaoJiDianJing 4 | // 5 | // Created by Lucky on 2018/5/24. 6 | // Copyright © 2018年 KaiHei. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UINavigationBar (JKRBottomLine) 12 | 13 | /// 隐藏导航条底部黑线 14 | - (void)jkr_hideBottomLine; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Category/UINavigationBar/UINavigationBar+JKRBottomLine.m: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationBar+JKRBottomLine.m 3 | // BaoJiDianJing 4 | // 5 | // Created by Lucky on 2018/5/24. 6 | // Copyright © 2018年 KaiHei. All rights reserved. 7 | // 8 | 9 | #import "UINavigationBar+JKRBottomLine.h" 10 | 11 | @implementation UINavigationBar (JKRBottomLine) 12 | 13 | - (void)jkr_hideBottomLine { 14 | UIView *line; 15 | for (UIView *subView in self.subviews) { 16 | UIView *result = [self jkr_findline:subView]; 17 | if (result) { 18 | line = result; 19 | } 20 | } 21 | if (line) { 22 | line.hidden = YES; 23 | } 24 | } 25 | 26 | - (UIView *)jkr_findline:(UIView *)view { 27 | if ([view isKindOfClass:[UIImageView class]] && view.frame.size.height <= 1.0) { 28 | return view; 29 | } else { 30 | for (UIView *subView in view.subviews) { 31 | UIView *result = [self jkr_findline:subView]; 32 | if (result) { 33 | return result; 34 | } 35 | } 36 | } 37 | return nil; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Category/UINavigationController/UINavigationController+JKRBackButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationController+JKRBackButton.h 3 | // BaoJiDianJing 4 | // 5 | // Created by Lucky on 2017/5/5. 6 | // Copyright © 2017年 KaiHei. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UINavigationController (JKRBackButton) 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Category/UINavigationController/UINavigationController+JKRBackButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationController+JKRBackButton.m 3 | // BaoJiDianJing 4 | // 5 | // Created by Lucky on 2017/5/5. 6 | // Copyright © 2017年 KaiHei. All rights reserved. 7 | // 8 | 9 | #import "UINavigationController+JKRBackButton.h" 10 | #import 11 | 12 | @interface UINavigationController () 13 | 14 | @property (nonatomic, strong) id popDelegate; 15 | 16 | @end 17 | 18 | @implementation UINavigationController (JKRBackButton) 19 | 20 | + (void)load { 21 | method_exchangeImplementations(class_getInstanceMethod([UINavigationController class], @selector(initWithRootViewController:)), class_getInstanceMethod([UINavigationController class], @selector(initWithRootViewControllerCustom:))); 22 | method_exchangeImplementations(class_getInstanceMethod([UINavigationController class], @selector(pushViewController:animated:)), class_getInstanceMethod([UINavigationController class], @selector(jkr_pushViewController:animated:))); 23 | } 24 | 25 | - (instancetype)initWithRootViewControllerCustom:(UIViewController *)rootViewController { 26 | self = [self initWithRootViewControllerCustom:rootViewController]; 27 | self.popDelegate = self.interactivePopGestureRecognizer.delegate; 28 | self.delegate = (id)self; 29 | return self; 30 | } 31 | 32 | - (void)setPopDelegate:(id)popDelegate { 33 | objc_setAssociatedObject(self, "jkr_pop_delegate", popDelegate, OBJC_ASSOCIATION_ASSIGN); 34 | } 35 | 36 | - (id)popDelegate { 37 | return objc_getAssociatedObject(self, "jkr_pop_delegate"); 38 | } 39 | 40 | - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated 41 | { 42 | self.interactivePopGestureRecognizer.delegate = viewController == self.viewControllers[0]? self.popDelegate : nil; 43 | } 44 | 45 | - (void)jkr_pushViewController:(UIViewController *)viewController animated:(BOOL)animated { 46 | if (self.childViewControllers.count == 1) { 47 | viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"nav_fh"] style:UIBarButtonItemStyleDone target:self action:@selector(popController)]; 48 | } 49 | [self jkr_pushViewController:viewController animated:YES]; 50 | } 51 | 52 | - (void)popController { 53 | [self popViewControllerAnimated:YES]; 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /Category/UINavigationController/UINavigationController+JKRStatusBar.h: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationController+JKRStatusBar.h 3 | // RongCloudDemo 4 | // 5 | // Created by Lucky on 2017/5/4. 6 | // Copyright © 2017年 KaiHei. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /// 修改NavigationController界面顶栏取决于根控制器 12 | @interface UINavigationController (JKRStatusBar) 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Category/UINavigationController/UINavigationController+JKRStatusBar.m: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationController+JKRStatusBar.m 3 | // RongCloudDemo 4 | // 5 | // Created by Lucky on 2017/5/4. 6 | // Copyright © 2017年 KaiHei. All rights reserved. 7 | // 8 | 9 | #import "UINavigationController+JKRStatusBar.h" 10 | #import 11 | 12 | @implementation UINavigationController (JKRStatusBar) 13 | 14 | + (void)load { 15 | method_exchangeImplementations(class_getInstanceMethod([UINavigationController class], @selector(childViewControllerForStatusBarStyle)), class_getInstanceMethod([UINavigationController class], @selector(jkr_childViewControllerForStatusBarStyle))); 16 | } 17 | 18 | - (UIViewController *)jkr_childViewControllerForStatusBarStyle { 19 | return self.childViewControllers.firstObject; 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Category/UIResponder/UIView+JKR_HitTest.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+JKR_HitTest.h 3 | // JKRUIResponderDemo 4 | // 5 | // Created by Lucky on 17/3/24. 6 | // Copyright © 2017年 Lucky. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIView (JKR_HitTest) 12 | 13 | /// 自定义hitHest方法 14 | - (UIView *)jkr_hitTest:(CGPoint)point withEvent:(UIEvent *)event; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Category/UIResponder/UIView+JKR_HitTest.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+JKR_HitTest.m 3 | // JKRUIResponderDemo 4 | // 5 | // Created by Lucky on 17/3/24. 6 | // Copyright © 2017年 Lucky. All rights reserved. 7 | // 8 | 9 | #import "UIView+JKR_HitTest.h" 10 | 11 | @implementation UIView (JKR_HitTest) 12 | 13 | - (UIView *)jkr_hitTest:(CGPoint)point withEvent:(UIEvent *)event { 14 | if (self.alpha <= 0.01 || self.userInteractionEnabled == false || self.hidden == YES) { 15 | return nil; 16 | } 17 | UIView *lastResultView = nil; 18 | if ([self pointInside:point withEvent:event]) { 19 | lastResultView = self; 20 | NSArray *subViews = [[self.subviews reverseObjectEnumerator] allObjects]; 21 | if (subViews.count) { 22 | for (id view in subViews) { 23 | CGPoint convertPoint = [self convertPoint:point toView:view]; 24 | UIView *currentResultView = [view hitTest:convertPoint withEvent:event]; 25 | if (currentResultView) { 26 | lastResultView = currentResultView; 27 | break; 28 | } 29 | } 30 | return lastResultView; 31 | } else { 32 | return lastResultView; 33 | } 34 | } 35 | return nil; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /Category/UITableView/UITableView+JKREmptyView.h: -------------------------------------------------------------------------------- 1 | // 2 | // UITableView+JKREmptyView.h 3 | // Demo 4 | // 5 | // Created by Lucky on 2017/5/27. 6 | // Copyright © 2017年 Lucky. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UITableView (JKREmptyView) 12 | 13 | /// 为UITableView添加一个空占位控件,跟随滑动,需要制定frame,不支持autolayout 14 | @property (nonatomic, strong) UIView *jkr_placeHolderView; 15 | /// 判定为空是否忽略第一个cell,防止有人用cell充当顶部控件 16 | @property (nonatomic, assign) BOOL jkr_placeHolderIgnoreFirstRow; 17 | 18 | @end 19 | 20 | -------------------------------------------------------------------------------- /Category/UITableView/UITableView+JKREmptyView.m: -------------------------------------------------------------------------------- 1 | // 2 | // UITableView+JKREmptyView.m 3 | // Demo 4 | // 5 | // Created by Lucky on 2017/5/27. 6 | // Copyright © 2017年 Lucky. All rights reserved. 7 | // 8 | 9 | #import "UITableView+JKREmptyView.h" 10 | #import 11 | 12 | @implementation UITableView (JKREmptyView) 13 | 14 | + (void)load { 15 | static dispatch_once_t onceToken; 16 | dispatch_once(&onceToken, ^{ 17 | Method originMethod = class_getInstanceMethod(self, @selector(reloadData)); 18 | Method swizzedMethod = class_getInstanceMethod(self, @selector(jkr_reloadData)); 19 | BOOL methodAdded = class_addMethod(self, @selector(reloadData), method_getImplementation(swizzedMethod), method_getTypeEncoding(swizzedMethod)); 20 | 21 | if (methodAdded) { 22 | class_replaceMethod(self, @selector(jkr_reloadData), method_getImplementation(originMethod), method_getTypeEncoding(originMethod)); 23 | }else{ 24 | method_exchangeImplementations(originMethod, swizzedMethod); 25 | } 26 | }); 27 | } 28 | 29 | - (void)setJkr_placeHolderView:(UIView *)jkr_placeHolderView { 30 | objc_setAssociatedObject(self, @selector(jkr_placeHolderView), jkr_placeHolderView, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 31 | jkr_placeHolderView.hidden = YES; 32 | [self insertSubview:jkr_placeHolderView atIndex:0]; 33 | } 34 | 35 | - (UIView *)jkr_placeHolderView { 36 | return objc_getAssociatedObject(self, @selector(jkr_placeHolderView)); 37 | } 38 | 39 | - (void)setJkr_placeHolderIgnoreFirstRow:(BOOL)jkr_placeHolderIgnoreFirstRow { 40 | objc_setAssociatedObject(self, @selector(jkr_placeHolderIgnoreFirstRow), [NSNumber numberWithBool:jkr_placeHolderIgnoreFirstRow], OBJC_ASSOCIATION_RETAIN_NONATOMIC); 41 | } 42 | 43 | - (BOOL)jkr_placeHolderIgnoreFirstRow { 44 | return [objc_getAssociatedObject(self, @selector(jkr_placeHolderIgnoreFirstRow)) boolValue]; 45 | } 46 | 47 | - (void)jkr_reloadData { 48 | [self jkr_reloadData]; 49 | [self jkr_resetPlaceHoderView]; 50 | } 51 | 52 | - (void)jkr_resetPlaceHoderView { 53 | BOOL isEmpty = YES; 54 | id dataSource = self.dataSource; 55 | NSInteger sectionCount; 56 | if ([dataSource respondsToSelector:@selector(numberOfSectionsInTableView:)]) { 57 | sectionCount = [dataSource numberOfSectionsInTableView:self]; 58 | } else { 59 | sectionCount = 1; 60 | } 61 | if ([dataSource respondsToSelector:@selector(tableView:numberOfRowsInSection:)]) { 62 | for (int i = 0; i < sectionCount; i++) { 63 | if (i == 0 && self.jkr_placeHolderIgnoreFirstRow) { 64 | continue; 65 | } 66 | if ([dataSource tableView:self numberOfRowsInSection:i]) { 67 | isEmpty = NO; 68 | break; 69 | } 70 | } 71 | self.jkr_placeHolderView.hidden = !isEmpty; 72 | } else { 73 | self.jkr_placeHolderView.hidden = NO; 74 | } 75 | } 76 | 77 | @end 78 | -------------------------------------------------------------------------------- /Category/UITextField/UITextField+JKRFilter.h: -------------------------------------------------------------------------------- 1 | // 2 | // UITextField+JKRFilter.h 3 | // JKRCategoryDemo 4 | // 5 | // Created by Joker on 2017/10/5. 6 | // Copyright © 2017 Joker. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef void(^jkr_textFieldChangeBlock)(UITextField *textField); 12 | 13 | @interface UITextField (JKRFilter) 14 | 15 | #pragma mark - delegate:shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 16 | /// 限制输入多少位,中文或联想输入可能会被屏幕 17 | - (BOOL)jkr_limitInputMaxLength:(NSInteger)length shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string; 18 | /// 限制输入仅限数字 19 | - (BOOL)jkr_limitInputNumberWithShouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string; 20 | 21 | #pragma mark - ControlEvents 会和ControlEvents监听冲突 22 | /// 添加长度限制,支持联想和中文 23 | - (void)jkr_addlimitMaxInputLength:(NSInteger)length; 24 | /// 添加长度限制,支持联想和中文,回调实时文字改变 25 | - (void)jkr_addlimitMaxInputLength:(NSInteger)length changeBlock:(jkr_textFieldChangeBlock)changeBlock; 26 | 27 | @end 28 | 29 | -------------------------------------------------------------------------------- /Category/UITextField/UITextField+JKRFilter.m: -------------------------------------------------------------------------------- 1 | // 2 | // UITextField+JKRFilter.m 3 | // JKRCategoryDemo 4 | // 5 | // Created by Joker on 2017/10/5. 6 | // Copyright © 2017 Joker. All rights reserved. 7 | // 8 | 9 | #import "UITextField+JKRFilter.h" 10 | #import 11 | 12 | @interface UITextField () 13 | 14 | @property (nonatomic, assign) NSInteger jkr_max_limit; 15 | @property (nonatomic, copy) jkr_textFieldChangeBlock jkr_textFieldChangeBlock; 16 | 17 | @end 18 | 19 | @implementation UITextField (JKRFilter) 20 | 21 | /// 限制输入多少位 22 | - (BOOL)jkr_limitInputMaxLength:(NSInteger)length shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { 23 | // 允许回删 24 | if (range.length == 1 && string.length == 0) return YES; 25 | NSString *prefix = self.text; 26 | NSString *newValueStr = prefix.length == 0 ? string : [NSString stringWithFormat:@"%@%@",prefix, string]; 27 | if (newValueStr.length > length) return NO; 28 | return YES; 29 | } 30 | 31 | /// 限制输入仅限数字 32 | - (BOOL)jkr_limitInputNumberWithShouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { 33 | // 允许回删 34 | if (range.length == 1 && string.length == 0) return YES; 35 | BOOL res = YES; 36 | NSCharacterSet *tmpSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"]; 37 | int i = 0; 38 | while (i < string.length) { 39 | NSString * str = [string substringWithRange:NSMakeRange(i, 1)]; 40 | NSRange range = [str rangeOfCharacterFromSet:tmpSet]; 41 | if (range.length == 0) { 42 | res = NO; 43 | break; 44 | } 45 | i++; 46 | } 47 | return res; 48 | } 49 | 50 | - (void)jkr_addlimitMaxInputLength:(NSInteger)length { 51 | [self jkr_addlimitMaxInputLength:length changeBlock:nil]; 52 | } 53 | 54 | - (void)jkr_addlimitMaxInputLength:(NSInteger)length changeBlock:(jkr_textFieldChangeBlock)changeBlock { 55 | if (length <= 0) return; 56 | self.jkr_max_limit = length; 57 | self.jkr_textFieldChangeBlock = changeBlock; 58 | [self addTarget:self action:@selector(textDidChange:) forControlEvents:UIControlEventEditingChanged]; 59 | } 60 | 61 | - (NSInteger)jkr_max_limit { 62 | return [objc_getAssociatedObject(self, @selector(jkr_max_limit)) integerValue]; 63 | } 64 | 65 | - (void)setJkr_max_limit:(NSInteger)jkr_max_limit { 66 | objc_setAssociatedObject(self, @selector(jkr_max_limit), [NSNumber numberWithInteger:jkr_max_limit], OBJC_ASSOCIATION_RETAIN_NONATOMIC); 67 | } 68 | 69 | - (jkr_textFieldChangeBlock)jkr_textFieldChangeBlock { 70 | return objc_getAssociatedObject(self, @selector(jkr_textFieldChangeBlock)); 71 | } 72 | 73 | - (void)setJkr_textFieldChangeBlock:(jkr_textFieldChangeBlock)jkr_textFieldChangeBlock { 74 | objc_setAssociatedObject(self, @selector(jkr_textFieldChangeBlock), jkr_textFieldChangeBlock, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 75 | } 76 | 77 | - (void)textDidChange:(UITextField *)textField { 78 | NSInteger kMaxLength = self.jkr_max_limit; 79 | NSString *toBeString = textField.text; 80 | NSString *lang = [[UIApplication sharedApplication]textInputMode].primaryLanguage; //ios7之前使用[UITextInputMode currentInputMode].primaryLanguage 81 | if ([lang isEqualToString:@"zh-Hans"]) { //中文输入 82 | UITextRange *selectedRange = [textField markedTextRange]; 83 | //获取高亮部分 84 | UITextPosition *position = [textField positionFromPosition:selectedRange.start offset:0]; 85 | if (!position) {// 没有高亮选择的字,则对已输入的文字进行字数统计和限制 86 | if (toBeString.length > kMaxLength) { 87 | textField.text = [toBeString substringToIndex:kMaxLength]; 88 | } 89 | } else {//有高亮选择的字符串,则暂不对文字进行统计和限制 90 | 91 | } 92 | }else{//中文输入法以外的直接对其统计限制即可,不考虑其他语种情况 93 | if (toBeString.length > kMaxLength) { 94 | textField.text = [toBeString substringToIndex:kMaxLength]; 95 | } 96 | } 97 | 98 | if (self.jkr_textFieldChangeBlock) self.jkr_textFieldChangeBlock(textField); 99 | } 100 | 101 | @end 102 | -------------------------------------------------------------------------------- /Category/UITextView/UITextView+JKRPlaceHolder.h: -------------------------------------------------------------------------------- 1 | // 2 | // UITextView+JKRPlaceHolder.h 3 | // UITextViewDemo 4 | // 5 | // Created by Lucky on 2017/5/27. 6 | // Copyright © 2017年 Lucky. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UITextView (JKRPlaceHolder) 12 | 13 | /// 有问题,先不要用 14 | @property (nonatomic, strong) NSString *placeHolder; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Category/UITextView/UITextView+JKRPlaceHolder.m: -------------------------------------------------------------------------------- 1 | // 2 | // UITextView+JKRPlaceHolder.m 3 | // UITextViewDemo 4 | // 5 | // Created by Lucky on 2017/5/27. 6 | // Copyright © 2017年 Lucky. All rights reserved. 7 | // 8 | 9 | #import "UITextView+JKRPlaceHolder.h" 10 | #import 11 | 12 | @interface UITextView () 13 | 14 | @property (nonatomic, strong) UILabel *jkr_placeLabel; 15 | @property (nonatomic, weak) id outSideDelegate; 16 | 17 | @end 18 | 19 | @implementation UITextView (JKRPlaceHolder) 20 | 21 | static const char * JKR_UITEXTVIEW_PLACEHOLDER_KEY = "JKR_UITEXTVIEW_PLACEHOLDER_KEY"; 22 | static const char * JKR_UITEXTVIEW_PLACEHOLDER_LABEL_KEY = "JKR_UITEXTVIEW_PLACEHOLDER_LABEL_KEY"; 23 | static const char * JKR_UITEXTVIEW_PLACEHOLDER_DELEGATE_KEY = "JKR_UITEXTVIEW_PLACEHOLDER_DELEGATE_KEY"; 24 | 25 | - (void)jkr_setText:(NSString *)text { 26 | [self jkr_setText:text]; 27 | self.jkr_placeLabel.hidden = text.length; 28 | } 29 | 30 | - (void)jkr_setDelegate:(id)delegate { 31 | if ([self isKindOfClass:[UITextView class]]) { 32 | [self jkr_setDelegate:(id) self]; 33 | if (delegate != self) self.outSideDelegate = delegate; 34 | } 35 | } 36 | 37 | - (void)setOutSideDelegate:(id)outSideDelegate { 38 | objc_setAssociatedObject(self, JKR_UITEXTVIEW_PLACEHOLDER_DELEGATE_KEY, outSideDelegate, OBJC_ASSOCIATION_ASSIGN); 39 | } 40 | 41 | - (id)outSideDelegate { 42 | return objc_getAssociatedObject(self, JKR_UITEXTVIEW_PLACEHOLDER_DELEGATE_KEY); 43 | } 44 | 45 | - (void)setPlaceHolder:(NSString *)placeHolder { 46 | objc_setAssociatedObject(self, JKR_UITEXTVIEW_PLACEHOLDER_KEY, placeHolder, OBJC_ASSOCIATION_COPY_NONATOMIC); 47 | 48 | static dispatch_once_t onceToken; 49 | dispatch_once(&onceToken, ^{ 50 | method_exchangeImplementations(class_getInstanceMethod([self class], @selector(setText:)), class_getInstanceMethod([self class], @selector(jkr_setText:))); 51 | method_exchangeImplementations(class_getInstanceMethod([self class], @selector(setDelegate:)), class_getInstanceMethod([self class], @selector(jkr_setDelegate:))); 52 | 53 | self.jkr_placeLabel = [[UILabel alloc] init]; 54 | [self addSubview:self.jkr_placeLabel]; 55 | self.delegate = self; 56 | }); 57 | 58 | self.jkr_placeLabel.font = self.font; 59 | self.jkr_placeLabel.text = placeHolder; 60 | self.jkr_placeLabel.textColor = [UIColor lightGrayColor]; 61 | [self.jkr_placeLabel sizeToFit]; 62 | CGRect frame = self.jkr_placeLabel.frame; 63 | frame.origin.x = 5; 64 | frame.origin.y = 8; 65 | self.jkr_placeLabel.frame = frame; 66 | } 67 | 68 | - (NSString *)placeHolder { 69 | return objc_getAssociatedObject(self, JKR_UITEXTVIEW_PLACEHOLDER_KEY); 70 | } 71 | 72 | - (UILabel *)jkr_placeLabel { 73 | return objc_getAssociatedObject(self, JKR_UITEXTVIEW_PLACEHOLDER_LABEL_KEY); 74 | } 75 | 76 | - (void)setJkr_placeLabel:(UILabel *)jkr_placeLabel { 77 | objc_setAssociatedObject(self, JKR_UITEXTVIEW_PLACEHOLDER_LABEL_KEY, jkr_placeLabel, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 78 | } 79 | 80 | - (void)textViewDidChange:(UITextView *)textView { 81 | if (self.outSideDelegate && [self.outSideDelegate respondsToSelector:@selector(textViewDidChange:)]) { 82 | [self.outSideDelegate textViewDidChange:textView]; 83 | } 84 | self.jkr_placeLabel.hidden = textView.text.length; 85 | } 86 | 87 | @end 88 | -------------------------------------------------------------------------------- /Category/UIView/UIView+JKRFrame.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+JKRFrame.h 3 | // JKRDemo 4 | // 5 | // Created by Lucky on 14/7/12. 6 | // Copyright © 2014年 Lucky. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #define kScreenWidth [[UIScreen mainScreen] bounds].size.width 12 | #define kScreenHeight [[UIScreen mainScreen] bounds].size.height 13 | 14 | @interface UIView (JKRFrame) 15 | 16 | @property (nonatomic, assign) CGFloat x; 17 | @property (nonatomic, assign) CGFloat y; 18 | @property (nonatomic, assign) CGFloat width; 19 | @property (nonatomic, assign) CGFloat height; 20 | @property (nonatomic, assign) CGSize size; 21 | @property (nonatomic, assign) CGPoint origan; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Category/UIView/UIView+JKRFrame.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+JKRFrame.m 3 | // JKRDemo 4 | // 5 | // Created by Lucky on 14/7/12. 6 | // Copyright © 2014年 Lucky. All rights reserved. 7 | // 8 | 9 | #import "UIView+JKRFrame.h" 10 | 11 | @implementation UIView (JKRFrame) 12 | 13 | - (void)setX:(CGFloat)x { 14 | CGRect frame = self.frame; 15 | frame.origin.x = x; 16 | self.frame = frame; 17 | } 18 | 19 | - (CGFloat)x { 20 | return self.frame.origin.x; 21 | } 22 | 23 | - (void)setY:(CGFloat)y { 24 | CGRect frame = self.frame; 25 | frame.origin.y = y; 26 | self.frame = frame; 27 | } 28 | 29 | - (CGFloat)y { 30 | return self.frame.origin.y; 31 | } 32 | 33 | - (void)setWidth:(CGFloat)width { 34 | CGRect frame = self.frame; 35 | frame.size.width = width; 36 | self.frame = frame; 37 | } 38 | 39 | - (CGFloat)width { 40 | return self.frame.size.width; 41 | } 42 | 43 | - (void)setHeight:(CGFloat)height { 44 | CGRect frame = self.frame; 45 | frame.size.height = height; 46 | self.frame = frame; 47 | } 48 | 49 | - (CGFloat)height { 50 | return self.frame.size.height; 51 | } 52 | 53 | - (void)setSize:(CGSize)size { 54 | CGRect frame = self.frame; 55 | frame.size = size; 56 | self.frame = frame; 57 | } 58 | 59 | - (CGSize)size { 60 | return self.frame.size; 61 | } 62 | 63 | - (void)setOrigan:(CGPoint)origan { 64 | CGRect frame = self.frame; 65 | frame.origin = origan; 66 | self.frame = frame; 67 | } 68 | 69 | - (CGPoint)origan { 70 | return self.frame.origin; 71 | } 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /Category/UIView/UIView+JKRSnap.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+JKRSnap.h 3 | // JKRUIViewDemo 4 | // 5 | // Created by Joker on 2015/9/6. 6 | // Copyright © 2015年 ZHYQ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIView (JKRSnap) 12 | 13 | /// 给当前View截图 14 | - (UIImage *)jkr_snapImage; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Category/UIView/UIView+JKRSnap.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+JKRSnap.m 3 | // JKRUIViewDemo 4 | // 5 | // Created by Joker on 2015/9/6. 6 | // Copyright © 2015年 ZHYQ. All rights reserved. 7 | // 8 | 9 | #import "UIView+JKRSnap.h" 10 | 11 | @implementation UIView (JKRSnap) 12 | 13 | - (UIImage *)jkr_snapImage { 14 | UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.opaque, 0); 15 | [self.layer renderInContext:UIGraphicsGetCurrentContext()]; 16 | UIImage *snapImage = UIGraphicsGetImageFromCurrentImageContext(); 17 | UIGraphicsEndImageContext(); 18 | return snapImage; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Category/UIView/UIView+JKRTapGestureRecognizer.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+JKRTapGestureRecognizer.h 3 | // JKRTouch 4 | // 5 | // Created by Lucky on 2016/8/9. 6 | // Copyright © 2016年 Lucky. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef void(^tapGestureRecognizerBlock)(UIGestureRecognizer *gestureRecognizer); 12 | 13 | @interface UIView (JKRTapGestureRecognizer) 14 | 15 | /// 给控件添加一个点击手势并在block中处理 16 | - (void)jkr_addTapGestureRecognizerWithBlock:(tapGestureRecognizerBlock)block; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Category/UIView/UIView+JKRTapGestureRecognizer.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+JKRTapGestureRecognizer.m 3 | // JKRTouch 4 | // 5 | // Created by Lucky on 2016/8/9. 6 | // Copyright © 2016年 Lucky. All rights reserved. 7 | // 8 | 9 | #import "UIView+JKRTapGestureRecognizer.h" 10 | #import 11 | 12 | @interface UIView () 13 | 14 | @property (nonatomic, strong) tapGestureRecognizerBlock tapBlock; 15 | 16 | @end 17 | 18 | @implementation UIView (JKRTapGestureRecognizer) 19 | 20 | static const char * TAP_BLOCK_KEY = "JKR_TAP_BLOCK_KEY"; 21 | 22 | - (void)jkr_addTapGestureRecognizerWithBlock:(void (^)(UIGestureRecognizer *))block { 23 | UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)]; 24 | self.tapBlock = block; 25 | [self addGestureRecognizer:tapGestureRecognizer]; 26 | } 27 | 28 | - (void)handleTapGesture:(UIGestureRecognizer *)gestureRecognizer { 29 | self.tapBlock(gestureRecognizer); 30 | } 31 | 32 | - (tapGestureRecognizerBlock)tapBlock { 33 | return objc_getAssociatedObject(self, TAP_BLOCK_KEY); 34 | } 35 | 36 | - (void)setTapBlock:(tapGestureRecognizerBlock)tapBlock { 37 | objc_setAssociatedObject(self, TAP_BLOCK_KEY, tapBlock, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Category/UIView/UIView+JKRTouch.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+JKRTouch.h 3 | // JKRSearchDemo 4 | // 5 | // Created by Joker on 2017/4/6. 6 | // Copyright © 2017年 Lucky. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIView (JKRTouch) 12 | 13 | // 是否能够响应touch事件 14 | @property (nonatomic, assign) BOOL unTouch; 15 | // 不响应touch事件的区域 16 | @property (nonatomic, assign) CGRect unTouchRect; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Category/UIView/UIView+JKRTouch.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+JKRTouch.m 3 | // JKRSearchDemo 4 | // 5 | // Created by Joker on 2017/4/6. 6 | // Copyright © 2017年 Lucky. All rights reserved. 7 | // 8 | 9 | #import "UIView+JKRTouch.h" 10 | #import 11 | 12 | @implementation UIView (JKRTouch) 13 | 14 | static const char * JKR_UN_TOUCH_KEY = "JKR_UN_TOUCH"; 15 | static const char * JKR_UN_TOUCH_RECT_KEY = "JKR_UN_TOUCH_RECT"; 16 | 17 | + (void)load { 18 | method_exchangeImplementations(class_getInstanceMethod([UIView class], @selector(pointInside:withEvent:)), class_getInstanceMethod([UIView class], @selector(jkr_pointInside:withEvent:))); 19 | } 20 | 21 | - (void)setUnTouch:(BOOL)unTouch { 22 | objc_setAssociatedObject(self, JKR_UN_TOUCH_KEY, [NSNumber numberWithInt:unTouch], OBJC_ASSOCIATION_RETAIN_NONATOMIC); 23 | } 24 | 25 | - (BOOL)unTouch { 26 | return objc_getAssociatedObject(self, JKR_UN_TOUCH_KEY) ? [objc_getAssociatedObject(self, JKR_UN_TOUCH_KEY) boolValue] : NO; 27 | } 28 | 29 | - (void)setUnTouchRect:(CGRect)unTouchRect { 30 | objc_setAssociatedObject(self, JKR_UN_TOUCH_RECT_KEY, [NSValue valueWithCGRect:unTouchRect], OBJC_ASSOCIATION_RETAIN_NONATOMIC); 31 | } 32 | 33 | - (CGRect)unTouchRect { 34 | return objc_getAssociatedObject(self, JKR_UN_TOUCH_RECT_KEY) ? [objc_getAssociatedObject(self, JKR_UN_TOUCH_RECT_KEY) CGRectValue] : CGRectZero; 35 | } 36 | 37 | - (BOOL)jkr_pointInside:(CGPoint)point withEvent:(UIEvent *)event { 38 | if (self.unTouch) return NO; 39 | if (self.unTouchRect.origin.x == 0 && self.unTouchRect.origin.y == 0 && self.unTouchRect.size.width == 0 && self.unTouchRect.size.height == 0) { 40 | return [self jkr_pointInside:point withEvent:event]; 41 | } else { 42 | if (CGRectContainsPoint(self.unTouchRect, point)) return NO; 43 | else return [self jkr_pointInside:point withEvent:event]; 44 | } 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /Category/UIView/UIView+JKRViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+JKRViewController.h 3 | // JKRSearchDemo 4 | // 5 | // Created by Joker on 2016/5/16. 6 | // Copyright © 2016年 Lucky. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIView (JKRViewController) 12 | 13 | /// 当前视图最近一级的UIViewController 14 | @property (nonatomic, strong, readonly) UIViewController *jkr_viewController; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Category/UIView/UIView+JKRViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+JKRViewController.m 3 | // JKRSearchDemo 4 | // 5 | // Created by Joker on 2016/5/16. 6 | // Copyright © 2016年 Lucky. All rights reserved. 7 | // 8 | 9 | #import "UIView+JKRViewController.h" 10 | 11 | @implementation UIView (JKRViewController) 12 | 13 | - (UIViewController *)jkr_viewController { 14 | UIResponder *next = [self nextResponder]; 15 | do { 16 | if ([next isKindOfClass:[UIViewController class]]) { 17 | return (UIViewController *)next; 18 | } 19 | next = [next nextResponder]; 20 | } while (next != nil); 21 | return nil; 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Category/UIViewController/UIViewController+JKRStatusBarStyle.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+JKRStatusBarStyle.h 3 | // JKRTest 4 | // 5 | // Created by Joker on 2016/5/7. 6 | // Copyright © 2016年 Lucky. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIViewController (JKRStatusBarStyle) 12 | 13 | @property (nonatomic, assign) BOOL jkr_lightStatusBar; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Category/UIViewController/UIViewController+JKRStatusBarStyle.m: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // UIViewController+JKRStatusBarStyle.m 4 | // JKRTest 5 | // 6 | // Created by Joker on 2016/5/7. 7 | // Copyright © 2016年 Lucky. All rights reserved. 8 | // 9 | 10 | #import "UIViewController+JKRStatusBarStyle.h" 11 | #import 12 | 13 | @implementation UIViewController (JKRStatusBarStyle) 14 | 15 | static const char * JKR_STATUS_BAR_LIGHT_KEY = "JKR_STATUS_LIGHT"; 16 | 17 | - (void)setJkr_lightStatusBar:(BOOL)jkr_lightStatusBar { 18 | objc_setAssociatedObject(self, JKR_STATUS_BAR_LIGHT_KEY, [NSNumber numberWithInt:jkr_lightStatusBar], OBJC_ASSOCIATION_RETAIN_NONATOMIC); 19 | [self preferredStatusBarStyle]; 20 | [self setNeedsStatusBarAppearanceUpdate]; 21 | } 22 | 23 | - (BOOL)jkr_lightStatusBar { 24 | return objc_getAssociatedObject(self, JKR_STATUS_BAR_LIGHT_KEY) ? [objc_getAssociatedObject(self, JKR_STATUS_BAR_LIGHT_KEY) boolValue] : NO; 25 | } 26 | 27 | - (UIStatusBarStyle)preferredStatusBarStyle { 28 | return self.jkr_lightStatusBar ? UIStatusBarStyleLightContent : UIStatusBarStyleDefault; 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // JKRCategoryDemo 4 | // 5 | // Created by Joker on 2018/11/3. 6 | // Copyright © 2018 Joker. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // JKRCategoryDemo 4 | // 5 | // Created by Joker on 2018/11/3. 6 | // Copyright © 2018 Joker. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "ahud1@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "ahud1@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud1.imageset/ahud1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud1.imageset/ahud1@2x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud1.imageset/ahud1@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud1.imageset/ahud1@3x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud10.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "ahud10@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "ahud10@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud10.imageset/ahud10@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud10.imageset/ahud10@2x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud10.imageset/ahud10@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud10.imageset/ahud10@3x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud11.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "ahud11@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "ahud11@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud11.imageset/ahud11@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud11.imageset/ahud11@2x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud11.imageset/ahud11@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud11.imageset/ahud11@3x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud12.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "ahud12@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "ahud12@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud12.imageset/ahud12@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud12.imageset/ahud12@2x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud12.imageset/ahud12@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud12.imageset/ahud12@3x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "ahud2@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "ahud2@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud2.imageset/ahud2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud2.imageset/ahud2@2x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud2.imageset/ahud2@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud2.imageset/ahud2@3x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud3.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "ahud3@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "ahud3@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud3.imageset/ahud3@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud3.imageset/ahud3@2x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud3.imageset/ahud3@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud3.imageset/ahud3@3x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud4.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "ahud4@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "ahud4@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud4.imageset/ahud4@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud4.imageset/ahud4@2x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud4.imageset/ahud4@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud4.imageset/ahud4@3x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud5.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "ahud5@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "ahud5@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud5.imageset/ahud5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud5.imageset/ahud5@2x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud5.imageset/ahud5@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud5.imageset/ahud5@3x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud6.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "ahud6@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "ahud6@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud6.imageset/ahud6@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud6.imageset/ahud6@2x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud6.imageset/ahud6@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud6.imageset/ahud6@3x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud7.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "ahud7@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "ahud7@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud7.imageset/ahud7@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud7.imageset/ahud7@2x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud7.imageset/ahud7@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud7.imageset/ahud7@3x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud8.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "ahud8@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "ahud8@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud8.imageset/ahud8@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud8.imageset/ahud8@2x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud8.imageset/ahud8@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud8.imageset/ahud8@3x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud9.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "ahud9@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "ahud9@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud9.imageset/ahud9@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud9.imageset/ahud9@2x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud9.imageset/ahud9@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/ahud9.imageset/ahud9@3x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/contentItemDefault.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "contentItemDefault@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "contentItemDefault@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/contentItemDefault.imageset/contentItemDefault@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/contentItemDefault.imageset/contentItemDefault@2x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/contentItemDefault.imageset/contentItemDefault@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/contentItemDefault.imageset/contentItemDefault@3x.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/timg.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "timg.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/timg.imageset/timg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joker-388/JKRCategory/bc1e8d92a2f852b739890dd8776db515f7a6ebb6/JKRCategoryDemo/JKRCategoryDemo/Assets.xcassets/timg.imageset/timg.png -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 33 | 41 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/Prefix.h: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix.h 3 | // JKRCategoryDemo 4 | // 5 | // Created by Joker on 2018/11/3. 6 | // Copyright © 2018 Joker. All rights reserved. 7 | // 8 | 9 | #ifndef Prefix_h 10 | #define Prefix_h 11 | 12 | #import "UIColor+JKRColor.h" 13 | #define JKRColor(r,g,b,a) [UIColor jkr_colorWithRed:r green:g blue:b alpha:a] 14 | #define JKRColorHex(_hex_) [UIColor jkr_colorWithHexString:((__bridge NSString *)CFSTR(#_hex_))] 15 | 16 | #define JKRColorGray(x) \ 17 | ({\ 18 | NSInteger __color = (x);\ 19 | UIColor *color = [UIColor jkr_colorWithRed:__color green:__color blue:__color alpha:1];\ 20 | (color);\ 21 | })\ 22 | 23 | #import "UIView+JKRFrame.h" 24 | #import "UIView+JKRViewController.h" 25 | #import "UIImage+JKRImage.h" 26 | #define kScreenWidth [[UIScreen mainScreen] bounds].size.width 27 | #define kScreenHeight [[UIScreen mainScreen] bounds].size.height 28 | 29 | #endif /* Prefix_h */ 30 | -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // JKRCategoryDemo 4 | // 5 | // Created by Joker on 2018/11/3. 6 | // Copyright © 2018 Joker. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // JKRCategoryDemo 4 | // 5 | // Created by Joker on 2018/11/3. 6 | // Copyright © 2018 Joker. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "NSString+JKRFilter.h" 11 | #import "UIImageView+JKRImagesAnimation.h" 12 | 13 | @interface ViewController () 14 | 15 | @property (nonatomic, strong) UIImageView *imageView; 16 | @property (nonatomic, strong) NSArray *images; 17 | 18 | 19 | @end 20 | 21 | @implementation ViewController 22 | 23 | - (void)viewDidLoad { 24 | [super viewDidLoad]; 25 | self.view.backgroundColor = [UIColor whiteColor]; 26 | 27 | 28 | } 29 | 30 | - (IBAction)start:(id)sender { 31 | [self.imageView jkr_startAnimationWithDuration:3 images:self.images completion:^(BOOL finished) { 32 | NSLog(@"finish"); 33 | }]; 34 | } 35 | 36 | - (IBAction)startRepeat:(id)sender { 37 | [self.imageView jkr_startRepeatAnimationWithDuration:3 images:self.images]; 38 | } 39 | 40 | - (IBAction)stop:(id)sender { 41 | [self.imageView jkr_finishAnimation]; 42 | } 43 | 44 | - (NSArray *)images { 45 | if (!_images) { 46 | NSMutableArray *array = [NSMutableArray array]; 47 | for (NSInteger i = 1; i < 13; i++) { 48 | [array addObject:[UIImage imageNamed:[NSString stringWithFormat:@"ahud%zd", i]]]; 49 | } 50 | _images = [NSArray arrayWithArray:array]; 51 | } 52 | return _images; 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // JKRCategoryDemo 4 | // 5 | // Created by Joker on 2018/11/3. 6 | // Copyright © 2018 Joker. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemoTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemoTests/JKRCategoryDemoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // JKRCategoryDemoTests.m 3 | // JKRCategoryDemoTests 4 | // 5 | // Created by Joker on 2018/11/3. 6 | // Copyright © 2018 Joker. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface JKRCategoryDemoTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation JKRCategoryDemoTests 16 | 17 | - (void)setUp { 18 | // Put setup code here. This method is called before the invocation of each test method in the class. 19 | } 20 | 21 | - (void)tearDown { 22 | // Put teardown code here. This method is called after the invocation of each test method in the class. 23 | } 24 | 25 | - (void)testExample { 26 | // This is an example of a functional test case. 27 | // Use XCTAssert and related functions to verify your tests produce the correct results. 28 | } 29 | 30 | - (void)testPerformanceExample { 31 | // This is an example of a performance test case. 32 | [self measureBlock:^{ 33 | // Put the code you want to measure the time of here. 34 | }]; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemoUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /JKRCategoryDemo/JKRCategoryDemoUITests/JKRCategoryDemoUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // JKRCategoryDemoUITests.m 3 | // JKRCategoryDemoUITests 4 | // 5 | // Created by Joker on 2018/11/3. 6 | // Copyright © 2018 Joker. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface JKRCategoryDemoUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation JKRCategoryDemoUITests 16 | 17 | - (void)setUp { 18 | // Put setup code here. This method is called before the invocation of each test method in the class. 19 | 20 | // In UI tests it is usually best to stop immediately when a failure occurs. 21 | self.continueAfterFailure = NO; 22 | 23 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 24 | [[[XCUIApplication alloc] init] launch]; 25 | 26 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 27 | } 28 | 29 | - (void)tearDown { 30 | // Put teardown code here. This method is called after the invocation of each test method in the class. 31 | } 32 | 33 | - (void)testExample { 34 | // Use recording to get started writing UI tests. 35 | // Use XCTAssert and related functions to verify your tests produce the correct results. 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /JKRCategoryDemo/Podfile: -------------------------------------------------------------------------------- 1 | platform:ios,'8.0' 2 | 3 | target 'JKRCategoryDemo' do 4 | 5 | end 6 | -------------------------------------------------------------------------------- /JKRCategoryDemo/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODFILE CHECKSUM: 0ba309ef1752b6c218aca428ae84de57da8d2e90 2 | 3 | COCOAPODS: 1.5.3 4 | -------------------------------------------------------------------------------- /JKRCategoryDemo/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODFILE CHECKSUM: 0ba309ef1752b6c218aca428ae84de57da8d2e90 2 | 3 | COCOAPODS: 1.5.3 4 | -------------------------------------------------------------------------------- /JKRCategoryDemo/Pods/Pods.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1FEF5C2C6BAAABDF9DE393DD3C7D4278 /* Pods-JKRCategoryDemo-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 97879E2D5F48AF745DA44F56E9315C85 /* Pods-JKRCategoryDemo-dummy.m */; }; 11 | /* End PBXBuildFile section */ 12 | 13 | /* Begin PBXFileReference section */ 14 | 0BF189FF2249EEFB832F464B3ACDA9FD /* Pods-JKRCategoryDemo-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-JKRCategoryDemo-resources.sh"; sourceTree = ""; }; 15 | 15548DC327ACFAD24F0AA8ABC898731D /* Pods-JKRCategoryDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-JKRCategoryDemo.release.xcconfig"; sourceTree = ""; }; 16 | 1834098FA04D707C606804F99B4FCF16 /* Pods-JKRCategoryDemo-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-JKRCategoryDemo-acknowledgements.plist"; sourceTree = ""; }; 17 | 1E14A9A79F9A003187D12E9D55EE42EF /* Pods-JKRCategoryDemo-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-JKRCategoryDemo-frameworks.sh"; sourceTree = ""; }; 18 | 204C57B643799DD91A29422ADB7BDB74 /* Pods-JKRCategoryDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-JKRCategoryDemo.debug.xcconfig"; sourceTree = ""; }; 19 | 73714A4255DA4E635E98F952DFB279A7 /* libPods-JKRCategoryDemo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libPods-JKRCategoryDemo.a"; path = "libPods-JKRCategoryDemo.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 20 | 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 21 | 97879E2D5F48AF745DA44F56E9315C85 /* Pods-JKRCategoryDemo-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-JKRCategoryDemo-dummy.m"; sourceTree = ""; }; 22 | CAD6F11EEA021D7493C4109B13380328 /* Pods-JKRCategoryDemo-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-JKRCategoryDemo-acknowledgements.markdown"; sourceTree = ""; }; 23 | /* End PBXFileReference section */ 24 | 25 | /* Begin PBXFrameworksBuildPhase section */ 26 | 0202E2EF8F0A52E6B5911DBB6E1B9A98 /* Frameworks */ = { 27 | isa = PBXFrameworksBuildPhase; 28 | buildActionMask = 2147483647; 29 | files = ( 30 | ); 31 | runOnlyForDeploymentPostprocessing = 0; 32 | }; 33 | /* End PBXFrameworksBuildPhase section */ 34 | 35 | /* Begin PBXGroup section */ 36 | 0F8D2E47FE03D3B91B51069F7C273AF4 /* Frameworks */ = { 37 | isa = PBXGroup; 38 | children = ( 39 | ); 40 | name = Frameworks; 41 | sourceTree = ""; 42 | }; 43 | 7DB346D0F39D3F0E887471402A8071AB = { 44 | isa = PBXGroup; 45 | children = ( 46 | 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */, 47 | 0F8D2E47FE03D3B91B51069F7C273AF4 /* Frameworks */, 48 | 825F17E6DC6409A1E6C6925E492C1A8B /* Products */, 49 | 90A17433FCA121EC36818A0D69B97F8F /* Targets Support Files */, 50 | ); 51 | sourceTree = ""; 52 | }; 53 | 825F17E6DC6409A1E6C6925E492C1A8B /* Products */ = { 54 | isa = PBXGroup; 55 | children = ( 56 | 73714A4255DA4E635E98F952DFB279A7 /* libPods-JKRCategoryDemo.a */, 57 | ); 58 | name = Products; 59 | sourceTree = ""; 60 | }; 61 | 90A17433FCA121EC36818A0D69B97F8F /* Targets Support Files */ = { 62 | isa = PBXGroup; 63 | children = ( 64 | B34E77A34D820718EA9FB74A820DBA4C /* Pods-JKRCategoryDemo */, 65 | ); 66 | name = "Targets Support Files"; 67 | sourceTree = ""; 68 | }; 69 | B34E77A34D820718EA9FB74A820DBA4C /* Pods-JKRCategoryDemo */ = { 70 | isa = PBXGroup; 71 | children = ( 72 | CAD6F11EEA021D7493C4109B13380328 /* Pods-JKRCategoryDemo-acknowledgements.markdown */, 73 | 1834098FA04D707C606804F99B4FCF16 /* Pods-JKRCategoryDemo-acknowledgements.plist */, 74 | 97879E2D5F48AF745DA44F56E9315C85 /* Pods-JKRCategoryDemo-dummy.m */, 75 | 1E14A9A79F9A003187D12E9D55EE42EF /* Pods-JKRCategoryDemo-frameworks.sh */, 76 | 0BF189FF2249EEFB832F464B3ACDA9FD /* Pods-JKRCategoryDemo-resources.sh */, 77 | 204C57B643799DD91A29422ADB7BDB74 /* Pods-JKRCategoryDemo.debug.xcconfig */, 78 | 15548DC327ACFAD24F0AA8ABC898731D /* Pods-JKRCategoryDemo.release.xcconfig */, 79 | ); 80 | name = "Pods-JKRCategoryDemo"; 81 | path = "Target Support Files/Pods-JKRCategoryDemo"; 82 | sourceTree = ""; 83 | }; 84 | /* End PBXGroup section */ 85 | 86 | /* Begin PBXHeadersBuildPhase section */ 87 | CADC3E8CD3DB3D0387A45FA0C166DDFA /* Headers */ = { 88 | isa = PBXHeadersBuildPhase; 89 | buildActionMask = 2147483647; 90 | files = ( 91 | ); 92 | runOnlyForDeploymentPostprocessing = 0; 93 | }; 94 | /* End PBXHeadersBuildPhase section */ 95 | 96 | /* Begin PBXNativeTarget section */ 97 | 999E6D17CDE51D7A3534DB8DB970C008 /* Pods-JKRCategoryDemo */ = { 98 | isa = PBXNativeTarget; 99 | buildConfigurationList = 6B8559F4DF8F10BF31D213C848153537 /* Build configuration list for PBXNativeTarget "Pods-JKRCategoryDemo" */; 100 | buildPhases = ( 101 | CADC3E8CD3DB3D0387A45FA0C166DDFA /* Headers */, 102 | CB7785C2BB84DC079252B8D9C64F1B2B /* Sources */, 103 | 0202E2EF8F0A52E6B5911DBB6E1B9A98 /* Frameworks */, 104 | ); 105 | buildRules = ( 106 | ); 107 | dependencies = ( 108 | ); 109 | name = "Pods-JKRCategoryDemo"; 110 | productName = "Pods-JKRCategoryDemo"; 111 | productReference = 73714A4255DA4E635E98F952DFB279A7 /* libPods-JKRCategoryDemo.a */; 112 | productType = "com.apple.product-type.library.static"; 113 | }; 114 | /* End PBXNativeTarget section */ 115 | 116 | /* Begin PBXProject section */ 117 | D41D8CD98F00B204E9800998ECF8427E /* Project object */ = { 118 | isa = PBXProject; 119 | attributes = { 120 | LastSwiftUpdateCheck = 0930; 121 | LastUpgradeCheck = 0930; 122 | }; 123 | buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; 124 | compatibilityVersion = "Xcode 3.2"; 125 | developmentRegion = English; 126 | hasScannedForEncodings = 0; 127 | knownRegions = ( 128 | en, 129 | ); 130 | mainGroup = 7DB346D0F39D3F0E887471402A8071AB; 131 | productRefGroup = 825F17E6DC6409A1E6C6925E492C1A8B /* Products */; 132 | projectDirPath = ""; 133 | projectRoot = ""; 134 | targets = ( 135 | 999E6D17CDE51D7A3534DB8DB970C008 /* Pods-JKRCategoryDemo */, 136 | ); 137 | }; 138 | /* End PBXProject section */ 139 | 140 | /* Begin PBXSourcesBuildPhase section */ 141 | CB7785C2BB84DC079252B8D9C64F1B2B /* Sources */ = { 142 | isa = PBXSourcesBuildPhase; 143 | buildActionMask = 2147483647; 144 | files = ( 145 | 1FEF5C2C6BAAABDF9DE393DD3C7D4278 /* Pods-JKRCategoryDemo-dummy.m in Sources */, 146 | ); 147 | runOnlyForDeploymentPostprocessing = 0; 148 | }; 149 | /* End PBXSourcesBuildPhase section */ 150 | 151 | /* Begin XCBuildConfiguration section */ 152 | 3479F5BCBD7F8DA77B8B1E0C163CE4A4 /* Release */ = { 153 | isa = XCBuildConfiguration; 154 | baseConfigurationReference = 15548DC327ACFAD24F0AA8ABC898731D /* Pods-JKRCategoryDemo.release.xcconfig */; 155 | buildSettings = { 156 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; 157 | CODE_SIGN_IDENTITY = "iPhone Developer"; 158 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 159 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 160 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 161 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 162 | MACH_O_TYPE = staticlib; 163 | OTHER_LDFLAGS = ""; 164 | OTHER_LIBTOOLFLAGS = ""; 165 | PODS_ROOT = "$(SRCROOT)"; 166 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 167 | SDKROOT = iphoneos; 168 | SKIP_INSTALL = YES; 169 | TARGETED_DEVICE_FAMILY = "1,2"; 170 | VALIDATE_PRODUCT = YES; 171 | }; 172 | name = Release; 173 | }; 174 | 85B95B1234E227C814CCC2C7902D0916 /* Release */ = { 175 | isa = XCBuildConfiguration; 176 | buildSettings = { 177 | ALWAYS_SEARCH_USER_PATHS = NO; 178 | CLANG_ANALYZER_NONNULL = YES; 179 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 180 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 181 | CLANG_CXX_LIBRARY = "libc++"; 182 | CLANG_ENABLE_MODULES = YES; 183 | CLANG_ENABLE_OBJC_ARC = YES; 184 | CLANG_ENABLE_OBJC_WEAK = YES; 185 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 186 | CLANG_WARN_BOOL_CONVERSION = YES; 187 | CLANG_WARN_COMMA = YES; 188 | CLANG_WARN_CONSTANT_CONVERSION = YES; 189 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 190 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 191 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 192 | CLANG_WARN_EMPTY_BODY = YES; 193 | CLANG_WARN_ENUM_CONVERSION = YES; 194 | CLANG_WARN_INFINITE_RECURSION = YES; 195 | CLANG_WARN_INT_CONVERSION = YES; 196 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 197 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 198 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 199 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 200 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 201 | CLANG_WARN_STRICT_PROTOTYPES = YES; 202 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 203 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 204 | CLANG_WARN_UNREACHABLE_CODE = YES; 205 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 206 | CODE_SIGNING_ALLOWED = NO; 207 | CODE_SIGNING_REQUIRED = NO; 208 | COPY_PHASE_STRIP = NO; 209 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 210 | ENABLE_NS_ASSERTIONS = NO; 211 | ENABLE_STRICT_OBJC_MSGSEND = YES; 212 | GCC_C_LANGUAGE_STANDARD = gnu11; 213 | GCC_NO_COMMON_BLOCKS = YES; 214 | GCC_PREPROCESSOR_DEFINITIONS = ( 215 | "POD_CONFIGURATION_RELEASE=1", 216 | "$(inherited)", 217 | ); 218 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 219 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 220 | GCC_WARN_UNDECLARED_SELECTOR = YES; 221 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 222 | GCC_WARN_UNUSED_FUNCTION = YES; 223 | GCC_WARN_UNUSED_VARIABLE = YES; 224 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 225 | MTL_ENABLE_DEBUG_INFO = NO; 226 | MTL_FAST_MATH = YES; 227 | PRODUCT_NAME = "$(TARGET_NAME)"; 228 | STRIP_INSTALLED_PRODUCT = NO; 229 | SWIFT_COMPILATION_MODE = wholemodule; 230 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 231 | SWIFT_VERSION = 4.2; 232 | SYMROOT = "${SRCROOT}/../build"; 233 | }; 234 | name = Release; 235 | }; 236 | A73625DEBD810B78234FA1958C191C8C /* Debug */ = { 237 | isa = XCBuildConfiguration; 238 | buildSettings = { 239 | ALWAYS_SEARCH_USER_PATHS = NO; 240 | CLANG_ANALYZER_NONNULL = YES; 241 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 242 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 243 | CLANG_CXX_LIBRARY = "libc++"; 244 | CLANG_ENABLE_MODULES = YES; 245 | CLANG_ENABLE_OBJC_ARC = YES; 246 | CLANG_ENABLE_OBJC_WEAK = YES; 247 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 248 | CLANG_WARN_BOOL_CONVERSION = YES; 249 | CLANG_WARN_COMMA = YES; 250 | CLANG_WARN_CONSTANT_CONVERSION = YES; 251 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 252 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 253 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 254 | CLANG_WARN_EMPTY_BODY = YES; 255 | CLANG_WARN_ENUM_CONVERSION = YES; 256 | CLANG_WARN_INFINITE_RECURSION = YES; 257 | CLANG_WARN_INT_CONVERSION = YES; 258 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 259 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 260 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 261 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 262 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 263 | CLANG_WARN_STRICT_PROTOTYPES = YES; 264 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 265 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 266 | CLANG_WARN_UNREACHABLE_CODE = YES; 267 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 268 | CODE_SIGNING_ALLOWED = NO; 269 | CODE_SIGNING_REQUIRED = NO; 270 | COPY_PHASE_STRIP = NO; 271 | DEBUG_INFORMATION_FORMAT = dwarf; 272 | ENABLE_STRICT_OBJC_MSGSEND = YES; 273 | ENABLE_TESTABILITY = YES; 274 | GCC_C_LANGUAGE_STANDARD = gnu11; 275 | GCC_DYNAMIC_NO_PIC = NO; 276 | GCC_NO_COMMON_BLOCKS = YES; 277 | GCC_OPTIMIZATION_LEVEL = 0; 278 | GCC_PREPROCESSOR_DEFINITIONS = ( 279 | "POD_CONFIGURATION_DEBUG=1", 280 | "DEBUG=1", 281 | "$(inherited)", 282 | ); 283 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 284 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 285 | GCC_WARN_UNDECLARED_SELECTOR = YES; 286 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 287 | GCC_WARN_UNUSED_FUNCTION = YES; 288 | GCC_WARN_UNUSED_VARIABLE = YES; 289 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 290 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 291 | MTL_FAST_MATH = YES; 292 | ONLY_ACTIVE_ARCH = YES; 293 | PRODUCT_NAME = "$(TARGET_NAME)"; 294 | STRIP_INSTALLED_PRODUCT = NO; 295 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 296 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 297 | SWIFT_VERSION = 4.2; 298 | SYMROOT = "${SRCROOT}/../build"; 299 | }; 300 | name = Debug; 301 | }; 302 | F9E2D64F05ECDD47156702A360904CB4 /* Debug */ = { 303 | isa = XCBuildConfiguration; 304 | baseConfigurationReference = 204C57B643799DD91A29422ADB7BDB74 /* Pods-JKRCategoryDemo.debug.xcconfig */; 305 | buildSettings = { 306 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; 307 | CODE_SIGN_IDENTITY = "iPhone Developer"; 308 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 309 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 310 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 311 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 312 | MACH_O_TYPE = staticlib; 313 | OTHER_LDFLAGS = ""; 314 | OTHER_LIBTOOLFLAGS = ""; 315 | PODS_ROOT = "$(SRCROOT)"; 316 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 317 | SDKROOT = iphoneos; 318 | SKIP_INSTALL = YES; 319 | TARGETED_DEVICE_FAMILY = "1,2"; 320 | }; 321 | name = Debug; 322 | }; 323 | /* End XCBuildConfiguration section */ 324 | 325 | /* Begin XCConfigurationList section */ 326 | 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { 327 | isa = XCConfigurationList; 328 | buildConfigurations = ( 329 | A73625DEBD810B78234FA1958C191C8C /* Debug */, 330 | 85B95B1234E227C814CCC2C7902D0916 /* Release */, 331 | ); 332 | defaultConfigurationIsVisible = 0; 333 | defaultConfigurationName = Release; 334 | }; 335 | 6B8559F4DF8F10BF31D213C848153537 /* Build configuration list for PBXNativeTarget "Pods-JKRCategoryDemo" */ = { 336 | isa = XCConfigurationList; 337 | buildConfigurations = ( 338 | F9E2D64F05ECDD47156702A360904CB4 /* Debug */, 339 | 3479F5BCBD7F8DA77B8B1E0C163CE4A4 /* Release */, 340 | ); 341 | defaultConfigurationIsVisible = 0; 342 | defaultConfigurationName = Release; 343 | }; 344 | /* End XCConfigurationList section */ 345 | }; 346 | rootObject = D41D8CD98F00B204E9800998ECF8427E /* Project object */; 347 | } 348 | -------------------------------------------------------------------------------- /JKRCategoryDemo/Pods/Target Support Files/Pods-JKRCategoryDemo/Pods-JKRCategoryDemo-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /JKRCategoryDemo/Pods/Target Support Files/Pods-JKRCategoryDemo/Pods-JKRCategoryDemo-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /JKRCategoryDemo/Pods/Target Support Files/Pods-JKRCategoryDemo/Pods-JKRCategoryDemo-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_JKRCategoryDemo : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_JKRCategoryDemo 5 | @end 6 | -------------------------------------------------------------------------------- /JKRCategoryDemo/Pods/Target Support Files/Pods-JKRCategoryDemo/Pods-JKRCategoryDemo-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then 7 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy 8 | # frameworks to, so exit 0 (signalling the script phase was successful). 9 | exit 0 10 | fi 11 | 12 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 13 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 14 | 15 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" 16 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 17 | 18 | # Used as a return value for each invocation of `strip_invalid_archs` function. 19 | STRIP_BINARY_RETVAL=0 20 | 21 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 22 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 23 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 24 | 25 | # Copies and strips a vendored framework 26 | install_framework() 27 | { 28 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 29 | local source="${BUILT_PRODUCTS_DIR}/$1" 30 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 31 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 32 | elif [ -r "$1" ]; then 33 | local source="$1" 34 | fi 35 | 36 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 37 | 38 | if [ -L "${source}" ]; then 39 | echo "Symlinked..." 40 | source="$(readlink "${source}")" 41 | fi 42 | 43 | # Use filter instead of exclude so missing patterns don't throw errors. 44 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 45 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 46 | 47 | local basename 48 | basename="$(basename -s .framework "$1")" 49 | binary="${destination}/${basename}.framework/${basename}" 50 | if ! [ -r "$binary" ]; then 51 | binary="${destination}/${basename}" 52 | fi 53 | 54 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 55 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 56 | strip_invalid_archs "$binary" 57 | fi 58 | 59 | # Resign the code if required by the build settings to avoid unstable apps 60 | code_sign_if_enabled "${destination}/$(basename "$1")" 61 | 62 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 63 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 64 | local swift_runtime_libs 65 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 66 | for lib in $swift_runtime_libs; do 67 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 68 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 69 | code_sign_if_enabled "${destination}/${lib}" 70 | done 71 | fi 72 | } 73 | 74 | # Copies and strips a vendored dSYM 75 | install_dsym() { 76 | local source="$1" 77 | if [ -r "$source" ]; then 78 | # Copy the dSYM into a the targets temp dir. 79 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" 80 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" 81 | 82 | local basename 83 | basename="$(basename -s .framework.dSYM "$source")" 84 | binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" 85 | 86 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 87 | if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then 88 | strip_invalid_archs "$binary" 89 | fi 90 | 91 | if [[ $STRIP_BINARY_RETVAL == 1 ]]; then 92 | # Move the stripped file into its final destination. 93 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" 94 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" 95 | else 96 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. 97 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" 98 | fi 99 | fi 100 | } 101 | 102 | # Signs a framework with the provided identity 103 | code_sign_if_enabled() { 104 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 105 | # Use the current code_sign_identitiy 106 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 107 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" 108 | 109 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 110 | code_sign_cmd="$code_sign_cmd &" 111 | fi 112 | echo "$code_sign_cmd" 113 | eval "$code_sign_cmd" 114 | fi 115 | } 116 | 117 | # Strip invalid architectures 118 | strip_invalid_archs() { 119 | binary="$1" 120 | # Get architectures for current target binary 121 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" 122 | # Intersect them with the architectures we are building for 123 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" 124 | # If there are no archs supported by this binary then warn the user 125 | if [[ -z "$intersected_archs" ]]; then 126 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." 127 | STRIP_BINARY_RETVAL=0 128 | return 129 | fi 130 | stripped="" 131 | for arch in $binary_archs; do 132 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 133 | # Strip non-valid architectures in-place 134 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 135 | stripped="$stripped $arch" 136 | fi 137 | done 138 | if [[ "$stripped" ]]; then 139 | echo "Stripped $binary of architectures:$stripped" 140 | fi 141 | STRIP_BINARY_RETVAL=1 142 | } 143 | 144 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 145 | wait 146 | fi 147 | -------------------------------------------------------------------------------- /JKRCategoryDemo/Pods/Target Support Files/Pods-JKRCategoryDemo/Pods-JKRCategoryDemo-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then 7 | # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy 8 | # resources to, so exit 0 (signalling the script phase was successful). 9 | exit 0 10 | fi 11 | 12 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 13 | 14 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 15 | > "$RESOURCES_TO_COPY" 16 | 17 | XCASSET_FILES=() 18 | 19 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 20 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 21 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 22 | 23 | case "${TARGETED_DEVICE_FAMILY:-}" in 24 | 1,2) 25 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 26 | ;; 27 | 1) 28 | TARGET_DEVICE_ARGS="--target-device iphone" 29 | ;; 30 | 2) 31 | TARGET_DEVICE_ARGS="--target-device ipad" 32 | ;; 33 | 3) 34 | TARGET_DEVICE_ARGS="--target-device tv" 35 | ;; 36 | 4) 37 | TARGET_DEVICE_ARGS="--target-device watch" 38 | ;; 39 | *) 40 | TARGET_DEVICE_ARGS="--target-device mac" 41 | ;; 42 | esac 43 | 44 | install_resource() 45 | { 46 | if [[ "$1" = /* ]] ; then 47 | RESOURCE_PATH="$1" 48 | else 49 | RESOURCE_PATH="${PODS_ROOT}/$1" 50 | fi 51 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 52 | cat << EOM 53 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 54 | EOM 55 | exit 1 56 | fi 57 | case $RESOURCE_PATH in 58 | *.storyboard) 59 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 60 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 61 | ;; 62 | *.xib) 63 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 64 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 65 | ;; 66 | *.framework) 67 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 68 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 69 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 70 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 71 | ;; 72 | *.xcdatamodel) 73 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true 74 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 75 | ;; 76 | *.xcdatamodeld) 77 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true 78 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 79 | ;; 80 | *.xcmappingmodel) 81 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true 82 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 83 | ;; 84 | *.xcassets) 85 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 86 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 87 | ;; 88 | *) 89 | echo "$RESOURCE_PATH" || true 90 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 91 | ;; 92 | esac 93 | } 94 | 95 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 96 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 97 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 98 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 99 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 100 | fi 101 | rm -f "$RESOURCES_TO_COPY" 102 | 103 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] 104 | then 105 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 106 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 107 | while read line; do 108 | if [[ $line != "${PODS_ROOT}*" ]]; then 109 | XCASSET_FILES+=("$line") 110 | fi 111 | done <<<"$OTHER_XCASSETS" 112 | 113 | if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then 114 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 115 | else 116 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist" 117 | fi 118 | fi 119 | -------------------------------------------------------------------------------- /JKRCategoryDemo/Pods/Target Support Files/Pods-JKRCategoryDemo/Pods-JKRCategoryDemo.debug.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | OTHER_LDFLAGS = $(inherited) -ObjC 3 | PODS_BUILD_DIR = ${BUILD_DIR} 4 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 5 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 6 | PODS_ROOT = ${SRCROOT}/Pods 7 | -------------------------------------------------------------------------------- /JKRCategoryDemo/Pods/Target Support Files/Pods-JKRCategoryDemo/Pods-JKRCategoryDemo.release.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | OTHER_LDFLAGS = $(inherited) -ObjC 3 | PODS_BUILD_DIR = ${BUILD_DIR} 4 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 5 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 6 | PODS_ROOT = ${SRCROOT}/Pods 7 | --------------------------------------------------------------------------------