├── .gitignore ├── Examples ├── JMRoundedCornerDemo.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── JMRoundedCornerDemo.xcworkspace │ └── contents.xcworkspacedata ├── JMRoundedCornerDemo │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── avatar.imageset │ │ │ ├── Contents.json │ │ │ └── avatar.jpg │ │ ├── giftpack_close.imageset │ │ │ ├── Contents.json │ │ │ ├── guanbi@2x.png │ │ │ └── guanbi@3x.png │ │ └── share_QQ.imageset │ │ │ ├── Contents.json │ │ │ ├── share_qq@2x.png │ │ │ └── share_qq@3x.png │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ ├── TableViewCell.h │ ├── TableViewCell.m │ ├── UIControl+YYAdd.h │ ├── UIControl+YYAdd.m │ ├── ViewController.h │ ├── ViewController.m │ ├── ViewController2.h │ ├── ViewController2.m │ └── main.m ├── Podfile ├── Podfile.lock ├── Pods │ ├── Headers │ │ ├── Private │ │ │ ├── YYCache │ │ │ │ ├── YYCache.h │ │ │ │ ├── YYDiskCache.h │ │ │ │ ├── YYKVStorage.h │ │ │ │ └── YYMemoryCache.h │ │ │ ├── YYImage │ │ │ │ ├── YYAnimatedImageView.h │ │ │ │ ├── YYFrameImage.h │ │ │ │ ├── YYImage.h │ │ │ │ ├── YYImageCoder.h │ │ │ │ └── YYSpriteSheetImage.h │ │ │ └── YYWebImage │ │ │ │ ├── CALayer+YYWebImage.h │ │ │ │ ├── MKAnnotationView+YYWebImage.h │ │ │ │ ├── UIButton+YYWebImage.h │ │ │ │ ├── UIImage+YYWebImage.h │ │ │ │ ├── UIImageView+YYWebImage.h │ │ │ │ ├── YYImageCache.h │ │ │ │ ├── YYWebImage.h │ │ │ │ ├── YYWebImageManager.h │ │ │ │ ├── YYWebImageOperation.h │ │ │ │ └── _YYWebImageSetter.h │ │ └── Public │ │ │ ├── YYCache │ │ │ ├── YYCache.h │ │ │ ├── YYDiskCache.h │ │ │ ├── YYKVStorage.h │ │ │ └── YYMemoryCache.h │ │ │ ├── YYImage │ │ │ ├── YYAnimatedImageView.h │ │ │ ├── YYFrameImage.h │ │ │ ├── YYImage.h │ │ │ ├── YYImageCoder.h │ │ │ └── YYSpriteSheetImage.h │ │ │ └── YYWebImage │ │ │ ├── CALayer+YYWebImage.h │ │ │ ├── MKAnnotationView+YYWebImage.h │ │ │ ├── UIButton+YYWebImage.h │ │ │ ├── UIImage+YYWebImage.h │ │ │ ├── UIImageView+YYWebImage.h │ │ │ ├── YYImageCache.h │ │ │ ├── YYWebImage.h │ │ │ ├── YYWebImageManager.h │ │ │ └── YYWebImageOperation.h │ ├── Local Podspecs │ │ └── YYWebImage.podspec.json │ ├── Manifest.lock │ ├── Pods.xcodeproj │ │ └── project.pbxproj │ ├── Target Support Files │ │ ├── Pods-JMRoundedCornerDemo │ │ │ ├── Pods-JMRoundedCornerDemo-acknowledgements.markdown │ │ │ ├── Pods-JMRoundedCornerDemo-acknowledgements.plist │ │ │ ├── Pods-JMRoundedCornerDemo-dummy.m │ │ │ ├── Pods-JMRoundedCornerDemo-frameworks.sh │ │ │ ├── Pods-JMRoundedCornerDemo-resources.sh │ │ │ ├── Pods-JMRoundedCornerDemo.debug.xcconfig │ │ │ └── Pods-JMRoundedCornerDemo.release.xcconfig │ │ ├── YYCache │ │ │ ├── YYCache-dummy.m │ │ │ ├── YYCache-prefix.pch │ │ │ └── YYCache.xcconfig │ │ ├── YYImage │ │ │ ├── YYImage-dummy.m │ │ │ ├── YYImage-prefix.pch │ │ │ └── YYImage.xcconfig │ │ └── YYWebImage │ │ │ ├── YYWebImage-dummy.m │ │ │ ├── YYWebImage-prefix.pch │ │ │ └── YYWebImage.xcconfig │ ├── YYCache │ │ ├── LICENSE │ │ ├── README.md │ │ └── YYCache │ │ │ ├── YYCache.h │ │ │ ├── YYCache.m │ │ │ ├── YYDiskCache.h │ │ │ ├── YYDiskCache.m │ │ │ ├── YYKVStorage.h │ │ │ ├── YYKVStorage.m │ │ │ ├── YYMemoryCache.h │ │ │ └── YYMemoryCache.m │ ├── YYImage │ │ ├── LICENSE │ │ ├── README.md │ │ └── YYImage │ │ │ ├── YYAnimatedImageView.h │ │ │ ├── YYAnimatedImageView.m │ │ │ ├── YYFrameImage.h │ │ │ ├── YYFrameImage.m │ │ │ ├── YYImage.h │ │ │ ├── YYImage.m │ │ │ ├── YYImageCoder.h │ │ │ ├── YYImageCoder.m │ │ │ ├── YYSpriteSheetImage.h │ │ │ └── YYSpriteSheetImage.m │ └── YYWebImage │ │ ├── LICENSE │ │ ├── README.md │ │ └── YYWebImage │ │ ├── Categories │ │ ├── CALayer+YYWebImage.h │ │ ├── CALayer+YYWebImage.m │ │ ├── MKAnnotationView+YYWebImage.h │ │ ├── MKAnnotationView+YYWebImage.m │ │ ├── UIButton+YYWebImage.h │ │ ├── UIButton+YYWebImage.m │ │ ├── UIImage+YYWebImage.h │ │ ├── UIImage+YYWebImage.m │ │ ├── UIImageView+YYWebImage.h │ │ ├── UIImageView+YYWebImage.m │ │ ├── _YYWebImageSetter.h │ │ └── _YYWebImageSetter.m │ │ ├── YYImageCache.h │ │ ├── YYImageCache.m │ │ ├── YYWebImage.h │ │ ├── YYWebImageManager.h │ │ ├── YYWebImageManager.m │ │ ├── YYWebImageOperation.h │ │ └── YYWebImageOperation.m └── dots18.gif ├── JMRoundedCorner.podspec ├── JMRoundedCorner ├── JMRoundedCorner.h ├── UIButton+JMRadius.h ├── UIButton+JMRadius.m ├── UIImage+JMRadius.h ├── UIImage+JMRadius.m ├── UIImageView+JMRadius.h ├── UIImageView+JMRadius.m ├── UIView+JMRadius.h └── UIView+JMRadius.m ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # macOS 2 | .DS_Store 3 | 4 | ## Xcode / Obj-C 5 | 6 | ## Build generated 7 | build/ 8 | DerivedData/ 9 | 10 | ## Various settings 11 | *.pbxuser 12 | !default.pbxuser 13 | *.mode1v3 14 | !default.mode1v3 15 | *.mode2v3 16 | !default.mode2v3 17 | *.perspectivev3 18 | !default.perspectivev3 19 | xcuserdata/ 20 | 21 | ## Other 22 | *.moved-aside 23 | *.xccheckout 24 | *.xcscmblueprint 25 | *.xcuserstate 26 | 27 | ## Obj-C/Swift specific 28 | *.hmap 29 | *.ipa 30 | -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // JMRoundedCornerDemo 4 | // 5 | // Created by 饶志臻 on 2016/10/7. 6 | // Copyright © 2016年 饶志臻. 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 | -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // JMRoundedCornerDemo 4 | // 5 | // Created by 饶志臻 on 2016/10/7. 6 | // Copyright © 2016年 饶志臻. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "ViewController.h" 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 20 | _window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 21 | _window.backgroundColor = [UIColor whiteColor]; 22 | _window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[ViewController new]]; 23 | [_window makeKeyAndVisible]; 24 | return YES; 25 | } 26 | 27 | 28 | - (void)applicationWillResignActive:(UIApplication *)application { 29 | // 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. 30 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 31 | } 32 | 33 | 34 | - (void)applicationDidEnterBackground:(UIApplication *)application { 35 | // 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. 36 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 37 | } 38 | 39 | 40 | - (void)applicationWillEnterForeground:(UIApplication *)application { 41 | // 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. 42 | } 43 | 44 | 45 | - (void)applicationDidBecomeActive:(UIApplication *)application { 46 | // 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. 47 | } 48 | 49 | 50 | - (void)applicationWillTerminate:(UIApplication *)application { 51 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 52 | } 53 | 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo/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 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo/Assets.xcassets/avatar.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "avatar.jpg", 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 | } -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo/Assets.xcassets/avatar.imageset/avatar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raozhizhen/JMRoundedCorner/d577bb3f7c100c73e0fba426790530856274c60a/Examples/JMRoundedCornerDemo/Assets.xcassets/avatar.imageset/avatar.jpg -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo/Assets.xcassets/giftpack_close.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "guanbi@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "guanbi@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo/Assets.xcassets/giftpack_close.imageset/guanbi@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raozhizhen/JMRoundedCorner/d577bb3f7c100c73e0fba426790530856274c60a/Examples/JMRoundedCornerDemo/Assets.xcassets/giftpack_close.imageset/guanbi@2x.png -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo/Assets.xcassets/giftpack_close.imageset/guanbi@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raozhizhen/JMRoundedCorner/d577bb3f7c100c73e0fba426790530856274c60a/Examples/JMRoundedCornerDemo/Assets.xcassets/giftpack_close.imageset/guanbi@3x.png -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo/Assets.xcassets/share_QQ.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "share_qq@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "share_qq@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo/Assets.xcassets/share_QQ.imageset/share_qq@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raozhizhen/JMRoundedCorner/d577bb3f7c100c73e0fba426790530856274c60a/Examples/JMRoundedCornerDemo/Assets.xcassets/share_QQ.imageset/share_qq@2x.png -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo/Assets.xcassets/share_QQ.imageset/share_qq@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raozhizhen/JMRoundedCorner/d577bb3f7c100c73e0fba426790530856274c60a/Examples/JMRoundedCornerDemo/Assets.xcassets/share_QQ.imageset/share_qq@3x.png -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo/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 | 27 | 28 | -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo/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 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 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 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo/TableViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // TableViewCell.h 3 | // JMRoundedCornerDemo 4 | // 5 | // Created by 饶志臻 on 2016/10/7. 6 | // Copyright © 2016年 饶志臻. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TableViewCell : UITableViewCell 12 | 13 | @property (nonatomic, strong) NSURL *avatarURL; 14 | 15 | + (NSString *)cellReuseIdentifier; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo/TableViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // TableViewCell.m 3 | // JMRoundedCornerDemo 4 | // 5 | // Created by 饶志臻 on 2016/10/7. 6 | // Copyright © 2016年 饶志臻. All rights reserved. 7 | // 8 | 9 | #import "TableViewCell.h" 10 | #import "JMRoundedCorner.h" 11 | #import "UIImageView+YYWebImage.h" 12 | 13 | @interface TableViewCell () 14 | 15 | @property (nonatomic, strong) UIImageView *avatarView; 16 | @property (nonatomic, strong) UIButton *button; 17 | @property (nonatomic, strong) UILabel *label; 18 | 19 | @end 20 | 21 | @implementation TableViewCell 22 | 23 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 24 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 25 | if (self) { 26 | [self setupViews]; 27 | } 28 | return self; 29 | } 30 | 31 | - (void)setupViews { 32 | self.contentView.backgroundColor = [UIColor lightGrayColor]; 33 | 34 | _avatarView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 7, 40, 40)]; 35 | [self.contentView addSubview:_avatarView]; 36 | 37 | NSInteger viewWidth = ([UIScreen mainScreen].bounds.size.width - 78) / 2; 38 | 39 | _button = [[UIButton alloc] initWithFrame:CGRectMake(60 + 0.22, 7, viewWidth + 0.34, 40)]; 40 | [_button setTitle:@"button" forState:UIControlStateNormal]; 41 | [_button jm_setImageWithJMRadius:JMRadiusMake(10, 2, 10, 2) image:[UIImage imageNamed:@"avatar"] borderColor:[UIColor blueColor] borderWidth:1 backgroundColor:[UIColor whiteColor] contentMode:UIViewContentModeScaleAspectFill size:CGSizeMake(viewWidth + 0.34, 40) forState:UIControlStateNormal completion:nil]; 42 | _button.titleLabel.font = [UIFont systemFontOfSize:12]; 43 | [_button setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; 44 | [self.contentView addSubview:_button]; 45 | 46 | _label = [[UILabel alloc] initWithFrame:CGRectMake(70 + viewWidth , 7, viewWidth, 40)]; 47 | _label.text = @"label"; 48 | [_label jm_setImageWithJMRadius:JMRadiusMake(2, 10, 2, 10) borderColor:[UIColor redColor] borderWidth:0.5 backgroundColor:[UIColor whiteColor]]; 49 | _label.font = [UIFont systemFontOfSize:12]; 50 | _label.textAlignment = NSTextAlignmentCenter; 51 | [self.contentView addSubview:_label]; 52 | } 53 | 54 | - (void)setAvatarURL:(NSURL *)avatarURL { 55 | _avatarURL = avatarURL; 56 | 57 | // [_avatarView jm_setImageWithCornerRadius:20 imageURL:_avatarURL placeholder:@"avatar" size:CGSizeMake(40, 40)]; 58 | 59 | [_avatarView jm_setImageWithJMRadius:JMRadiusMake(20, 20, 20, 20) 60 | imageURL:_avatarURL 61 | placeholder:[UIImage imageNamed:@"avatar"] 62 | borderColor:[UIColor redColor] 63 | borderWidth:1 64 | backgroundColor:[UIColor blueColor] 65 | contentMode:UIViewContentModeScaleAspectFill 66 | size:CGSizeMake(40, 40)]; 67 | 68 | [_button jm_setImageWithJMRadius:JMRadiusMake(2, 10, 2, 10) imageURL:_avatarURL placeholder:[UIImage imageNamed:@"avatar"] borderColor:[UIColor redColor] borderWidth:1 backgroundColor:nil contentMode:UIViewContentModeScaleAspectFill size:_button.bounds.size forState:UIControlStateHighlighted]; 69 | } 70 | 71 | + (NSString *)cellReuseIdentifier { 72 | return NSStringFromClass(self); 73 | } 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo/UIControl+YYAdd.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIControl+YYAdd.h 3 | // UIImageRoundedCornerDemo 4 | // 5 | // Created by jm on 16/3/12. 6 | // Copyright © 2016年 Jim. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIControl (YYAdd) 12 | 13 | - (void)addBlockForControlEvents:(UIControlEvents)controlEvents block:(void (^)(id sender))block; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo/UIControl+YYAdd.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIControl+YYAdd.m 3 | // UIImageRoundedCornerDemo 4 | // 5 | // Created by jm on 16/3/12. 6 | // Copyright © 2016年 Jim. All rights reserved. 7 | // 8 | 9 | #import "UIControl+YYAdd.h" 10 | #import 11 | 12 | #ifndef YYSYNTH_DUMMY_CLASS 13 | #define YYSYNTH_DUMMY_CLASS(_name_) \ 14 | @interface YYSYNTH_DUMMY_CLASS_ ## _name_ : NSObject @end \ 15 | @implementation YYSYNTH_DUMMY_CLASS_ ## _name_ @end 16 | #endif 17 | 18 | YYSYNTH_DUMMY_CLASS(UIControl_YYAdd) 19 | 20 | 21 | static const int block_key; 22 | 23 | @interface _YYUIControlBlockTarget : NSObject 24 | 25 | @property (nonatomic, copy) void (^block)(id sender); 26 | @property (nonatomic, assign) UIControlEvents events; 27 | 28 | - (id)initWithBlock:(void (^)(id sender))block events:(UIControlEvents)events; 29 | - (void)invoke:(id)sender; 30 | 31 | @end 32 | 33 | @implementation _YYUIControlBlockTarget 34 | 35 | - (id)initWithBlock:(void (^)(id sender))block events:(UIControlEvents)events { 36 | self = [super init]; 37 | if (self) { 38 | _block = [block copy]; 39 | _events = events; 40 | } 41 | return self; 42 | } 43 | 44 | - (void)invoke:(id)sender { 45 | if (_block) _block(sender); 46 | } 47 | 48 | @end 49 | 50 | @implementation UIControl (YYAdd) 51 | 52 | 53 | - (void)addBlockForControlEvents:(UIControlEvents)controlEvents 54 | block:(void (^)(id sender))block { 55 | if (!controlEvents) return; 56 | _YYUIControlBlockTarget *target = [[_YYUIControlBlockTarget alloc] 57 | initWithBlock:block events:controlEvents]; 58 | [self addTarget:target action:@selector(invoke:) forControlEvents:controlEvents]; 59 | NSMutableArray *targets = [self _yy_allUIControlBlockTargets]; 60 | [targets addObject:target]; 61 | } 62 | 63 | - (NSMutableArray *)_yy_allUIControlBlockTargets { 64 | NSMutableArray *targets = objc_getAssociatedObject(self, &block_key); 65 | if (!targets) { 66 | targets = [NSMutableArray array]; 67 | objc_setAssociatedObject(self, &block_key, targets, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 68 | } 69 | return targets; 70 | } 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // JMRoundedCornerDemo 4 | // 5 | // Created by 饶志臻 on 2016/10/7. 6 | // Copyright © 2016年 饶志臻. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // JMRoundedCornerDemo 4 | // 5 | // Created by 饶志臻 on 2016/10/7. 6 | // Copyright © 2016年 饶志臻. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "ViewController2.h" 11 | #import "TableViewCell.h" 12 | 13 | @interface ViewController () 14 | 15 | @end 16 | 17 | @implementation ViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | // http://image.raozhizhen.com/avatar.png 22 | self.title = @"使用JMRoundedCorner绘制圆角"; 23 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"切换" style:UIBarButtonItemStylePlain target:self action:@selector(rightBarButtonClick)]; 24 | 25 | UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStylePlain]; 26 | [tableView registerClass:[TableViewCell class] forCellReuseIdentifier:[TableViewCell cellReuseIdentifier]]; 27 | tableView.rowHeight = 54; 28 | tableView.dataSource = self; 29 | [self.view addSubview:tableView]; 30 | } 31 | 32 | - (void)rightBarButtonClick { 33 | ViewController2 *VC = [[ViewController2 alloc] init]; 34 | [self.navigationController pushViewController:VC animated:YES]; 35 | } 36 | 37 | 38 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 39 | return 1000; 40 | } 41 | 42 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 43 | TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:[TableViewCell cellReuseIdentifier] forIndexPath:indexPath]; 44 | cell.avatarURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://oepjvpu5g.qnssl.com/avatar%li.jpg", indexPath.row % 20]]; 45 | return cell; 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo/ViewController2.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController2.h 3 | // JMRoundedCornerDemo 4 | // 5 | // Created by 饶志臻 on 2016/10/7. 6 | // Copyright © 2016年 饶志臻. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController2 : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo/ViewController2.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController2.m 3 | // JMRoundedCornerDemo 4 | // 5 | // Created by 饶志臻 on 2016/10/7. 6 | // Copyright © 2016年 饶志臻. All rights reserved. 7 | // 8 | 9 | #import "ViewController2.h" 10 | #import "JMRoundedCorner.h" 11 | #import "UIControl+YYAdd.h" 12 | 13 | @implementation ViewController2 { 14 | UIImageView *_imageView; 15 | UISlider *_slider0; 16 | UISlider *_slider1; 17 | UISlider *_slider2; 18 | UISlider *_slider3; 19 | UISlider *_slider4; 20 | } 21 | 22 | - (void)viewDidLoad { 23 | [super viewDidLoad]; 24 | self.title = @"测试用页面"; 25 | self.view.backgroundColor = [UIColor lightGrayColor]; 26 | 27 | CGFloat viewWidth = self.view.frame.size.width - 40; 28 | 29 | _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 80, viewWidth, 200)]; 30 | [_imageView jm_setImageWithJMRadius: JMRadiusMake(20, 20, 20, 20) image:[UIImage imageNamed:@"avatar"] borderColor:[UIColor redColor] borderWidth:10 backgroundColor:[UIColor blueColor] contentMode:UIViewContentModeScaleAspectFill]; 31 | [self.view addSubview:_imageView]; 32 | 33 | _slider0 = [[UISlider alloc] initWithFrame:CGRectMake(20, 340, viewWidth, 20)]; 34 | _slider0.minimumValue = 0; 35 | _slider0.maximumValue = 300; 36 | _slider0.value = 20; 37 | [self.view addSubview:_slider0]; 38 | 39 | _slider1 = [[UISlider alloc] initWithFrame:CGRectMake(20, 380, viewWidth, 20)]; 40 | _slider1.minimumValue = 0; 41 | _slider1.maximumValue = 300; 42 | _slider1.value = 20; 43 | [self.view addSubview:_slider1]; 44 | 45 | _slider2 = [[UISlider alloc] initWithFrame:CGRectMake(20, 420, viewWidth, 20)]; 46 | _slider2.minimumValue = 0; 47 | _slider2.maximumValue = 300; 48 | _slider2.value = 20; 49 | [self.view addSubview:_slider2]; 50 | 51 | _slider3 = [[UISlider alloc] initWithFrame:CGRectMake(20, 460, viewWidth, 20)]; 52 | _slider3.minimumValue = 0; 53 | _slider3.maximumValue = 300; 54 | _slider3.value = 20; 55 | [self.view addSubview:_slider3]; 56 | 57 | _slider4 = [[UISlider alloc] initWithFrame:CGRectMake(20, 520, viewWidth, 20)]; 58 | _slider4.minimumValue = 0; 59 | _slider4.maximumValue = 30; 60 | _slider4.value = 10; 61 | [self.view addSubview:_slider4]; 62 | 63 | __weak typeof(self) weakSelf = self; 64 | [_slider0 addBlockForControlEvents:UIControlEventValueChanged block:^(id sender) { 65 | [weakSelf sliderChanged]; 66 | }]; 67 | [_slider1 addBlockForControlEvents:UIControlEventValueChanged block:^(id sender) { 68 | [weakSelf sliderChanged]; 69 | }]; 70 | [_slider2 addBlockForControlEvents:UIControlEventValueChanged block:^(id sender) { 71 | [weakSelf sliderChanged]; 72 | }]; 73 | [_slider3 addBlockForControlEvents:UIControlEventValueChanged block:^(id sender) { 74 | [weakSelf sliderChanged]; 75 | }]; 76 | [_slider4 addBlockForControlEvents:UIControlEventValueChanged block:^(id sender) { 77 | [weakSelf sliderChanged]; 78 | }]; 79 | } 80 | 81 | - (void)sliderChanged { 82 | [_imageView jm_setImageWithJMRadius:JMRadiusMake(_slider0.value, _slider1.value, _slider2.value, _slider3.value) imageURL:[NSURL URLWithString:@"https://oepjvpu5g.qnssl.com/avatar12.jpg"] placeholder:[UIImage imageNamed:@"avatar"] borderColor:[UIColor redColor] borderWidth:_slider4.value backgroundColor:[UIColor whiteColor] contentMode:UIViewContentModeScaleAspectFill size:CGSizeMake(self.view.frame.size.width - 40, 200)]; 83 | 84 | // [_imageView jm_setImageWithJMRadius:JMRadiusMake(_slider0.value, _slider1.value, _slider2.value, _slider3.value) image:[UIImage imageNamed:@"avatar.jpg"] borderColor:[UIColor redColor] borderWidth:_slider4.value backgroundColor:[UIColor blueColor] contentMode:UIViewContentModeScaleAspectFill]; 85 | } 86 | 87 | @end 88 | -------------------------------------------------------------------------------- /Examples/JMRoundedCornerDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // JMRoundedCornerDemo 4 | // 5 | // Created by 饶志臻 on 2016/10/7. 6 | // Copyright © 2016年 饶志臻. 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 | -------------------------------------------------------------------------------- /Examples/Podfile: -------------------------------------------------------------------------------- 1 | target ‘JMRoundedCornerDemo’ do 2 | platform :ios,’7.0’ 3 | 4 | pod 'YYWebImage', :git => 'https://github.com/raozhizhen/YYWebImage.git', :tag => '1.0.5' 5 | 6 | end 7 | 8 | -------------------------------------------------------------------------------- /Examples/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - YYCache (1.0.4) 3 | - YYImage (1.0.4): 4 | - YYImage/Core (= 1.0.4) 5 | - YYImage/Core (1.0.4) 6 | - YYWebImage (1.0.5): 7 | - YYCache 8 | - YYImage 9 | 10 | DEPENDENCIES: 11 | - YYWebImage (from `https://github.com/raozhizhen/YYWebImage.git`, tag `1.0.5`) 12 | 13 | EXTERNAL SOURCES: 14 | YYWebImage: 15 | :git: https://github.com/raozhizhen/YYWebImage.git 16 | :tag: 1.0.5 17 | 18 | CHECKOUT OPTIONS: 19 | YYWebImage: 20 | :git: https://github.com/raozhizhen/YYWebImage.git 21 | :tag: 1.0.5 22 | 23 | SPEC CHECKSUMS: 24 | YYCache: 8105b6638f5e849296c71f331ff83891a4942952 25 | YYImage: 1e1b62a9997399593e4b9c4ecfbbabbf1d3f3b54 26 | YYWebImage: 5f7f36aee2ae293f016d418c7d6ba05c4863e928 27 | 28 | PODFILE CHECKSUM: 6ee0f2ac6bb1e71ebfe130dc5fdf906b023e251f 29 | 30 | COCOAPODS: 1.0.1 31 | -------------------------------------------------------------------------------- /Examples/Pods/Headers/Private/YYCache/YYCache.h: -------------------------------------------------------------------------------- 1 | ../../../YYCache/YYCache/YYCache.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Private/YYCache/YYDiskCache.h: -------------------------------------------------------------------------------- 1 | ../../../YYCache/YYCache/YYDiskCache.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Private/YYCache/YYKVStorage.h: -------------------------------------------------------------------------------- 1 | ../../../YYCache/YYCache/YYKVStorage.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Private/YYCache/YYMemoryCache.h: -------------------------------------------------------------------------------- 1 | ../../../YYCache/YYCache/YYMemoryCache.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Private/YYImage/YYAnimatedImageView.h: -------------------------------------------------------------------------------- 1 | ../../../YYImage/YYImage/YYAnimatedImageView.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Private/YYImage/YYFrameImage.h: -------------------------------------------------------------------------------- 1 | ../../../YYImage/YYImage/YYFrameImage.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Private/YYImage/YYImage.h: -------------------------------------------------------------------------------- 1 | ../../../YYImage/YYImage/YYImage.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Private/YYImage/YYImageCoder.h: -------------------------------------------------------------------------------- 1 | ../../../YYImage/YYImage/YYImageCoder.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Private/YYImage/YYSpriteSheetImage.h: -------------------------------------------------------------------------------- 1 | ../../../YYImage/YYImage/YYSpriteSheetImage.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Private/YYWebImage/CALayer+YYWebImage.h: -------------------------------------------------------------------------------- 1 | ../../../YYWebImage/YYWebImage/Categories/CALayer+YYWebImage.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Private/YYWebImage/MKAnnotationView+YYWebImage.h: -------------------------------------------------------------------------------- 1 | ../../../YYWebImage/YYWebImage/Categories/MKAnnotationView+YYWebImage.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Private/YYWebImage/UIButton+YYWebImage.h: -------------------------------------------------------------------------------- 1 | ../../../YYWebImage/YYWebImage/Categories/UIButton+YYWebImage.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Private/YYWebImage/UIImage+YYWebImage.h: -------------------------------------------------------------------------------- 1 | ../../../YYWebImage/YYWebImage/Categories/UIImage+YYWebImage.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Private/YYWebImage/UIImageView+YYWebImage.h: -------------------------------------------------------------------------------- 1 | ../../../YYWebImage/YYWebImage/Categories/UIImageView+YYWebImage.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Private/YYWebImage/YYImageCache.h: -------------------------------------------------------------------------------- 1 | ../../../YYWebImage/YYWebImage/YYImageCache.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Private/YYWebImage/YYWebImage.h: -------------------------------------------------------------------------------- 1 | ../../../YYWebImage/YYWebImage/YYWebImage.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Private/YYWebImage/YYWebImageManager.h: -------------------------------------------------------------------------------- 1 | ../../../YYWebImage/YYWebImage/YYWebImageManager.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Private/YYWebImage/YYWebImageOperation.h: -------------------------------------------------------------------------------- 1 | ../../../YYWebImage/YYWebImage/YYWebImageOperation.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Private/YYWebImage/_YYWebImageSetter.h: -------------------------------------------------------------------------------- 1 | ../../../YYWebImage/YYWebImage/Categories/_YYWebImageSetter.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Public/YYCache/YYCache.h: -------------------------------------------------------------------------------- 1 | ../../../YYCache/YYCache/YYCache.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Public/YYCache/YYDiskCache.h: -------------------------------------------------------------------------------- 1 | ../../../YYCache/YYCache/YYDiskCache.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Public/YYCache/YYKVStorage.h: -------------------------------------------------------------------------------- 1 | ../../../YYCache/YYCache/YYKVStorage.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Public/YYCache/YYMemoryCache.h: -------------------------------------------------------------------------------- 1 | ../../../YYCache/YYCache/YYMemoryCache.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Public/YYImage/YYAnimatedImageView.h: -------------------------------------------------------------------------------- 1 | ../../../YYImage/YYImage/YYAnimatedImageView.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Public/YYImage/YYFrameImage.h: -------------------------------------------------------------------------------- 1 | ../../../YYImage/YYImage/YYFrameImage.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Public/YYImage/YYImage.h: -------------------------------------------------------------------------------- 1 | ../../../YYImage/YYImage/YYImage.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Public/YYImage/YYImageCoder.h: -------------------------------------------------------------------------------- 1 | ../../../YYImage/YYImage/YYImageCoder.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Public/YYImage/YYSpriteSheetImage.h: -------------------------------------------------------------------------------- 1 | ../../../YYImage/YYImage/YYSpriteSheetImage.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Public/YYWebImage/CALayer+YYWebImage.h: -------------------------------------------------------------------------------- 1 | ../../../YYWebImage/YYWebImage/Categories/CALayer+YYWebImage.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Public/YYWebImage/MKAnnotationView+YYWebImage.h: -------------------------------------------------------------------------------- 1 | ../../../YYWebImage/YYWebImage/Categories/MKAnnotationView+YYWebImage.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Public/YYWebImage/UIButton+YYWebImage.h: -------------------------------------------------------------------------------- 1 | ../../../YYWebImage/YYWebImage/Categories/UIButton+YYWebImage.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Public/YYWebImage/UIImage+YYWebImage.h: -------------------------------------------------------------------------------- 1 | ../../../YYWebImage/YYWebImage/Categories/UIImage+YYWebImage.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Public/YYWebImage/UIImageView+YYWebImage.h: -------------------------------------------------------------------------------- 1 | ../../../YYWebImage/YYWebImage/Categories/UIImageView+YYWebImage.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Public/YYWebImage/YYImageCache.h: -------------------------------------------------------------------------------- 1 | ../../../YYWebImage/YYWebImage/YYImageCache.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Public/YYWebImage/YYWebImage.h: -------------------------------------------------------------------------------- 1 | ../../../YYWebImage/YYWebImage/YYWebImage.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Public/YYWebImage/YYWebImageManager.h: -------------------------------------------------------------------------------- 1 | ../../../YYWebImage/YYWebImage/YYWebImageManager.h -------------------------------------------------------------------------------- /Examples/Pods/Headers/Public/YYWebImage/YYWebImageOperation.h: -------------------------------------------------------------------------------- 1 | ../../../YYWebImage/YYWebImage/YYWebImageOperation.h -------------------------------------------------------------------------------- /Examples/Pods/Local Podspecs/YYWebImage.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "YYWebImage", 3 | "summary": "Asynchronous image loading framework.", 4 | "version": "1.0.5", 5 | "license": { 6 | "type": "MIT", 7 | "file": "LICENSE" 8 | }, 9 | "authors": { 10 | "ibireme": "ibireme@gmail.com" 11 | }, 12 | "social_media_url": "http://blog.ibireme.com", 13 | "homepage": "https://github.com/ibireme/YYWebImage", 14 | "platforms": { 15 | "ios": "6.0" 16 | }, 17 | "source": { 18 | "git": "https://github.com/ibireme/YYWebImage.git", 19 | "tag": "1.0.5" 20 | }, 21 | "requires_arc": true, 22 | "source_files": [ 23 | "YYWebImage/*.{h,m}", 24 | "YYWebImage/Categories/*.{h,m}" 25 | ], 26 | "public_header_files": [ 27 | "YYWebImage/*.{h}", 28 | "YYWebImage/Categories/*.{h}" 29 | ], 30 | "private_header_files": "YYWebImage/Categories/_*.{h}", 31 | "frameworks": [ 32 | "UIKit", 33 | "CoreFoundation", 34 | "QuartzCore", 35 | "AssetsLibrary", 36 | "ImageIO", 37 | "Accelerate", 38 | "MobileCoreServices" 39 | ], 40 | "dependencies": { 41 | "YYImage": [ 42 | 43 | ], 44 | "YYCache": [ 45 | 46 | ] 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Examples/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - YYCache (1.0.4) 3 | - YYImage (1.0.4): 4 | - YYImage/Core (= 1.0.4) 5 | - YYImage/Core (1.0.4) 6 | - YYWebImage (1.0.5): 7 | - YYCache 8 | - YYImage 9 | 10 | DEPENDENCIES: 11 | - YYWebImage (from `https://github.com/raozhizhen/YYWebImage.git`, tag `1.0.5`) 12 | 13 | EXTERNAL SOURCES: 14 | YYWebImage: 15 | :git: https://github.com/raozhizhen/YYWebImage.git 16 | :tag: 1.0.5 17 | 18 | CHECKOUT OPTIONS: 19 | YYWebImage: 20 | :git: https://github.com/raozhizhen/YYWebImage.git 21 | :tag: 1.0.5 22 | 23 | SPEC CHECKSUMS: 24 | YYCache: 8105b6638f5e849296c71f331ff83891a4942952 25 | YYImage: 1e1b62a9997399593e4b9c4ecfbbabbf1d3f3b54 26 | YYWebImage: 5f7f36aee2ae293f016d418c7d6ba05c4863e928 27 | 28 | PODFILE CHECKSUM: 6ee0f2ac6bb1e71ebfe130dc5fdf906b023e251f 29 | 30 | COCOAPODS: 1.0.1 31 | -------------------------------------------------------------------------------- /Examples/Pods/Target Support Files/Pods-JMRoundedCornerDemo/Pods-JMRoundedCornerDemo-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## YYCache 5 | 6 | The MIT License (MIT) 7 | 8 | Copyright (c) 2015 ibireme 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | 29 | 30 | ## YYImage 31 | 32 | The MIT License (MIT) 33 | 34 | Copyright (c) 2015 ibireme 35 | 36 | Permission is hereby granted, free of charge, to any person obtaining a copy 37 | of this software and associated documentation files (the "Software"), to deal 38 | in the Software without restriction, including without limitation the rights 39 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 40 | copies of the Software, and to permit persons to whom the Software is 41 | furnished to do so, subject to the following conditions: 42 | 43 | The above copyright notice and this permission notice shall be included in all 44 | copies or substantial portions of the Software. 45 | 46 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 47 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 48 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 49 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 50 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 51 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 52 | SOFTWARE. 53 | 54 | 55 | 56 | ## YYWebImage 57 | 58 | The MIT License (MIT) 59 | 60 | Copyright (c) 2015 ibireme 61 | 62 | Permission is hereby granted, free of charge, to any person obtaining a copy 63 | of this software and associated documentation files (the "Software"), to deal 64 | in the Software without restriction, including without limitation the rights 65 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 66 | copies of the Software, and to permit persons to whom the Software is 67 | furnished to do so, subject to the following conditions: 68 | 69 | The above copyright notice and this permission notice shall be included in all 70 | copies or substantial portions of the Software. 71 | 72 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 73 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 74 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 75 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 76 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 77 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 78 | SOFTWARE. 79 | 80 | 81 | Generated by CocoaPods - https://cocoapods.org 82 | -------------------------------------------------------------------------------- /Examples/Pods/Target Support Files/Pods-JMRoundedCornerDemo/Pods-JMRoundedCornerDemo-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 | The MIT License (MIT) 18 | 19 | Copyright (c) 2015 ibireme <ibireme@gmail.com> 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all 29 | copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 37 | SOFTWARE. 38 | 39 | 40 | Title 41 | YYCache 42 | Type 43 | PSGroupSpecifier 44 | 45 | 46 | FooterText 47 | The MIT License (MIT) 48 | 49 | Copyright (c) 2015 ibireme <ibireme@gmail.com> 50 | 51 | Permission is hereby granted, free of charge, to any person obtaining a copy 52 | of this software and associated documentation files (the "Software"), to deal 53 | in the Software without restriction, including without limitation the rights 54 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 55 | copies of the Software, and to permit persons to whom the Software is 56 | furnished to do so, subject to the following conditions: 57 | 58 | The above copyright notice and this permission notice shall be included in all 59 | copies or substantial portions of the Software. 60 | 61 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 62 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 63 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 64 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 65 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 66 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 67 | SOFTWARE. 68 | 69 | 70 | Title 71 | YYImage 72 | Type 73 | PSGroupSpecifier 74 | 75 | 76 | FooterText 77 | The MIT License (MIT) 78 | 79 | Copyright (c) 2015 ibireme <ibireme@gmail.com> 80 | 81 | Permission is hereby granted, free of charge, to any person obtaining a copy 82 | of this software and associated documentation files (the "Software"), to deal 83 | in the Software without restriction, including without limitation the rights 84 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 85 | copies of the Software, and to permit persons to whom the Software is 86 | furnished to do so, subject to the following conditions: 87 | 88 | The above copyright notice and this permission notice shall be included in all 89 | copies or substantial portions of the Software. 90 | 91 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 92 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 93 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 94 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 95 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 96 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 97 | SOFTWARE. 98 | 99 | 100 | Title 101 | YYWebImage 102 | Type 103 | PSGroupSpecifier 104 | 105 | 106 | FooterText 107 | Generated by CocoaPods - https://cocoapods.org 108 | Title 109 | 110 | Type 111 | PSGroupSpecifier 112 | 113 | 114 | StringsTable 115 | Acknowledgements 116 | Title 117 | Acknowledgements 118 | 119 | 120 | -------------------------------------------------------------------------------- /Examples/Pods/Target Support Files/Pods-JMRoundedCornerDemo/Pods-JMRoundedCornerDemo-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_JMRoundedCornerDemo : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_JMRoundedCornerDemo 5 | @end 6 | -------------------------------------------------------------------------------- /Examples/Pods/Target Support Files/Pods-JMRoundedCornerDemo/Pods-JMRoundedCornerDemo-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | install_framework() 10 | { 11 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 12 | local source="${BUILT_PRODUCTS_DIR}/$1" 13 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 14 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 15 | elif [ -r "$1" ]; then 16 | local source="$1" 17 | fi 18 | 19 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 20 | 21 | if [ -L "${source}" ]; then 22 | echo "Symlinked..." 23 | source="$(readlink "${source}")" 24 | fi 25 | 26 | # use filter instead of exclude so missing patterns dont' throw errors 27 | echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 28 | rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 29 | 30 | local basename 31 | basename="$(basename -s .framework "$1")" 32 | binary="${destination}/${basename}.framework/${basename}" 33 | if ! [ -r "$binary" ]; then 34 | binary="${destination}/${basename}" 35 | fi 36 | 37 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 38 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 39 | strip_invalid_archs "$binary" 40 | fi 41 | 42 | # Resign the code if required by the build settings to avoid unstable apps 43 | code_sign_if_enabled "${destination}/$(basename "$1")" 44 | 45 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 46 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 47 | local swift_runtime_libs 48 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 49 | for lib in $swift_runtime_libs; do 50 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 51 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 52 | code_sign_if_enabled "${destination}/${lib}" 53 | done 54 | fi 55 | } 56 | 57 | # Signs a framework with the provided identity 58 | code_sign_if_enabled() { 59 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 60 | # Use the current code_sign_identitiy 61 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 62 | echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements \"$1\"" 63 | /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1" 64 | fi 65 | } 66 | 67 | # Strip invalid architectures 68 | strip_invalid_archs() { 69 | binary="$1" 70 | # Get architectures for current file 71 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 72 | stripped="" 73 | for arch in $archs; do 74 | if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then 75 | # Strip non-valid architectures in-place 76 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 77 | stripped="$stripped $arch" 78 | fi 79 | done 80 | if [[ "$stripped" ]]; then 81 | echo "Stripped $binary of architectures:$stripped" 82 | fi 83 | } 84 | 85 | -------------------------------------------------------------------------------- /Examples/Pods/Target Support Files/Pods-JMRoundedCornerDemo/Pods-JMRoundedCornerDemo-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | case "${TARGETED_DEVICE_FAMILY}" in 12 | 1,2) 13 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 14 | ;; 15 | 1) 16 | TARGET_DEVICE_ARGS="--target-device iphone" 17 | ;; 18 | 2) 19 | TARGET_DEVICE_ARGS="--target-device ipad" 20 | ;; 21 | *) 22 | TARGET_DEVICE_ARGS="--target-device mac" 23 | ;; 24 | esac 25 | 26 | realpath() { 27 | DIRECTORY="$(cd "${1%/*}" && pwd)" 28 | FILENAME="${1##*/}" 29 | echo "$DIRECTORY/$FILENAME" 30 | } 31 | 32 | install_resource() 33 | { 34 | if [[ "$1" = /* ]] ; then 35 | RESOURCE_PATH="$1" 36 | else 37 | RESOURCE_PATH="${PODS_ROOT}/$1" 38 | fi 39 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 40 | cat << EOM 41 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 42 | EOM 43 | exit 1 44 | fi 45 | case $RESOURCE_PATH in 46 | *.storyboard) 47 | 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}" 48 | 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} 49 | ;; 50 | *.xib) 51 | 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}" 52 | 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} 53 | ;; 54 | *.framework) 55 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 56 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 57 | echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 58 | rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 59 | ;; 60 | *.xcdatamodel) 61 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" 62 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 63 | ;; 64 | *.xcdatamodeld) 65 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" 66 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 67 | ;; 68 | *.xcmappingmodel) 69 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" 70 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 71 | ;; 72 | *.xcassets) 73 | ABSOLUTE_XCASSET_FILE=$(realpath "$RESOURCE_PATH") 74 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 75 | ;; 76 | *) 77 | echo "$RESOURCE_PATH" 78 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 79 | ;; 80 | esac 81 | } 82 | 83 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 84 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 85 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 86 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 87 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 88 | fi 89 | rm -f "$RESOURCES_TO_COPY" 90 | 91 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 92 | then 93 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 94 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 95 | while read line; do 96 | if [[ $line != "`realpath $PODS_ROOT`*" ]]; then 97 | XCASSET_FILES+=("$line") 98 | fi 99 | done <<<"$OTHER_XCASSETS" 100 | 101 | 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}" 102 | fi 103 | -------------------------------------------------------------------------------- /Examples/Pods/Target Support Files/Pods-JMRoundedCornerDemo/Pods-JMRoundedCornerDemo.debug.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/YYCache" "${PODS_ROOT}/Headers/Public/YYImage" "${PODS_ROOT}/Headers/Public/YYWebImage" 3 | LIBRARY_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/YYCache" "$PODS_CONFIGURATION_BUILD_DIR/YYImage" "$PODS_CONFIGURATION_BUILD_DIR/YYWebImage" 4 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/YYCache" -isystem "${PODS_ROOT}/Headers/Public/YYImage" -isystem "${PODS_ROOT}/Headers/Public/YYWebImage" 5 | OTHER_LDFLAGS = $(inherited) -ObjC -l"YYCache" -l"YYImage" -l"YYWebImage" -l"sqlite3" -l"z" -framework "Accelerate" -framework "AssetsLibrary" -framework "CoreFoundation" -framework "ImageIO" -framework "MobileCoreServices" -framework "QuartzCore" -framework "UIKit" 6 | PODS_BUILD_DIR = $BUILD_DIR 7 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | -------------------------------------------------------------------------------- /Examples/Pods/Target Support Files/Pods-JMRoundedCornerDemo/Pods-JMRoundedCornerDemo.release.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/YYCache" "${PODS_ROOT}/Headers/Public/YYImage" "${PODS_ROOT}/Headers/Public/YYWebImage" 3 | LIBRARY_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/YYCache" "$PODS_CONFIGURATION_BUILD_DIR/YYImage" "$PODS_CONFIGURATION_BUILD_DIR/YYWebImage" 4 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/YYCache" -isystem "${PODS_ROOT}/Headers/Public/YYImage" -isystem "${PODS_ROOT}/Headers/Public/YYWebImage" 5 | OTHER_LDFLAGS = $(inherited) -ObjC -l"YYCache" -l"YYImage" -l"YYWebImage" -l"sqlite3" -l"z" -framework "Accelerate" -framework "AssetsLibrary" -framework "CoreFoundation" -framework "ImageIO" -framework "MobileCoreServices" -framework "QuartzCore" -framework "UIKit" 6 | PODS_BUILD_DIR = $BUILD_DIR 7 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | -------------------------------------------------------------------------------- /Examples/Pods/Target Support Files/YYCache/YYCache-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_YYCache : NSObject 3 | @end 4 | @implementation PodsDummy_YYCache 5 | @end 6 | -------------------------------------------------------------------------------- /Examples/Pods/Target Support Files/YYCache/YYCache-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | -------------------------------------------------------------------------------- /Examples/Pods/Target Support Files/YYCache/YYCache.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/YYCache 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/YYCache" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/YYCache" "${PODS_ROOT}/Headers/Public/YYImage" "${PODS_ROOT}/Headers/Public/YYWebImage" 4 | OTHER_LDFLAGS = -l"sqlite3" -framework "CoreFoundation" -framework "QuartzCore" -framework "UIKit" 5 | PODS_BUILD_DIR = $BUILD_DIR 6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | -------------------------------------------------------------------------------- /Examples/Pods/Target Support Files/YYImage/YYImage-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_YYImage : NSObject 3 | @end 4 | @implementation PodsDummy_YYImage 5 | @end 6 | -------------------------------------------------------------------------------- /Examples/Pods/Target Support Files/YYImage/YYImage-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | -------------------------------------------------------------------------------- /Examples/Pods/Target Support Files/YYImage/YYImage.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/YYImage 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/YYImage" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/YYCache" "${PODS_ROOT}/Headers/Public/YYImage" "${PODS_ROOT}/Headers/Public/YYWebImage" 4 | OTHER_LDFLAGS = -l"z" -framework "Accelerate" -framework "AssetsLibrary" -framework "CoreFoundation" -framework "ImageIO" -framework "MobileCoreServices" -framework "QuartzCore" -framework "UIKit" 5 | PODS_BUILD_DIR = $BUILD_DIR 6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | -------------------------------------------------------------------------------- /Examples/Pods/Target Support Files/YYWebImage/YYWebImage-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_YYWebImage : NSObject 3 | @end 4 | @implementation PodsDummy_YYWebImage 5 | @end 6 | -------------------------------------------------------------------------------- /Examples/Pods/Target Support Files/YYWebImage/YYWebImage-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | -------------------------------------------------------------------------------- /Examples/Pods/Target Support Files/YYWebImage/YYWebImage.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/YYWebImage 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/YYWebImage" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/YYCache" "${PODS_ROOT}/Headers/Public/YYImage" "${PODS_ROOT}/Headers/Public/YYWebImage" 4 | LIBRARY_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/YYCache" "$PODS_CONFIGURATION_BUILD_DIR/YYImage" 5 | OTHER_LDFLAGS = -framework "Accelerate" -framework "AssetsLibrary" -framework "CoreFoundation" -framework "ImageIO" -framework "MobileCoreServices" -framework "QuartzCore" -framework "UIKit" 6 | PODS_BUILD_DIR = $BUILD_DIR 7 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | -------------------------------------------------------------------------------- /Examples/Pods/YYCache/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 ibireme 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Examples/Pods/YYCache/README.md: -------------------------------------------------------------------------------- 1 | YYCache 2 | ============== 3 | 4 | [![License MIT](https://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://raw.githubusercontent.com/ibireme/YYCache/master/LICENSE)  5 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)  6 | [![CocoaPods](http://img.shields.io/cocoapods/v/YYCache.svg?style=flat)](http://cocoapods.org/?q= YYCache)  7 | [![CocoaPods](http://img.shields.io/cocoapods/p/YYCache.svg?style=flat)](http://cocoapods.org/?q= YYCache)  8 | [![Support](https://img.shields.io/badge/support-iOS%206%2B%20-blue.svg?style=flat)](https://www.apple.com/nl/ios/)  9 | [![Build Status](https://travis-ci.org/ibireme/YYCache.svg?branch=master)](https://travis-ci.org/ibireme/YYCache) 10 | 11 | High performance cache framework for iOS.
12 | (It's a component of [YYKit](https://github.com/ibireme/YYKit)) 13 | 14 | Performance 15 | ============== 16 | 17 | ![Memory cache benchmark result](https://raw.github.com/ibireme/YYCache/master/Benchmark/Result_memory.png 18 | ) 19 | 20 | ![Disk benchmark result](https://raw.github.com/ibireme/YYCache/master/Benchmark/Result_disk.png 21 | ) 22 | 23 | You may [download](http://www.sqlite.org/download.html) and compile the latest version of sqlite and ignore the libsqlite3.dylib in iOS system to get higher performance. 24 | 25 | See `Benchmark/CacheBenchmark.xcodeproj` for more benchmark case. 26 | 27 | 28 | Features 29 | ============== 30 | - **LRU**: Objects can be evicted with least-recently-used algorithm. 31 | - **Limitation**: Cache limitation can be controlled with count, cost, age and free space. 32 | - **Compatibility**: The API is similar to `NSCache`, all methods are thread-safe. 33 | - **Memory Cache** 34 | - **Release Control**: Objects can be released synchronously/asynchronously on main thread or background thread. 35 | - **Automatically Clear**: It can be configured to automatically evict objects when receive memory warning or app enter background. 36 | - **Disk Cache** 37 | - **Customization**: It supports custom archive and unarchive method to store object which does not adopt NSCoding. 38 | - **Storage Type Control**: It can automatically decide the storage type (sqlite / file) for each object to get 39 | better performance. 40 | 41 | 42 | Installation 43 | ============== 44 | 45 | ### CocoaPods 46 | 47 | 1. Add `pod 'YYCache'` to your Podfile. 48 | 2. Run `pod install` or `pod update`. 49 | 3. Import \. 50 | 51 | 52 | ### Carthage 53 | 54 | 1. Add `github "ibireme/YYCache"` to your Cartfile. 55 | 2. Run `carthage update --platform ios` and add the framework to your project. 56 | 3. Import \. 57 | 58 | 59 | ### Manually 60 | 61 | 1. Download all the files in the YYCache subdirectory. 62 | 2. Add the source files to your Xcode project. 63 | 3. Link with required frameworks: 64 | * UIKit 65 | * CoreFoundation 66 | * QuartzCore 67 | * sqlite3 68 | 4. Import `YYCache.h`. 69 | 70 | 71 | Documentation 72 | ============== 73 | Full API documentation is available on [CocoaDocs](http://cocoadocs.org/docsets/YYCache/).
74 | You can also install documentation locally using [appledoc](https://github.com/tomaz/appledoc). 75 | 76 | 77 | Requirements 78 | ============== 79 | This library requires `iOS 6.0+` and `Xcode 7.0+`. 80 | 81 | 82 | License 83 | ============== 84 | YYCache is provided under the MIT license. See LICENSE file for details. 85 | 86 | 87 |

88 | --- 89 | 中文介绍 90 | ============== 91 | 高性能 iOS 缓存框架。
92 | (该项目是 [YYKit](https://github.com/ibireme/YYKit) 组件之一) 93 | 94 | 性能 95 | ============== 96 | 97 | iPhone 6 上,内存缓存每秒响应次数 (越高越好): 98 | ![Memory cache benchmark result](https://raw.github.com/ibireme/YYCache/master/Benchmark/Result_memory.png 99 | ) 100 | 101 | iPhone 6 上,磁盘缓存每秒响应次数 (越高越好): 102 | ![Disk benchmark result](https://raw.github.com/ibireme/YYCache/master/Benchmark/Result_disk.png 103 | ) 104 | 105 | 推荐到 SQLite 官网[下载](http://www.sqlite.org/download.html)和编译最新的 SQLite,以替换 iOS 自带的 libsqlite3.dylib,以获得最高 1.5~3 倍的性能提升。 106 | 107 | 更多测试代码和用例见 `Benchmark/CacheBenchmark.xcodeproj`。 108 | 109 | 110 | 特性 111 | ============== 112 | - **LRU**: 缓存支持 LRU (least-recently-used) 淘汰算法。 113 | - **缓存控制**: 支持多种缓存控制方法:总数量、总大小、存活时间、空闲空间。 114 | - **兼容性**: API 基本和 `NSCache` 保持一致, 所有方法都是线程安全的。 115 | - **内存缓存** 116 | - **对象释放控制**: 对象的释放(release) 可以配置为同步或异步进行,可以配置在主线程或后台线程进行。 117 | - **自动清空**: 当收到内存警告或 App 进入后台时,缓存可以配置为自动清空。 118 | - **磁盘缓存** 119 | - **可定制性**: 磁盘缓存支持自定义的归档解档方法,以支持那些没有实现 NSCoding 协议的对象。 120 | - **存储类型控制**: 磁盘缓存支持对每个对象的存储类型 (SQLite/文件) 进行自动或手动控制,以获得更高的存取性能。 121 | 122 | 123 | 安装 124 | ============== 125 | 126 | ### CocoaPods 127 | 128 | 1. 在 Podfile 中添加 `pod 'YYCache'`。 129 | 2. 执行 `pod install` 或 `pod update`。 130 | 3. 导入 \。 131 | 132 | 133 | ### Carthage 134 | 135 | 1. 在 Cartfile 中添加 `github "ibireme/YYCache"`。 136 | 2. 执行 `carthage update --platform ios` 并将生成的 framework 添加到你的工程。 137 | 3. 导入 \。 138 | 139 | 140 | ### 手动安装 141 | 142 | 1. 下载 YYCache 文件夹内的所有内容。 143 | 2. 将 YYCache 内的源文件添加(拖放)到你的工程。 144 | 3. 链接以下的 frameworks: 145 | * UIKit 146 | * CoreFoundation 147 | * QuartzCore 148 | * sqlite3 149 | 4. 导入 `YYCache.h`。 150 | 151 | 152 | 文档 153 | ============== 154 | 你可以在 [CocoaDocs](http://cocoadocs.org/docsets/YYCache/) 查看在线 API 文档,也可以用 [appledoc](https://github.com/tomaz/appledoc) 本地生成文档。 155 | 156 | 157 | 系统要求 158 | ============== 159 | 该项目最低支持 `iOS 6.0` 和 `Xcode 7.0`。 160 | 161 | 162 | 许可证 163 | ============== 164 | YYCache 使用 MIT 许可证,详情见 LICENSE 文件。 165 | 166 | 167 | 相关链接 168 | ============== 169 | [YYCache 设计思路与技术细节](http://blog.ibireme.com/2015/10/26/yycache/) 170 | 171 | 172 | -------------------------------------------------------------------------------- /Examples/Pods/YYCache/YYCache/YYCache.h: -------------------------------------------------------------------------------- 1 | // 2 | // YYCache.h 3 | // YYCache 4 | // 5 | // Created by ibireme on 15/2/13. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | #if __has_include() 15 | FOUNDATION_EXPORT double YYCacheVersionNumber; 16 | FOUNDATION_EXPORT const unsigned char YYCacheVersionString[]; 17 | #import 18 | #import 19 | #import 20 | #elif __has_include() 21 | #import 22 | #import 23 | #import 24 | #else 25 | #import "YYMemoryCache.h" 26 | #import "YYDiskCache.h" 27 | #import "YYKVStorage.h" 28 | #endif 29 | 30 | NS_ASSUME_NONNULL_BEGIN 31 | 32 | 33 | /** 34 | `YYCache` is a thread safe key-value cache. 35 | 36 | It use `YYMemoryCache` to store objects in a small and fast memory cache, 37 | and use `YYDiskCache` to persisting objects to a large and slow disk cache. 38 | See `YYMemoryCache` and `YYDiskCache` for more information. 39 | */ 40 | @interface YYCache : NSObject 41 | 42 | /** The name of the cache, readonly. */ 43 | @property (copy, readonly) NSString *name; 44 | 45 | /** The underlying memory cache. see `YYMemoryCache` for more information.*/ 46 | @property (strong, readonly) YYMemoryCache *memoryCache; 47 | 48 | /** The underlying disk cache. see `YYDiskCache` for more information.*/ 49 | @property (strong, readonly) YYDiskCache *diskCache; 50 | 51 | /** 52 | Create a new instance with the specified name. 53 | Multiple instances with the same name will make the cache unstable. 54 | 55 | @param name The name of the cache. It will create a dictionary with the name in 56 | the app's caches dictionary for disk cache. Once initialized you should not 57 | read and write to this directory. 58 | @result A new cache object, or nil if an error occurs. 59 | */ 60 | - (nullable instancetype)initWithName:(NSString *)name; 61 | 62 | /** 63 | Create a new instance with the specified path. 64 | Multiple instances with the same name will make the cache unstable. 65 | 66 | @param path Full path of a directory in which the cache will write data. 67 | Once initialized you should not read and write to this directory. 68 | @result A new cache object, or nil if an error occurs. 69 | */ 70 | - (nullable instancetype)initWithPath:(NSString *)path NS_DESIGNATED_INITIALIZER; 71 | 72 | /** 73 | Convenience Initializers 74 | Create a new instance with the specified name. 75 | Multiple instances with the same name will make the cache unstable. 76 | 77 | @param name The name of the cache. It will create a dictionary with the name in 78 | the app's caches dictionary for disk cache. Once initialized you should not 79 | read and write to this directory. 80 | @result A new cache object, or nil if an error occurs. 81 | */ 82 | + (nullable instancetype)cacheWithName:(NSString *)name; 83 | 84 | /** 85 | Convenience Initializers 86 | Create a new instance with the specified path. 87 | Multiple instances with the same name will make the cache unstable. 88 | 89 | @param path Full path of a directory in which the cache will write data. 90 | Once initialized you should not read and write to this directory. 91 | @result A new cache object, or nil if an error occurs. 92 | */ 93 | + (nullable instancetype)cacheWithPath:(NSString *)path; 94 | 95 | - (instancetype)init UNAVAILABLE_ATTRIBUTE; 96 | + (instancetype)new UNAVAILABLE_ATTRIBUTE; 97 | 98 | #pragma mark - Access Methods 99 | ///============================================================================= 100 | /// @name Access Methods 101 | ///============================================================================= 102 | 103 | /** 104 | Returns a boolean value that indicates whether a given key is in cache. 105 | This method may blocks the calling thread until file read finished. 106 | 107 | @param key A string identifying the value. If nil, just return NO. 108 | @return Whether the key is in cache. 109 | */ 110 | - (BOOL)containsObjectForKey:(NSString *)key; 111 | 112 | /** 113 | Returns a boolean value with the block that indicates whether a given key is in cache. 114 | This method returns immediately and invoke the passed block in background queue 115 | when the operation finished. 116 | 117 | @param key A string identifying the value. If nil, just return NO. 118 | @param block A block which will be invoked in background queue when finished. 119 | */ 120 | - (void)containsObjectForKey:(NSString *)key withBlock:(nullable void(^)(NSString *key, BOOL contains))block; 121 | 122 | /** 123 | Returns the value associated with a given key. 124 | This method may blocks the calling thread until file read finished. 125 | 126 | @param key A string identifying the value. If nil, just return nil. 127 | @return The value associated with key, or nil if no value is associated with key. 128 | */ 129 | - (nullable id)objectForKey:(NSString *)key; 130 | 131 | /** 132 | Returns the value associated with a given key. 133 | This method returns immediately and invoke the passed block in background queue 134 | when the operation finished. 135 | 136 | @param key A string identifying the value. If nil, just return nil. 137 | @param block A block which will be invoked in background queue when finished. 138 | */ 139 | - (void)objectForKey:(NSString *)key withBlock:(nullable void(^)(NSString *key, id object))block; 140 | 141 | /** 142 | Sets the value of the specified key in the cache. 143 | This method may blocks the calling thread until file write finished. 144 | 145 | @param object The object to be stored in the cache. If nil, it calls `removeObjectForKey:`. 146 | @param key The key with which to associate the value. If nil, this method has no effect. 147 | */ 148 | - (void)setObject:(nullable id)object forKey:(NSString *)key; 149 | 150 | /** 151 | Sets the value of the specified key in the cache. 152 | This method returns immediately and invoke the passed block in background queue 153 | when the operation finished. 154 | 155 | @param object The object to be stored in the cache. If nil, it calls `removeObjectForKey:`. 156 | @param block A block which will be invoked in background queue when finished. 157 | */ 158 | - (void)setObject:(nullable id)object forKey:(NSString *)key withBlock:(nullable void(^)(void))block; 159 | 160 | /** 161 | Removes the value of the specified key in the cache. 162 | This method may blocks the calling thread until file delete finished. 163 | 164 | @param key The key identifying the value to be removed. If nil, this method has no effect. 165 | */ 166 | - (void)removeObjectForKey:(NSString *)key; 167 | 168 | /** 169 | Removes the value of the specified key in the cache. 170 | This method returns immediately and invoke the passed block in background queue 171 | when the operation finished. 172 | 173 | @param key The key identifying the value to be removed. If nil, this method has no effect. 174 | @param block A block which will be invoked in background queue when finished. 175 | */ 176 | - (void)removeObjectForKey:(NSString *)key withBlock:(nullable void(^)(NSString *key))block; 177 | 178 | /** 179 | Empties the cache. 180 | This method may blocks the calling thread until file delete finished. 181 | */ 182 | - (void)removeAllObjects; 183 | 184 | /** 185 | Empties the cache. 186 | This method returns immediately and invoke the passed block in background queue 187 | when the operation finished. 188 | 189 | @param block A block which will be invoked in background queue when finished. 190 | */ 191 | - (void)removeAllObjectsWithBlock:(void(^)(void))block; 192 | 193 | /** 194 | Empties the cache with block. 195 | This method returns immediately and executes the clear operation with block in background. 196 | 197 | @warning You should not send message to this instance in these blocks. 198 | @param progress This block will be invoked during removing, pass nil to ignore. 199 | @param end This block will be invoked at the end, pass nil to ignore. 200 | */ 201 | - (void)removeAllObjectsWithProgressBlock:(nullable void(^)(int removedCount, int totalCount))progress 202 | endBlock:(nullable void(^)(BOOL error))end; 203 | 204 | @end 205 | 206 | NS_ASSUME_NONNULL_END 207 | -------------------------------------------------------------------------------- /Examples/Pods/YYCache/YYCache/YYCache.m: -------------------------------------------------------------------------------- 1 | // 2 | // YYCache.m 3 | // YYCache 4 | // 5 | // Created by ibireme on 15/2/13. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import "YYCache.h" 13 | #import "YYMemoryCache.h" 14 | #import "YYDiskCache.h" 15 | 16 | @implementation YYCache 17 | 18 | - (instancetype) init { 19 | NSLog(@"Use \"initWithName\" or \"initWithPath\" to create YYCache instance."); 20 | return [self initWithPath:@""]; 21 | } 22 | 23 | - (instancetype)initWithName:(NSString *)name { 24 | if (name.length == 0) return nil; 25 | NSString *cacheFolder = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject]; 26 | NSString *path = [cacheFolder stringByAppendingPathComponent:name]; 27 | return [self initWithPath:path]; 28 | } 29 | 30 | - (instancetype)initWithPath:(NSString *)path { 31 | if (path.length == 0) return nil; 32 | YYDiskCache *diskCache = [[YYDiskCache alloc] initWithPath:path]; 33 | if (!diskCache) return nil; 34 | NSString *name = [path lastPathComponent]; 35 | YYMemoryCache *memoryCache = [YYMemoryCache new]; 36 | memoryCache.name = name; 37 | 38 | self = [super init]; 39 | _name = name; 40 | _diskCache = diskCache; 41 | _memoryCache = memoryCache; 42 | return self; 43 | } 44 | 45 | + (instancetype)cacheWithName:(NSString *)name { 46 | return [[self alloc] initWithName:name]; 47 | } 48 | 49 | + (instancetype)cacheWithPath:(NSString *)path { 50 | return [[self alloc] initWithPath:path]; 51 | } 52 | 53 | - (BOOL)containsObjectForKey:(NSString *)key { 54 | return [_memoryCache containsObjectForKey:key] || [_diskCache containsObjectForKey:key]; 55 | } 56 | 57 | - (void)containsObjectForKey:(NSString *)key withBlock:(void (^)(NSString *key, BOOL contains))block { 58 | if (!block) return; 59 | 60 | if ([_memoryCache containsObjectForKey:key]) { 61 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 62 | block(key, YES); 63 | }); 64 | } else { 65 | [_diskCache containsObjectForKey:key withBlock:block]; 66 | } 67 | } 68 | 69 | - (id)objectForKey:(NSString *)key { 70 | id object = [_memoryCache objectForKey:key]; 71 | if (!object) { 72 | object = [_diskCache objectForKey:key]; 73 | if (object) { 74 | [_memoryCache setObject:object forKey:key]; 75 | } 76 | } 77 | return object; 78 | } 79 | 80 | - (void)objectForKey:(NSString *)key withBlock:(void (^)(NSString *key, id object))block { 81 | if (!block) return; 82 | id object = [_memoryCache objectForKey:key]; 83 | if (object) { 84 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 85 | block(key, object); 86 | }); 87 | } else { 88 | [_diskCache objectForKey:key withBlock:^(NSString *key, id object) { 89 | if (object && ![_memoryCache objectForKey:key]) { 90 | [_memoryCache setObject:object forKey:key]; 91 | } 92 | block(key, object); 93 | }]; 94 | } 95 | } 96 | 97 | - (void)setObject:(id)object forKey:(NSString *)key { 98 | [_memoryCache setObject:object forKey:key]; 99 | [_diskCache setObject:object forKey:key]; 100 | } 101 | 102 | - (void)setObject:(id)object forKey:(NSString *)key withBlock:(void (^)(void))block { 103 | [_memoryCache setObject:object forKey:key]; 104 | [_diskCache setObject:object forKey:key withBlock:block]; 105 | } 106 | 107 | - (void)removeObjectForKey:(NSString *)key { 108 | [_memoryCache removeObjectForKey:key]; 109 | [_diskCache removeObjectForKey:key]; 110 | } 111 | 112 | - (void)removeObjectForKey:(NSString *)key withBlock:(void (^)(NSString *key))block { 113 | [_memoryCache removeObjectForKey:key]; 114 | [_diskCache removeObjectForKey:key withBlock:block]; 115 | } 116 | 117 | - (void)removeAllObjects { 118 | [_memoryCache removeAllObjects]; 119 | [_diskCache removeAllObjects]; 120 | } 121 | 122 | - (void)removeAllObjectsWithBlock:(void(^)(void))block { 123 | [_memoryCache removeAllObjects]; 124 | [_diskCache removeAllObjectsWithBlock:block]; 125 | } 126 | 127 | - (void)removeAllObjectsWithProgressBlock:(void(^)(int removedCount, int totalCount))progress 128 | endBlock:(void(^)(BOOL error))end { 129 | [_memoryCache removeAllObjects]; 130 | [_diskCache removeAllObjectsWithProgressBlock:progress endBlock:end]; 131 | 132 | } 133 | 134 | - (NSString *)description { 135 | if (_name) return [NSString stringWithFormat:@"<%@: %p> (%@)", self.class, self, _name]; 136 | else return [NSString stringWithFormat:@"<%@: %p>", self.class, self]; 137 | } 138 | 139 | @end 140 | -------------------------------------------------------------------------------- /Examples/Pods/YYCache/YYCache/YYMemoryCache.h: -------------------------------------------------------------------------------- 1 | // 2 | // YYMemoryCache.h 3 | // YYCache 4 | // 5 | // Created by ibireme on 15/2/7. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | /** 17 | YYMemoryCache is a fast in-memory cache that stores key-value pairs. 18 | In contrast to NSDictionary, keys are retained and not copied. 19 | The API and performance is similar to `NSCache`, all methods are thread-safe. 20 | 21 | YYMemoryCache objects differ from NSCache in a few ways: 22 | 23 | * It uses LRU (least-recently-used) to remove objects; NSCache's eviction method 24 | is non-deterministic. 25 | * It can be controlled by cost, count and age; NSCache's limits are imprecise. 26 | * It can be configured to automatically evict objects when receive memory 27 | warning or app enter background. 28 | 29 | The time of `Access Methods` in YYMemoryCache is typically in constant time (O(1)). 30 | */ 31 | @interface YYMemoryCache : NSObject 32 | 33 | #pragma mark - Attribute 34 | ///============================================================================= 35 | /// @name Attribute 36 | ///============================================================================= 37 | 38 | /** The name of the cache. Default is nil. */ 39 | @property (nullable, copy) NSString *name; 40 | 41 | /** The number of objects in the cache (read-only) */ 42 | @property (readonly) NSUInteger totalCount; 43 | 44 | /** The total cost of objects in the cache (read-only). */ 45 | @property (readonly) NSUInteger totalCost; 46 | 47 | 48 | #pragma mark - Limit 49 | ///============================================================================= 50 | /// @name Limit 51 | ///============================================================================= 52 | 53 | /** 54 | The maximum number of objects the cache should hold. 55 | 56 | @discussion The default value is NSUIntegerMax, which means no limit. 57 | This is not a strict limit—if the cache goes over the limit, some objects in the 58 | cache could be evicted later in backgound thread. 59 | */ 60 | @property NSUInteger countLimit; 61 | 62 | /** 63 | The maximum total cost that the cache can hold before it starts evicting objects. 64 | 65 | @discussion The default value is NSUIntegerMax, which means no limit. 66 | This is not a strict limit—if the cache goes over the limit, some objects in the 67 | cache could be evicted later in backgound thread. 68 | */ 69 | @property NSUInteger costLimit; 70 | 71 | /** 72 | The maximum expiry time of objects in cache. 73 | 74 | @discussion The default value is DBL_MAX, which means no limit. 75 | This is not a strict limit—if an object goes over the limit, the object could 76 | be evicted later in backgound thread. 77 | */ 78 | @property NSTimeInterval ageLimit; 79 | 80 | /** 81 | The auto trim check time interval in seconds. Default is 5.0. 82 | 83 | @discussion The cache holds an internal timer to check whether the cache reaches 84 | its limits, and if the limit is reached, it begins to evict objects. 85 | */ 86 | @property NSTimeInterval autoTrimInterval; 87 | 88 | /** 89 | If `YES`, the cache will remove all objects when the app receives a memory warning. 90 | The default value is `YES`. 91 | */ 92 | @property BOOL shouldRemoveAllObjectsOnMemoryWarning; 93 | 94 | /** 95 | If `YES`, The cache will remove all objects when the app enter background. 96 | The default value is `YES`. 97 | */ 98 | @property BOOL shouldRemoveAllObjectsWhenEnteringBackground; 99 | 100 | /** 101 | A block to be executed when the app receives a memory warning. 102 | The default value is nil. 103 | */ 104 | @property (nullable, copy) void(^didReceiveMemoryWarningBlock)(YYMemoryCache *cache); 105 | 106 | /** 107 | A block to be executed when the app enter background. 108 | The default value is nil. 109 | */ 110 | @property (nullable, copy) void(^didEnterBackgroundBlock)(YYMemoryCache *cache); 111 | 112 | /** 113 | If `YES`, the key-value pair will be released on main thread, otherwise on 114 | background thread. Default is NO. 115 | 116 | @discussion You may set this value to `YES` if the key-value object contains 117 | the instance which should be released in main thread (such as UIView/CALayer). 118 | */ 119 | @property BOOL releaseOnMainThread; 120 | 121 | /** 122 | If `YES`, the key-value pair will be released asynchronously to avoid blocking 123 | the access methods, otherwise it will be released in the access method 124 | (such as removeObjectForKey:). Default is YES. 125 | */ 126 | @property BOOL releaseAsynchronously; 127 | 128 | 129 | #pragma mark - Access Methods 130 | ///============================================================================= 131 | /// @name Access Methods 132 | ///============================================================================= 133 | 134 | /** 135 | Returns a Boolean value that indicates whether a given key is in cache. 136 | 137 | @param key An object identifying the value. If nil, just return `NO`. 138 | @return Whether the key is in cache. 139 | */ 140 | - (BOOL)containsObjectForKey:(id)key; 141 | 142 | /** 143 | Returns the value associated with a given key. 144 | 145 | @param key An object identifying the value. If nil, just return nil. 146 | @return The value associated with key, or nil if no value is associated with key. 147 | */ 148 | - (nullable id)objectForKey:(id)key; 149 | 150 | /** 151 | Sets the value of the specified key in the cache (0 cost). 152 | 153 | @param object The object to be stored in the cache. If nil, it calls `removeObjectForKey:`. 154 | @param key The key with which to associate the value. If nil, this method has no effect. 155 | @discussion Unlike an NSMutableDictionary object, a cache does not copy the key 156 | objects that are put into it. 157 | */ 158 | - (void)setObject:(nullable id)object forKey:(id)key; 159 | 160 | /** 161 | Sets the value of the specified key in the cache, and associates the key-value 162 | pair with the specified cost. 163 | 164 | @param object The object to store in the cache. If nil, it calls `removeObjectForKey`. 165 | @param key The key with which to associate the value. If nil, this method has no effect. 166 | @param cost The cost with which to associate the key-value pair. 167 | @discussion Unlike an NSMutableDictionary object, a cache does not copy the key 168 | objects that are put into it. 169 | */ 170 | - (void)setObject:(nullable id)object forKey:(id)key withCost:(NSUInteger)cost; 171 | 172 | /** 173 | Removes the value of the specified key in the cache. 174 | 175 | @param key The key identifying the value to be removed. If nil, this method has no effect. 176 | */ 177 | - (void)removeObjectForKey:(id)key; 178 | 179 | /** 180 | Empties the cache immediately. 181 | */ 182 | - (void)removeAllObjects; 183 | 184 | 185 | #pragma mark - Trim 186 | ///============================================================================= 187 | /// @name Trim 188 | ///============================================================================= 189 | 190 | /** 191 | Removes objects from the cache with LRU, until the `totalCount` is below or equal to 192 | the specified value. 193 | @param count The total count allowed to remain after the cache has been trimmed. 194 | */ 195 | - (void)trimToCount:(NSUInteger)count; 196 | 197 | /** 198 | Removes objects from the cache with LRU, until the `totalCost` is or equal to 199 | the specified value. 200 | @param cost The total cost allowed to remain after the cache has been trimmed. 201 | */ 202 | - (void)trimToCost:(NSUInteger)cost; 203 | 204 | /** 205 | Removes objects from the cache with LRU, until all expiry objects removed by the 206 | specified value. 207 | @param age The maximum age (in seconds) of objects. 208 | */ 209 | - (void)trimToAge:(NSTimeInterval)age; 210 | 211 | @end 212 | 213 | NS_ASSUME_NONNULL_END 214 | -------------------------------------------------------------------------------- /Examples/Pods/YYImage/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 ibireme 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Examples/Pods/YYImage/YYImage/YYAnimatedImageView.h: -------------------------------------------------------------------------------- 1 | // 2 | // YYAnimatedImageView.h 3 | // YYImage 4 | // 5 | // Created by ibireme on 14/10/19. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | /** 17 | An image view for displaying animated image. 18 | 19 | @discussion It is a fully compatible `UIImageView` subclass. 20 | If the `image` or `highlightedImage` property adopt to the `YYAnimatedImage` protocol, 21 | then it can be used to play the multi-frame animation. The animation can also be 22 | controlled with the UIImageView methods `-startAnimating`, `-stopAnimating` and `-isAnimating`. 23 | 24 | This view request the frame data just in time. When the device has enough free memory, 25 | this view may cache some or all future frames in an inner buffer for lower CPU cost. 26 | Buffer size is dynamically adjusted based on the current state of the device memory. 27 | 28 | Sample Code: 29 | 30 | // ani@3x.gif 31 | YYImage *image = [YYImage imageNamed:@"ani"]; 32 | YYAnimatedImageView *imageView = [YYAnimatedImageView alloc] initWithImage:image]; 33 | [view addSubView:imageView]; 34 | */ 35 | @interface YYAnimatedImageView : UIImageView 36 | 37 | /** 38 | If the image has more than one frame, set this value to `YES` will automatically 39 | play/stop the animation when the view become visible/invisible. 40 | 41 | The default value is `YES`. 42 | */ 43 | @property (nonatomic) BOOL autoPlayAnimatedImage; 44 | 45 | /** 46 | Index of the currently displayed frame (index from 0). 47 | 48 | Set a new value to this property will cause to display the new frame immediately. 49 | If the new value is invalid, this method has no effect. 50 | 51 | You can add an observer to this property to observe the playing status. 52 | */ 53 | @property (nonatomic) NSUInteger currentAnimatedImageIndex; 54 | 55 | /** 56 | Whether the image view is playing animation currently. 57 | 58 | You can add an observer to this property to observe the playing status. 59 | */ 60 | @property (nonatomic, readonly) BOOL currentIsPlayingAnimation; 61 | 62 | /** 63 | The animation timer's runloop mode, default is `NSRunLoopCommonModes`. 64 | 65 | Set this property to `NSDefaultRunLoopMode` will make the animation pause during 66 | UIScrollView scrolling. 67 | */ 68 | @property (nonatomic, copy) NSString *runloopMode; 69 | 70 | /** 71 | The max size (in bytes) for inner frame buffer size, default is 0 (dynamically). 72 | 73 | When the device has enough free memory, this view will request and decode some or 74 | all future frame image into an inner buffer. If this property's value is 0, then 75 | the max buffer size will be dynamically adjusted based on the current state of 76 | the device free memory. Otherwise, the buffer size will be limited by this value. 77 | 78 | When receive memory warning or app enter background, the buffer will be released 79 | immediately, and may grow back at the right time. 80 | */ 81 | @property (nonatomic) NSUInteger maxBufferSize; 82 | 83 | @end 84 | 85 | 86 | 87 | /** 88 | The YYAnimatedImage protocol declares the required methods for animated image 89 | display with YYAnimatedImageView. 90 | 91 | Subclass a UIImage and implement this protocol, so that instances of that class 92 | can be set to YYAnimatedImageView.image or YYAnimatedImageView.highlightedImage 93 | to display animation. 94 | 95 | See `YYImage` and `YYFrameImage` for example. 96 | */ 97 | @protocol YYAnimatedImage 98 | @required 99 | /// Total animated frame count. 100 | /// It the frame count is less than 1, then the methods below will be ignored. 101 | - (NSUInteger)animatedImageFrameCount; 102 | 103 | /// Animation loop count, 0 means infinite looping. 104 | - (NSUInteger)animatedImageLoopCount; 105 | 106 | /// Bytes per frame (in memory). It may used to optimize memory buffer size. 107 | - (NSUInteger)animatedImageBytesPerFrame; 108 | 109 | /// Returns the frame image from a specified index. 110 | /// This method may be called on background thread. 111 | /// @param index Frame index (zero based). 112 | - (nullable UIImage *)animatedImageFrameAtIndex:(NSUInteger)index; 113 | 114 | /// Returns the frames's duration from a specified index. 115 | /// @param index Frame index (zero based). 116 | - (NSTimeInterval)animatedImageDurationAtIndex:(NSUInteger)index; 117 | 118 | @optional 119 | /// A rectangle in image coordinates defining the subrectangle of the image that 120 | /// will be displayed. The rectangle should not outside the image's bounds. 121 | /// It may used to display sprite animation with a single image (sprite sheet). 122 | - (CGRect)animatedImageContentsRectAtIndex:(NSUInteger)index; 123 | @end 124 | 125 | NS_ASSUME_NONNULL_END 126 | -------------------------------------------------------------------------------- /Examples/Pods/YYImage/YYImage/YYFrameImage.h: -------------------------------------------------------------------------------- 1 | // 2 | // YYFrameImage.h 3 | // YYImage 4 | // 5 | // Created by ibireme on 14/12/9. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | #if __has_include() 15 | #import 16 | #elif __has_include() 17 | #import 18 | #else 19 | #import "YYAnimatedImageView.h" 20 | #endif 21 | 22 | NS_ASSUME_NONNULL_BEGIN 23 | 24 | /** 25 | An image to display frame-based animation. 26 | 27 | @discussion It is a fully compatible `UIImage` subclass. 28 | It only support system image format such as png and jpeg. 29 | The animation can be played by YYAnimatedImageView. 30 | 31 | Sample Code: 32 | 33 | NSArray *paths = @[@"/ani/frame1.png", @"/ani/frame2.png", @"/ani/frame3.png"]; 34 | NSArray *times = @[@0.1, @0.2, @0.1]; 35 | YYFrameImage *image = [YYFrameImage alloc] initWithImagePaths:paths frameDurations:times repeats:YES]; 36 | YYAnimatedImageView *imageView = [YYAnimatedImageView alloc] initWithImage:image]; 37 | [view addSubView:imageView]; 38 | */ 39 | @interface YYFrameImage : UIImage 40 | 41 | /** 42 | Create a frame animated image from files. 43 | 44 | @param paths An array of NSString objects, contains the full or 45 | partial path to each image file. 46 | e.g. @[@"/ani/1.png",@"/ani/2.png",@"/ani/3.png"] 47 | 48 | @param oneFrameDuration The duration (in seconds) per frame. 49 | 50 | @param loopCount The animation loop count, 0 means infinite. 51 | 52 | @return An initialized YYFrameImage object, or nil when an error occurs. 53 | */ 54 | - (nullable instancetype)initWithImagePaths:(NSArray *)paths 55 | oneFrameDuration:(NSTimeInterval)oneFrameDuration 56 | loopCount:(NSUInteger)loopCount; 57 | 58 | /** 59 | Create a frame animated image from files. 60 | 61 | @param paths An array of NSString objects, contains the full or 62 | partial path to each image file. 63 | e.g. @[@"/ani/frame1.png",@"/ani/frame2.png",@"/ani/frame3.png"] 64 | 65 | @param frameDurations An array of NSNumber objects, contains the duration (in seconds) per frame. 66 | e.g. @[@0.1, @0.2, @0.3]; 67 | 68 | @param loopCount The animation loop count, 0 means infinite. 69 | 70 | @return An initialized YYFrameImage object, or nil when an error occurs. 71 | */ 72 | - (nullable instancetype)initWithImagePaths:(NSArray *)paths 73 | frameDurations:(NSArray *)frameDurations 74 | loopCount:(NSUInteger)loopCount; 75 | 76 | /** 77 | Create a frame animated image from an array of data. 78 | 79 | @param dataArray An array of NSData objects. 80 | 81 | @param oneFrameDuration The duration (in seconds) per frame. 82 | 83 | @param loopCount The animation loop count, 0 means infinite. 84 | 85 | @return An initialized YYFrameImage object, or nil when an error occurs. 86 | */ 87 | - (nullable instancetype)initWithImageDataArray:(NSArray *)dataArray 88 | oneFrameDuration:(NSTimeInterval)oneFrameDuration 89 | loopCount:(NSUInteger)loopCount; 90 | 91 | /** 92 | Create a frame animated image from an array of data. 93 | 94 | @param dataArray An array of NSData objects. 95 | 96 | @param frameDurations An array of NSNumber objects, contains the duration (in seconds) per frame. 97 | e.g. @[@0.1, @0.2, @0.3]; 98 | 99 | @param loopCount The animation loop count, 0 means infinite. 100 | 101 | @return An initialized YYFrameImage object, or nil when an error occurs. 102 | */ 103 | - (nullable instancetype)initWithImageDataArray:(NSArray *)dataArray 104 | frameDurations:(NSArray *)frameDurations 105 | loopCount:(NSUInteger)loopCount; 106 | 107 | @end 108 | 109 | NS_ASSUME_NONNULL_END 110 | -------------------------------------------------------------------------------- /Examples/Pods/YYImage/YYImage/YYFrameImage.m: -------------------------------------------------------------------------------- 1 | // 2 | // YYFrameImage.m 3 | // YYImage 4 | // 5 | // Created by ibireme on 14/12/9. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import "YYFrameImage.h" 13 | #import "YYImageCoder.h" 14 | 15 | 16 | /** 17 | Return the path scale. 18 | 19 | e.g. 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
Path Scale
"icon.png" 1
"icon@2x.png" 2
"icon@2.5x.png" 2.5
"icon@2x" 1
"icon@2x..png" 1
"icon@2x.png/" 1
29 | */ 30 | static CGFloat _NSStringPathScale(NSString *string) { 31 | if (string.length == 0 || [string hasSuffix:@"/"]) return 1; 32 | NSString *name = string.stringByDeletingPathExtension; 33 | __block CGFloat scale = 1; 34 | 35 | NSRegularExpression *pattern = [NSRegularExpression regularExpressionWithPattern:@"@[0-9]+\\.?[0-9]*x$" options:NSRegularExpressionAnchorsMatchLines error:nil]; 36 | [pattern enumerateMatchesInString:name options:kNilOptions range:NSMakeRange(0, name.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) { 37 | if (result.range.location >= 3) { 38 | scale = [string substringWithRange:NSMakeRange(result.range.location + 1, result.range.length - 2)].doubleValue; 39 | } 40 | }]; 41 | 42 | return scale; 43 | } 44 | 45 | 46 | 47 | @implementation YYFrameImage { 48 | NSUInteger _loopCount; 49 | NSUInteger _oneFrameBytes; 50 | NSArray *_imagePaths; 51 | NSArray *_imageDatas; 52 | NSArray *_frameDurations; 53 | } 54 | 55 | - (instancetype)initWithImagePaths:(NSArray *)paths oneFrameDuration:(NSTimeInterval)oneFrameDuration loopCount:(NSUInteger)loopCount { 56 | NSMutableArray *durations = [NSMutableArray new]; 57 | for (int i = 0, max = (int)paths.count; i < max; i++) { 58 | [durations addObject:@(oneFrameDuration)]; 59 | } 60 | return [self initWithImagePaths:paths frameDurations:durations loopCount:loopCount]; 61 | } 62 | 63 | - (instancetype)initWithImagePaths:(NSArray *)paths frameDurations:(NSArray *)frameDurations loopCount:(NSUInteger)loopCount { 64 | if (paths.count == 0) return nil; 65 | if (paths.count != frameDurations.count) return nil; 66 | 67 | NSString *firstPath = paths[0]; 68 | NSData *firstData = [NSData dataWithContentsOfFile:firstPath]; 69 | CGFloat scale = _NSStringPathScale(firstPath); 70 | UIImage *firstCG = [[[UIImage alloc] initWithData:firstData] yy_imageByDecoded]; 71 | self = [self initWithCGImage:firstCG.CGImage scale:scale orientation:UIImageOrientationUp]; 72 | if (!self) return nil; 73 | long frameByte = CGImageGetBytesPerRow(firstCG.CGImage) * CGImageGetHeight(firstCG.CGImage); 74 | _oneFrameBytes = (NSUInteger)frameByte; 75 | _imagePaths = paths.copy; 76 | _frameDurations = frameDurations.copy; 77 | _loopCount = loopCount; 78 | 79 | return self; 80 | } 81 | 82 | - (instancetype)initWithImageDataArray:(NSArray *)dataArray oneFrameDuration:(NSTimeInterval)oneFrameDuration loopCount:(NSUInteger)loopCount { 83 | NSMutableArray *durations = [NSMutableArray new]; 84 | for (int i = 0, max = (int)dataArray.count; i < max; i++) { 85 | [durations addObject:@(oneFrameDuration)]; 86 | } 87 | return [self initWithImageDataArray:dataArray frameDurations:durations loopCount:loopCount]; 88 | } 89 | 90 | - (instancetype)initWithImageDataArray:(NSArray *)dataArray frameDurations:(NSArray *)frameDurations loopCount:(NSUInteger)loopCount { 91 | if (dataArray.count == 0) return nil; 92 | if (dataArray.count != frameDurations.count) return nil; 93 | 94 | NSData *firstData = dataArray[0]; 95 | CGFloat scale = [UIScreen mainScreen].scale; 96 | UIImage *firstCG = [[[UIImage alloc] initWithData:firstData] yy_imageByDecoded]; 97 | self = [self initWithCGImage:firstCG.CGImage scale:scale orientation:UIImageOrientationUp]; 98 | if (!self) return nil; 99 | long frameByte = CGImageGetBytesPerRow(firstCG.CGImage) * CGImageGetHeight(firstCG.CGImage); 100 | _oneFrameBytes = (NSUInteger)frameByte; 101 | _imageDatas = dataArray.copy; 102 | _frameDurations = frameDurations.copy; 103 | _loopCount = loopCount; 104 | 105 | return self; 106 | } 107 | 108 | #pragma mark - YYAnimtedImage 109 | 110 | - (NSUInteger)animatedImageFrameCount { 111 | if (_imagePaths) { 112 | return _imagePaths.count; 113 | } else if (_imageDatas) { 114 | return _imageDatas.count; 115 | } else { 116 | return 1; 117 | } 118 | } 119 | 120 | - (NSUInteger)animatedImageLoopCount { 121 | return _loopCount; 122 | } 123 | 124 | - (NSUInteger)animatedImageBytesPerFrame { 125 | return _oneFrameBytes; 126 | } 127 | 128 | - (UIImage *)animatedImageFrameAtIndex:(NSUInteger)index { 129 | if (_imagePaths) { 130 | if (index >= _imagePaths.count) return nil; 131 | NSString *path = _imagePaths[index]; 132 | CGFloat scale = _NSStringPathScale(path); 133 | NSData *data = [NSData dataWithContentsOfFile:path]; 134 | return [[UIImage imageWithData:data scale:scale] yy_imageByDecoded]; 135 | } else if (_imageDatas) { 136 | if (index >= _imageDatas.count) return nil; 137 | NSData *data = _imageDatas[index]; 138 | return [[UIImage imageWithData:data scale:[UIScreen mainScreen].scale] yy_imageByDecoded]; 139 | } else { 140 | return index == 0 ? self : nil; 141 | } 142 | } 143 | 144 | - (NSTimeInterval)animatedImageDurationAtIndex:(NSUInteger)index { 145 | if (index >= _frameDurations.count) return 0; 146 | NSNumber *num = _frameDurations[index]; 147 | return [num doubleValue]; 148 | } 149 | 150 | @end 151 | -------------------------------------------------------------------------------- /Examples/Pods/YYImage/YYImage/YYImage.h: -------------------------------------------------------------------------------- 1 | // 2 | // YYImage.h 3 | // YYImage 4 | // 5 | // Created by ibireme on 14/10/20. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | #if __has_include() 15 | FOUNDATION_EXPORT double YYImageVersionNumber; 16 | FOUNDATION_EXPORT const unsigned char YYImageVersionString[]; 17 | #import 18 | #import 19 | #import 20 | #import 21 | #elif __has_include() 22 | #import 23 | #import 24 | #import 25 | #import 26 | #else 27 | #import "YYFrameImage.h" 28 | #import "YYSpriteSheetImage.h" 29 | #import "YYImageCoder.h" 30 | #import "YYAnimatedImageView.h" 31 | #endif 32 | 33 | NS_ASSUME_NONNULL_BEGIN 34 | 35 | 36 | /** 37 | A YYImage object is a high-level way to display animated image data. 38 | 39 | @discussion It is a fully compatible `UIImage` subclass. It extends the UIImage 40 | to support animated WebP, APNG and GIF format image data decoding. It also 41 | support NSCoding protocol to archive and unarchive multi-frame image data. 42 | 43 | If the image is created from multi-frame image data, and you want to play the 44 | animation, try replace UIImageView with `YYAnimatedImageView`. 45 | 46 | Sample Code: 47 | 48 | // animation@3x.webp 49 | YYImage *image = [YYImage imageNamed:@"animation.webp"]; 50 | YYAnimatedImageView *imageView = [YYAnimatedImageView alloc] initWithImage:image]; 51 | [view addSubView:imageView]; 52 | 53 | */ 54 | @interface YYImage : UIImage 55 | 56 | + (nullable YYImage *)imageNamed:(NSString *)name; // no cache! 57 | + (nullable YYImage *)imageWithContentsOfFile:(NSString *)path; 58 | + (nullable YYImage *)imageWithData:(NSData *)data; 59 | + (nullable YYImage *)imageWithData:(NSData *)data scale:(CGFloat)scale; 60 | 61 | /** 62 | If the image is created from data or file, then the value indicates the data type. 63 | */ 64 | @property (nonatomic, readonly) YYImageType animatedImageType; 65 | 66 | /** 67 | If the image is created from animated image data (multi-frame GIF/APNG/WebP), 68 | this property stores the original image data. 69 | */ 70 | @property (nullable, nonatomic, readonly) NSData *animatedImageData; 71 | 72 | /** 73 | The total memory usage (in bytes) if all frame images was loaded into memory. 74 | The value is 0 if the image is not created from a multi-frame image data. 75 | */ 76 | @property (nonatomic, readonly) NSUInteger animatedImageMemorySize; 77 | 78 | /** 79 | Preload all frame image to memory. 80 | 81 | @discussion Set this property to `YES` will block the calling thread to decode 82 | all animation frame image to memory, set to `NO` will release the preloaded frames. 83 | If the image is shared by lots of image views (such as emoticon), preload all 84 | frames will reduce the CPU cost. 85 | 86 | See `animatedImageMemorySize` for memory cost. 87 | */ 88 | @property (nonatomic) BOOL preloadAllAnimatedImageFrames; 89 | 90 | @end 91 | 92 | NS_ASSUME_NONNULL_END 93 | -------------------------------------------------------------------------------- /Examples/Pods/YYImage/YYImage/YYSpriteSheetImage.h: -------------------------------------------------------------------------------- 1 | // 2 | // YYSpriteImage.h 3 | // YYImage 4 | // 5 | // Created by ibireme on 15/4/21. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | #if __has_include() 15 | #import 16 | #elif __has_include() 17 | #import 18 | #else 19 | #import "YYAnimatedImageView.h" 20 | #endif 21 | 22 | NS_ASSUME_NONNULL_BEGIN 23 | 24 | /** 25 | An image to display sprite sheet animation. 26 | 27 | @discussion It is a fully compatible `UIImage` subclass. 28 | The animation can be played by YYAnimatedImageView. 29 | 30 | Sample Code: 31 | 32 | // 8 * 12 sprites in a single sheet image 33 | UIImage *spriteSheet = [UIImage imageNamed:@"sprite-sheet"]; 34 | NSMutableArray *contentRects = [NSMutableArray new]; 35 | NSMutableArray *durations = [NSMutableArray new]; 36 | for (int j = 0; j < 12; j++) { 37 | for (int i = 0; i < 8; i++) { 38 | CGRect rect; 39 | rect.size = CGSizeMake(img.size.width / 8, img.size.height / 12); 40 | rect.origin.x = img.size.width / 8 * i; 41 | rect.origin.y = img.size.height / 12 * j; 42 | [contentRects addObject:[NSValue valueWithCGRect:rect]]; 43 | [durations addObject:@(1 / 60.0)]; 44 | } 45 | } 46 | YYSpriteSheetImage *sprite; 47 | sprite = [[YYSpriteSheetImage alloc] initWithSpriteSheetImage:img 48 | contentRects:contentRects 49 | frameDurations:durations 50 | loopCount:0]; 51 | YYAnimatedImageView *imgView = [YYAnimatedImageView new]; 52 | imgView.size = CGSizeMake(img.size.width / 8, img.size.height / 12); 53 | imgView.image = sprite; 54 | 55 | 56 | 57 | @discussion It can also be used to display single frame in sprite sheet image. 58 | Sample Code: 59 | 60 | YYSpriteSheetImage *sheet = ...; 61 | UIImageView *imageView = ...; 62 | imageView.image = sheet; 63 | imageView.layer.contentsRect = [sheet contentsRectForCALayerAtIndex:6]; 64 | 65 | */ 66 | @interface YYSpriteSheetImage : UIImage 67 | 68 | /** 69 | Creates and returns an image object. 70 | 71 | @param image The sprite sheet image (contains all frames). 72 | 73 | @param contentRects The sprite sheet image frame rects in the image coordinates. 74 | The rectangle should not outside the image's bounds. The objects in this array 75 | should be created with [NSValue valueWithCGRect:]. 76 | 77 | @param frameDurations The sprite sheet image frame's durations in seconds. 78 | The objects in this array should be NSNumber. 79 | 80 | @param loopCount Animation loop count, 0 means infinite looping. 81 | 82 | @return An image object, or nil if an error occurs. 83 | */ 84 | - (nullable instancetype)initWithSpriteSheetImage:(UIImage *)image 85 | contentRects:(NSArray *)contentRects 86 | frameDurations:(NSArray *)frameDurations 87 | loopCount:(NSUInteger)loopCount; 88 | 89 | @property (nonatomic, readonly) NSArray *contentRects; 90 | @property (nonatomic, readonly) NSArray *frameDurations; 91 | @property (nonatomic, readonly) NSUInteger loopCount; 92 | 93 | /** 94 | Get the contents rect for CALayer. 95 | See "contentsRect" property in CALayer for more information. 96 | 97 | @param index Index of frame. 98 | @return Contents Rect. 99 | */ 100 | - (CGRect)contentsRectForCALayerAtIndex:(NSUInteger)index; 101 | 102 | @end 103 | 104 | NS_ASSUME_NONNULL_END 105 | -------------------------------------------------------------------------------- /Examples/Pods/YYImage/YYImage/YYSpriteSheetImage.m: -------------------------------------------------------------------------------- 1 | // 2 | // YYSpriteImage.m 3 | // YYImage 4 | // 5 | // Created by ibireme on 15/4/21. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import "YYSpriteSheetImage.h" 13 | 14 | @implementation YYSpriteSheetImage 15 | 16 | - (instancetype)initWithSpriteSheetImage:(UIImage *)image 17 | contentRects:(NSArray *)contentRects 18 | frameDurations:(NSArray *)frameDurations 19 | loopCount:(NSUInteger)loopCount { 20 | if (!image.CGImage) return nil; 21 | if (contentRects.count < 1 || frameDurations.count < 1) return nil; 22 | if (contentRects.count != frameDurations.count) return nil; 23 | 24 | self = [super initWithCGImage:image.CGImage scale:image.scale orientation:image.imageOrientation]; 25 | if (!self) return nil; 26 | 27 | _contentRects = contentRects.copy; 28 | _frameDurations = frameDurations.copy; 29 | _loopCount = loopCount; 30 | return self; 31 | } 32 | 33 | - (CGRect)contentsRectForCALayerAtIndex:(NSUInteger)index { 34 | CGRect layerRect = CGRectMake(0, 0, 1, 1); 35 | if (index >= _contentRects.count) return layerRect; 36 | 37 | CGSize imageSize = self.size; 38 | CGRect rect = [self animatedImageContentsRectAtIndex:index]; 39 | if (imageSize.width > 0.01 && imageSize.height > 0.01) { 40 | layerRect.origin.x = rect.origin.x / imageSize.width; 41 | layerRect.origin.y = rect.origin.y / imageSize.height; 42 | layerRect.size.width = rect.size.width / imageSize.width; 43 | layerRect.size.height = rect.size.height / imageSize.height; 44 | layerRect = CGRectIntersection(layerRect, CGRectMake(0, 0, 1, 1)); 45 | if (CGRectIsNull(layerRect) || CGRectIsEmpty(layerRect)) { 46 | layerRect = CGRectMake(0, 0, 1, 1); 47 | } 48 | } 49 | return layerRect; 50 | } 51 | 52 | #pragma mark @protocol YYAnimatedImage 53 | 54 | - (NSUInteger)animatedImageFrameCount { 55 | return _contentRects.count; 56 | } 57 | 58 | - (NSUInteger)animatedImageLoopCount { 59 | return _loopCount; 60 | } 61 | 62 | - (NSUInteger)animatedImageBytesPerFrame { 63 | return 0; 64 | } 65 | 66 | - (UIImage *)animatedImageFrameAtIndex:(NSUInteger)index { 67 | return self; 68 | } 69 | 70 | - (NSTimeInterval)animatedImageDurationAtIndex:(NSUInteger)index { 71 | if (index >= _frameDurations.count) return 0; 72 | return ((NSNumber *)_frameDurations[index]).doubleValue; 73 | } 74 | 75 | - (CGRect)animatedImageContentsRectAtIndex:(NSUInteger)index { 76 | if (index >= _contentRects.count) return CGRectZero; 77 | return ((NSValue *)_contentRects[index]).CGRectValue; 78 | } 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /Examples/Pods/YYWebImage/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 ibireme 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Examples/Pods/YYWebImage/YYWebImage/Categories/CALayer+YYWebImage.h: -------------------------------------------------------------------------------- 1 | // 2 | // CALayer+YYWebImage.h 3 | // YYWebImage 4 | // 5 | // Created by ibireme on 15/2/23. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | #import 14 | 15 | #if __has_include() 16 | #import 17 | #else 18 | #import "YYWebImageManager.h" 19 | #endif 20 | 21 | NS_ASSUME_NONNULL_BEGIN 22 | 23 | /** 24 | Web image methods for CALayer. 25 | It will set image to layer.contents. 26 | */ 27 | @interface CALayer (YYWebImage) 28 | 29 | #pragma mark - image 30 | 31 | /** 32 | Current image URL. 33 | 34 | @discussion Set a new value to this property will cancel the previous request 35 | operation and create a new request operation to fetch image. Set nil to clear 36 | the image and image URL. 37 | */ 38 | @property (nullable, nonatomic, strong) NSURL *yy_imageURL; 39 | 40 | /** 41 | Set the view's `image` with a specified URL. 42 | 43 | @param imageURL The image url (remote or local file path). 44 | @param placeholder The image to be set initially, until the image request finishes. 45 | */ 46 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL placeholder:(nullable UIImage *)placeholder; 47 | 48 | /** 49 | Set the view's `image` with a specified URL. 50 | 51 | @param imageURL The image url (remote or local file path). 52 | @param options The options to use when request the image. 53 | */ 54 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL options:(YYWebImageOptions)options; 55 | 56 | /** 57 | Set the view's `image` with a specified URL. 58 | 59 | @param imageURL The image url (remote or local file path). 60 | @param placeholder The image to be set initially, until the image request finishes. 61 | @param options The options to use when request the image. 62 | @param completion The block invoked (on main thread) when image request completed. 63 | */ 64 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL 65 | placeholder:(nullable UIImage *)placeholder 66 | options:(YYWebImageOptions)options 67 | completion:(nullable YYWebImageCompletionBlock)completion; 68 | 69 | /** 70 | Set the view's `image` with a specified URL. 71 | 72 | @param imageURL The image url (remote or local file path). 73 | @param placeholder The image to be set initially, until the image request finishes. 74 | @param options The options to use when request the image. 75 | @param progress The block invoked (on main thread) during image request. 76 | @param transform The block invoked (on background thread) to do additional image process. 77 | @param transformKey 转换key,链接相同但key不同会有不同的缓存 78 | @param completion The block invoked (on main thread) when image request completed. 79 | */ 80 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL 81 | placeholder:(nullable UIImage *)placeholder 82 | options:(YYWebImageOptions)options 83 | progress:(nullable YYWebImageProgressBlock)progress 84 | transform:(nullable YYWebImageTransformBlock)transform 85 | transformKey:(nullable NSString *)transformKey 86 | completion:(nullable YYWebImageCompletionBlock)completion; 87 | 88 | /** 89 | Set the view's `image` with a specified URL. 90 | 91 | @param imageURL The image url (remote or local file path). 92 | @param placeholder he image to be set initially, until the image request finishes. 93 | @param options The options to use when request the image. 94 | @param manager The manager to create image request operation. 95 | @param progress The block invoked (on main thread) during image request. 96 | @param transform The block invoked (on background thread) to do additional image process. 97 | @param transformKey 转换key,链接相同但key不同会有不同的缓存 98 | @param completion The block invoked (on main thread) when image request completed. 99 | */ 100 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL 101 | placeholder:(nullable UIImage *)placeholder 102 | options:(YYWebImageOptions)options 103 | manager:(nullable YYWebImageManager *)manager 104 | progress:(nullable YYWebImageProgressBlock)progress 105 | transform:(nullable YYWebImageTransformBlock)transform 106 | transformKey:(nullable NSString *)transformKey 107 | completion:(nullable YYWebImageCompletionBlock)completion; 108 | 109 | /** 110 | Cancel the current image request. 111 | */ 112 | - (void)yy_cancelCurrentImageRequest; 113 | 114 | @end 115 | 116 | NS_ASSUME_NONNULL_END 117 | -------------------------------------------------------------------------------- /Examples/Pods/YYWebImage/YYWebImage/Categories/CALayer+YYWebImage.m: -------------------------------------------------------------------------------- 1 | // 2 | // CALayer+YYWebImage.m 3 | // YYWebImage 4 | // 5 | // Created by ibireme on 15/2/23. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import "CALayer+YYWebImage.h" 13 | #import "YYWebImageOperation.h" 14 | #import "_YYWebImageSetter.h" 15 | #import 16 | 17 | // Dummy class for category 18 | @interface CALayer_YYWebImage : NSObject @end 19 | @implementation CALayer_YYWebImage @end 20 | 21 | 22 | static int _YYWebImageSetterKey; 23 | 24 | @implementation CALayer (YYWebImage) 25 | 26 | - (NSURL *)yy_imageURL { 27 | _YYWebImageSetter *setter = objc_getAssociatedObject(self, &_YYWebImageSetterKey); 28 | return setter.imageURL; 29 | } 30 | 31 | - (void)setYy_imageURL:(NSURL *)imageURL { 32 | [self yy_setImageWithURL:imageURL 33 | placeholder:nil 34 | options:kNilOptions 35 | manager:nil 36 | progress:nil 37 | transform:nil 38 | transformKey:nil 39 | completion:nil]; 40 | } 41 | 42 | - (void)yy_setImageWithURL:(NSURL *)imageURL placeholder:(UIImage *)placeholder { 43 | [self yy_setImageWithURL:imageURL 44 | placeholder:placeholder 45 | options:kNilOptions 46 | manager:nil 47 | progress:nil 48 | transform:nil 49 | transformKey:nil 50 | completion:nil]; 51 | } 52 | 53 | - (void)yy_setImageWithURL:(NSURL *)imageURL options:(YYWebImageOptions)options { 54 | [self yy_setImageWithURL:imageURL 55 | placeholder:nil 56 | options:options 57 | manager:nil 58 | progress:nil 59 | transform:nil 60 | transformKey:nil 61 | completion:nil]; 62 | } 63 | 64 | - (void)yy_setImageWithURL:(NSURL *)imageURL 65 | placeholder:(UIImage *)placeholder 66 | options:(YYWebImageOptions)options 67 | completion:(YYWebImageCompletionBlock)completion { 68 | [self yy_setImageWithURL:imageURL 69 | placeholder:placeholder 70 | options:options 71 | manager:nil 72 | progress:nil 73 | transform:nil 74 | transformKey:nil 75 | completion:completion]; 76 | } 77 | 78 | - (void)yy_setImageWithURL:(NSURL *)imageURL 79 | placeholder:(UIImage *)placeholder 80 | options:(YYWebImageOptions)options 81 | progress:(YYWebImageProgressBlock)progress 82 | transform:(YYWebImageTransformBlock)transform 83 | transformKey:(nullable NSString *)transformKey 84 | completion:(YYWebImageCompletionBlock)completion { 85 | [self yy_setImageWithURL:imageURL 86 | placeholder:placeholder 87 | options:options 88 | manager:nil 89 | progress:progress 90 | transform:transform 91 | transformKey:transformKey 92 | completion:completion]; 93 | } 94 | 95 | - (void)yy_setImageWithURL:(NSURL *)imageURL 96 | placeholder:(UIImage *)placeholder 97 | options:(YYWebImageOptions)options 98 | manager:(YYWebImageManager *)manager 99 | progress:(YYWebImageProgressBlock)progress 100 | transform:(YYWebImageTransformBlock)transform 101 | transformKey:(nullable NSString *)transformKey 102 | completion:(YYWebImageCompletionBlock)completion { 103 | if ([imageURL isKindOfClass:[NSString class]]) imageURL = [NSURL URLWithString:(id)imageURL]; 104 | manager = manager ? manager : [YYWebImageManager sharedManager]; 105 | 106 | 107 | _YYWebImageSetter *setter = objc_getAssociatedObject(self, &_YYWebImageSetterKey); 108 | if (!setter) { 109 | setter = [_YYWebImageSetter new]; 110 | objc_setAssociatedObject(self, &_YYWebImageSetterKey, setter, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 111 | } 112 | int32_t sentinel = [setter cancelWithNewURL:imageURL]; 113 | 114 | _yy_dispatch_sync_on_main_queue(^{ 115 | if ((options & YYWebImageOptionSetImageWithFadeAnimation) && 116 | !(options & YYWebImageOptionAvoidSetImage)) { 117 | [self removeAnimationForKey:_YYWebImageFadeAnimationKey]; 118 | } 119 | 120 | if (!imageURL) { 121 | if (!(options & YYWebImageOptionIgnorePlaceHolder)) { 122 | self.contents = (id)placeholder.CGImage; 123 | } 124 | return; 125 | } 126 | 127 | // get the image from memory as quickly as possible 128 | UIImage *imageFromMemory = nil; 129 | if (manager.cache && 130 | !(options & YYWebImageOptionUseNSURLCache) && 131 | !(options & YYWebImageOptionRefreshImageCache)) { 132 | imageFromMemory = [manager.cache getImageForKey:[manager cacheKeyForURL:imageURL transformKey:transformKey 133 | ] withType:YYImageCacheTypeMemory]; 134 | } 135 | if (imageFromMemory) { 136 | if (!(options & YYWebImageOptionAvoidSetImage)) { 137 | self.contents = (id)imageFromMemory.CGImage; 138 | } 139 | if(completion) completion(imageFromMemory, imageURL, YYWebImageFromMemoryCacheFast, YYWebImageStageFinished, nil); 140 | return; 141 | } 142 | 143 | if (!(options & YYWebImageOptionIgnorePlaceHolder)) { 144 | self.contents = (id)placeholder.CGImage; 145 | } 146 | 147 | __weak typeof(self) _self = self; 148 | dispatch_async([_YYWebImageSetter setterQueue], ^{ 149 | YYWebImageProgressBlock _progress = nil; 150 | if (progress) _progress = ^(NSInteger receivedSize, NSInteger expectedSize) { 151 | dispatch_async(dispatch_get_main_queue(), ^{ 152 | progress(receivedSize, expectedSize); 153 | }); 154 | }; 155 | 156 | __block int32_t newSentinel = 0; 157 | __block __weak typeof(setter) weakSetter = nil; 158 | YYWebImageCompletionBlock _completion = ^(UIImage *image, NSURL *url, YYWebImageFromType from, YYWebImageStage stage, NSError *error) { 159 | __strong typeof(_self) self = _self; 160 | BOOL setImage = (stage == YYWebImageStageFinished || stage == YYWebImageStageProgress) && image && !(options & YYWebImageOptionAvoidSetImage); 161 | BOOL showFade = (options & YYWebImageOptionSetImageWithFadeAnimation); 162 | dispatch_async(dispatch_get_main_queue(), ^{ 163 | BOOL sentinelChanged = weakSetter && weakSetter.sentinel != newSentinel; 164 | if (setImage && self && !sentinelChanged) { 165 | if (showFade) { 166 | CATransition *transition = [CATransition animation]; 167 | transition.duration = stage == YYWebImageStageFinished ? _YYWebImageFadeTime : _YYWebImageProgressiveFadeTime; 168 | transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 169 | transition.type = kCATransitionFade; 170 | [self addAnimation:transition forKey:_YYWebImageFadeAnimationKey]; 171 | } 172 | self.contents = (id)image.CGImage; 173 | } 174 | if (completion) { 175 | if (sentinelChanged) { 176 | completion(nil, url, YYWebImageFromNone, YYWebImageStageCancelled, nil); 177 | } else { 178 | completion(image, url, from, stage, error); 179 | } 180 | } 181 | }); 182 | }; 183 | 184 | newSentinel = [setter setOperationWithSentinel:sentinel url:imageURL options:options manager:manager progress:_progress transform:transform transformKey:transformKey completion:_completion]; 185 | weakSetter = setter; 186 | }); 187 | 188 | 189 | }); 190 | } 191 | 192 | - (void)yy_cancelCurrentImageRequest { 193 | _YYWebImageSetter *setter = objc_getAssociatedObject(self, &_YYWebImageSetterKey); 194 | if (setter) [setter cancel]; 195 | } 196 | 197 | @end 198 | -------------------------------------------------------------------------------- /Examples/Pods/YYWebImage/YYWebImage/Categories/MKAnnotationView+YYWebImage.h: -------------------------------------------------------------------------------- 1 | // 2 | // MKAnnotationView+YYWebImage.h 3 | // YYWebImage 4 | // 5 | // Created by ibireme on 15/2/23. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | #import 14 | 15 | #if __has_include() 16 | #import 17 | #else 18 | #import "YYWebImageManager.h" 19 | #endif 20 | 21 | NS_ASSUME_NONNULL_BEGIN 22 | 23 | /** 24 | Web image methods for MKAnnotationView. 25 | */ 26 | @interface MKAnnotationView (YYWebImage) 27 | 28 | /** 29 | Current image URL. 30 | 31 | @discussion Set a new value to this property will cancel the previous request 32 | operation and create a new request operation to fetch image. Set nil to clear 33 | the image and image URL. 34 | */ 35 | @property (nullable, nonatomic, strong) NSURL *yy_imageURL; 36 | 37 | /** 38 | Set the view's `image` with a specified URL. 39 | 40 | @param imageURL The image url (remote or local file path). 41 | @param placeholder The image to be set initially, until the image request finishes. 42 | */ 43 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL placeholder:(nullable UIImage *)placeholder; 44 | 45 | /** 46 | Set the view's `image` with a specified URL. 47 | 48 | @param imageURL The image url (remote or local file path). 49 | @param options The options to use when request the image. 50 | */ 51 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL options:(YYWebImageOptions)options; 52 | 53 | /** 54 | Set the view's `image` with a specified URL. 55 | 56 | @param imageURL The image url (remote or local file path). 57 | @param placeholder The image to be set initially, until the image request finishes. 58 | @param options The options to use when request the image. 59 | @param completion The block invoked (on main thread) when image request completed. 60 | */ 61 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL 62 | placeholder:(nullable UIImage *)placeholder 63 | options:(YYWebImageOptions)options 64 | completion:(nullable YYWebImageCompletionBlock)completion; 65 | 66 | /** 67 | Set the view's `image` with a specified URL. 68 | 69 | @param imageURL The image url (remote or local file path). 70 | @param placeholder The image to be set initially, until the image request finishes. 71 | @param options The options to use when request the image. 72 | @param progress The block invoked (on main thread) during image request. 73 | @param transform The block invoked (on background thread) to do additional image process. 74 | @param transformKey 转换key,链接相同但key不同会有不同的缓存 75 | @param completion The block invoked (on main thread) when image request completed. 76 | */ 77 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL 78 | placeholder:(nullable UIImage *)placeholder 79 | options:(YYWebImageOptions)options 80 | progress:(nullable YYWebImageProgressBlock)progress 81 | transform:(nullable YYWebImageTransformBlock)transform 82 | transformKey:(nullable NSString *)transformKey 83 | completion:(nullable YYWebImageCompletionBlock)completion; 84 | 85 | /** 86 | Set the view's `image` with a specified URL. 87 | 88 | @param imageURL The image url (remote or local file path). 89 | @param placeholder he image to be set initially, until the image request finishes. 90 | @param options The options to use when request the image. 91 | @param manager The manager to create image request operation. 92 | @param progress The block invoked (on main thread) during image request. 93 | @param transform The block invoked (on background thread) to do additional image process. 94 | @param transformKey 转换key,链接相同但key不同会有不同的缓存 95 | @param completion The block invoked (on main thread) when image request completed. 96 | */ 97 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL 98 | placeholder:(nullable UIImage *)placeholder 99 | options:(YYWebImageOptions)options 100 | manager:(nullable YYWebImageManager *)manager 101 | progress:(nullable YYWebImageProgressBlock)progress 102 | transform:(nullable YYWebImageTransformBlock)transform 103 | transformKey:(nullable NSString *)transformKey 104 | completion:(nullable YYWebImageCompletionBlock)completion; 105 | 106 | /** 107 | Cancel the current image request. 108 | */ 109 | - (void)yy_cancelCurrentImageRequest; 110 | 111 | @end 112 | 113 | NS_ASSUME_NONNULL_END 114 | -------------------------------------------------------------------------------- /Examples/Pods/YYWebImage/YYWebImage/Categories/MKAnnotationView+YYWebImage.m: -------------------------------------------------------------------------------- 1 | // 2 | // MKAnnotationView+YYWebImage.m 3 | // YYWebImage 4 | // 5 | // Created by ibireme on 15/2/23. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import "MKAnnotationView+YYWebImage.h" 13 | #import "YYWebImageOperation.h" 14 | #import "_YYWebImageSetter.h" 15 | #import 16 | 17 | // Dummy class for category 18 | @interface MKAnnotationView_YYWebImage : NSObject @end 19 | @implementation MKAnnotationView_YYWebImage @end 20 | 21 | 22 | static int _YYWebImageSetterKey; 23 | 24 | @implementation MKAnnotationView (YYWebImage) 25 | 26 | - (NSURL *)yy_imageURL { 27 | _YYWebImageSetter *setter = objc_getAssociatedObject(self, &_YYWebImageSetterKey); 28 | return setter.imageURL; 29 | } 30 | 31 | - (void)setYy_imageURL:(NSURL *)imageURL { 32 | [self yy_setImageWithURL:imageURL 33 | placeholder:nil 34 | options:kNilOptions 35 | manager:nil 36 | progress:nil 37 | transform:nil 38 | transformKey:nil 39 | completion:nil]; 40 | } 41 | 42 | - (void)yy_setImageWithURL:(NSURL *)imageURL placeholder:(UIImage *)placeholder { 43 | [self yy_setImageWithURL:imageURL 44 | placeholder:placeholder 45 | options:kNilOptions 46 | manager:nil 47 | progress:nil 48 | transform:nil 49 | transformKey:nil 50 | completion:nil]; 51 | } 52 | 53 | - (void)yy_setImageWithURL:(NSURL *)imageURL options:(YYWebImageOptions)options { 54 | [self yy_setImageWithURL:imageURL 55 | placeholder:nil 56 | options:options 57 | manager:nil 58 | progress:nil 59 | transform:nil 60 | transformKey:nil 61 | completion:nil]; 62 | } 63 | 64 | - (void)yy_setImageWithURL:(NSURL *)imageURL 65 | placeholder:(UIImage *)placeholder 66 | options:(YYWebImageOptions)options 67 | completion:(YYWebImageCompletionBlock)completion { 68 | [self yy_setImageWithURL:imageURL 69 | placeholder:placeholder 70 | options:options 71 | manager:nil 72 | progress:nil 73 | transform:nil 74 | transformKey:nil 75 | completion:completion]; 76 | } 77 | 78 | - (void)yy_setImageWithURL:(NSURL *)imageURL 79 | placeholder:(UIImage *)placeholder 80 | options:(YYWebImageOptions)options 81 | progress:(YYWebImageProgressBlock)progress 82 | transform:(YYWebImageTransformBlock)transform 83 | transformKey:(nullable NSString *)transformKey 84 | completion:(YYWebImageCompletionBlock)completion { 85 | [self yy_setImageWithURL:imageURL 86 | placeholder:placeholder 87 | options:options 88 | manager:nil 89 | progress:progress 90 | transform:transform 91 | transformKey:transformKey 92 | completion:completion]; 93 | } 94 | 95 | - (void)yy_setImageWithURL:(NSURL *)imageURL 96 | placeholder:(UIImage *)placeholder 97 | options:(YYWebImageOptions)options 98 | manager:(YYWebImageManager *)manager 99 | progress:(YYWebImageProgressBlock)progress 100 | transform:(YYWebImageTransformBlock)transform 101 | transformKey:(nullable NSString *)transformKey 102 | completion:(YYWebImageCompletionBlock)completion { 103 | if ([imageURL isKindOfClass:[NSString class]]) imageURL = [NSURL URLWithString:(id)imageURL]; 104 | manager = manager ? manager : [YYWebImageManager sharedManager]; 105 | 106 | _YYWebImageSetter *setter = objc_getAssociatedObject(self, &_YYWebImageSetterKey); 107 | if (!setter) { 108 | setter = [_YYWebImageSetter new]; 109 | objc_setAssociatedObject(self, &_YYWebImageSetterKey, setter, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 110 | } 111 | int32_t sentinel = [setter cancelWithNewURL:imageURL]; 112 | 113 | _yy_dispatch_sync_on_main_queue(^{ 114 | if ((options & YYWebImageOptionSetImageWithFadeAnimation) && 115 | !(options & YYWebImageOptionAvoidSetImage)) { 116 | if (!self.highlighted) { 117 | [self.layer removeAnimationForKey:_YYWebImageFadeAnimationKey]; 118 | } 119 | } 120 | if (!imageURL) { 121 | if (!(options & YYWebImageOptionIgnorePlaceHolder)) { 122 | self.image = placeholder; 123 | } 124 | return; 125 | } 126 | 127 | // get the image from memory as quickly as possible 128 | UIImage *imageFromMemory = nil; 129 | if (manager.cache && 130 | !(options & YYWebImageOptionUseNSURLCache) && 131 | !(options & YYWebImageOptionRefreshImageCache)) { 132 | imageFromMemory = [manager.cache getImageForKey:[manager cacheKeyForURL:imageURL transformKey:transformKey] withType:YYImageCacheTypeMemory]; 133 | } 134 | if (imageFromMemory) { 135 | if (!(options & YYWebImageOptionAvoidSetImage)) { 136 | self.image = imageFromMemory; 137 | } 138 | if(completion) completion(imageFromMemory, imageURL, YYWebImageFromMemoryCacheFast, YYWebImageStageFinished, nil); 139 | return; 140 | } 141 | 142 | if (!(options & YYWebImageOptionIgnorePlaceHolder)) { 143 | self.image = placeholder; 144 | } 145 | 146 | __weak typeof(self) _self = self; 147 | dispatch_async([_YYWebImageSetter setterQueue], ^{ 148 | YYWebImageProgressBlock _progress = nil; 149 | if (progress) _progress = ^(NSInteger receivedSize, NSInteger expectedSize) { 150 | dispatch_async(dispatch_get_main_queue(), ^{ 151 | progress(receivedSize, expectedSize); 152 | }); 153 | }; 154 | 155 | __block int32_t newSentinel = 0; 156 | __block __weak typeof(setter) weakSetter = nil; 157 | YYWebImageCompletionBlock _completion = ^(UIImage *image, NSURL *url, YYWebImageFromType from, YYWebImageStage stage, NSError *error) { 158 | __strong typeof(_self) self = _self; 159 | BOOL setImage = (stage == YYWebImageStageFinished || stage == YYWebImageStageProgress) && image && !(options & YYWebImageOptionAvoidSetImage); 160 | BOOL showFade = ((options & YYWebImageOptionSetImageWithFadeAnimation) && !self.highlighted); 161 | dispatch_async(dispatch_get_main_queue(), ^{ 162 | BOOL sentinelChanged = weakSetter && weakSetter.sentinel != newSentinel; 163 | if (setImage && self && !sentinelChanged) { 164 | if (showFade) { 165 | CATransition *transition = [CATransition animation]; 166 | transition.duration = stage == YYWebImageStageFinished ? _YYWebImageFadeTime : _YYWebImageProgressiveFadeTime; 167 | transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 168 | transition.type = kCATransitionFade; 169 | [self.layer addAnimation:transition forKey:_YYWebImageFadeAnimationKey]; 170 | } 171 | self.image = image; 172 | } 173 | if (completion) { 174 | if (sentinelChanged) { 175 | completion(nil, url, YYWebImageFromNone, YYWebImageStageCancelled, nil); 176 | } else { 177 | completion(image, url, from, stage, error); 178 | } 179 | } 180 | }); 181 | }; 182 | 183 | newSentinel = [setter setOperationWithSentinel:sentinel url:imageURL options:options manager:manager progress:_progress transform:transform transformKey:transformKey completion:_completion]; 184 | weakSetter = setter; 185 | }); 186 | }); 187 | } 188 | 189 | - (void)yy_cancelCurrentImageRequest { 190 | _YYWebImageSetter *setter = objc_getAssociatedObject(self, &_YYWebImageSetterKey); 191 | if (setter) [setter cancel]; 192 | } 193 | 194 | @end 195 | -------------------------------------------------------------------------------- /Examples/Pods/YYWebImage/YYWebImage/Categories/UIImageView+YYWebImage.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImageView+YYWebImage.h 3 | // YYWebImage 4 | // 5 | // Created by ibireme on 15/2/23. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | #if __has_include() 15 | #import 16 | #else 17 | #import "YYWebImageManager.h" 18 | #endif 19 | 20 | NS_ASSUME_NONNULL_BEGIN 21 | 22 | /** 23 | Web image methods for UIImageView. 24 | */ 25 | @interface UIImageView (YYWebImage) 26 | 27 | #pragma mark - image 28 | 29 | /** 30 | Current image URL. 31 | 32 | @discussion Set a new value to this property will cancel the previous request 33 | operation and create a new request operation to fetch image. Set nil to clear 34 | the image and image URL. 35 | */ 36 | @property (nullable, nonatomic, strong) NSURL *yy_imageURL; 37 | 38 | /** 39 | Set the view's `image` with a specified URL. 40 | 41 | @param imageURL The image url (remote or local file path). 42 | @param placeholder The image to be set initially, until the image request finishes. 43 | */ 44 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL placeholder:(nullable UIImage *)placeholder; 45 | 46 | /** 47 | Set the view's `image` with a specified URL. 48 | 49 | @param imageURL The image url (remote or local file path). 50 | @param options The options to use when request the image. 51 | */ 52 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL options:(YYWebImageOptions)options; 53 | 54 | /** 55 | Set the view's `image` with a specified URL. 56 | 57 | @param imageURL The image url (remote or local file path). 58 | @param placeholder The image to be set initially, until the image request finishes. 59 | @param options The options to use when request the image. 60 | @param completion The block invoked (on main thread) when image request completed. 61 | */ 62 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL 63 | placeholder:(nullable UIImage *)placeholder 64 | options:(YYWebImageOptions)options 65 | completion:(nullable YYWebImageCompletionBlock)completion; 66 | 67 | /** 68 | Set the view's `image` with a specified URL. 69 | 70 | @param imageURL The image url (remote or local file path). 71 | @param placeholder The image to be set initially, until the image request finishes. 72 | @param options The options to use when request the image. 73 | @param progress The block invoked (on main thread) during image request. 74 | @param transform The block invoked (on background thread) to do additional image process. 75 | @param transformKey 转换key,链接相同但key不同会有不同的缓存 76 | @param completion The block invoked (on main thread) when image request completed. 77 | */ 78 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL 79 | placeholder:(nullable UIImage *)placeholder 80 | options:(YYWebImageOptions)options 81 | progress:(nullable YYWebImageProgressBlock)progress 82 | transform:(nullable YYWebImageTransformBlock)transform 83 | transformKey:(nullable NSString *)transformKey 84 | completion:(nullable YYWebImageCompletionBlock)completion; 85 | 86 | /** 87 | Set the view's `image` with a specified URL. 88 | 89 | @param imageURL The image url (remote or local file path). 90 | @param placeholder he image to be set initially, until the image request finishes. 91 | @param options The options to use when request the image. 92 | @param manager The manager to create image request operation. 93 | @param progress The block invoked (on main thread) during image request. 94 | @param transform The block invoked (on background thread) to do additional image process. 95 | @param transformKey 转换key,链接相同但key不同会有不同的缓存 96 | @param completion The block invoked (on main thread) when image request completed. 97 | */ 98 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL 99 | placeholder:(nullable UIImage *)placeholder 100 | options:(YYWebImageOptions)options 101 | manager:(nullable YYWebImageManager *)manager 102 | progress:(nullable YYWebImageProgressBlock)progress 103 | transform:(nullable YYWebImageTransformBlock)transform 104 | transformKey:(nullable NSString *)transformKey 105 | completion:(nullable YYWebImageCompletionBlock)completion; 106 | 107 | /** 108 | Cancel the current image request. 109 | */ 110 | - (void)yy_cancelCurrentImageRequest; 111 | 112 | 113 | 114 | #pragma mark - highlight image 115 | 116 | /** 117 | Current highlighted image URL. 118 | 119 | @discussion Set a new value to this property will cancel the previous request 120 | operation and create a new request operation to fetch image. Set nil to clear 121 | the highlighted image and image URL. 122 | */ 123 | @property (nullable, nonatomic, strong) NSURL *yy_highlightedImageURL; 124 | 125 | /** 126 | Set the view's `highlightedImage` with a specified URL. 127 | 128 | @param imageURL The image url (remote or local file path). 129 | @param placeholder The image to be set initially, until the image request finishes. 130 | */ 131 | - (void)yy_setHighlightedImageWithURL:(nullable NSURL *)imageURL placeholder:(nullable UIImage *)placeholder; 132 | 133 | /** 134 | Set the view's `highlightedImage` with a specified URL. 135 | 136 | @param imageURL The image url (remote or local file path). 137 | @param options The options to use when request the image. 138 | */ 139 | - (void)yy_setHighlightedImageWithURL:(nullable NSURL *)imageURL options:(YYWebImageOptions)options; 140 | 141 | /** 142 | Set the view's `highlightedImage` with a specified URL. 143 | 144 | @param imageURL The image url (remote or local file path). 145 | @param placeholder The image to be set initially, until the image request finishes. 146 | @param options The options to use when request the image. 147 | @param completion The block invoked (on main thread) when image request completed. 148 | */ 149 | - (void)yy_setHighlightedImageWithURL:(nullable NSURL *)imageURL 150 | placeholder:(nullable UIImage *)placeholder 151 | options:(YYWebImageOptions)options 152 | completion:(nullable YYWebImageCompletionBlock)completion; 153 | 154 | /** 155 | Set the view's `highlightedImage` with a specified URL. 156 | 157 | @param imageURL The image url (remote or local file path). 158 | @param placeholder The image to be set initially, until the image request finishes. 159 | @param options The options to use when request the image. 160 | @param progress The block invoked (on main thread) during image request. 161 | @param transform The block invoked (on background thread) to do additional image process. 162 | @param transformKey 转换key,链接相同但key不同会有不同的缓存 163 | @param completion The block invoked (on main thread) when image request completed. 164 | */ 165 | - (void)yy_setHighlightedImageWithURL:(nullable NSURL *)imageURL 166 | placeholder:(nullable UIImage *)placeholder 167 | options:(YYWebImageOptions)options 168 | progress:(nullable YYWebImageProgressBlock)progress 169 | transform:(nullable YYWebImageTransformBlock)transform 170 | transformKey:(nullable NSString *)transformKey 171 | completion:(nullable YYWebImageCompletionBlock)completion; 172 | 173 | /** 174 | Set the view's `highlightedImage` with a specified URL. 175 | 176 | @param imageURL The image url (remote or local file path). 177 | @param placeholder The image to be set initially, until the image request finishes. 178 | @param options The options to use when request the image. 179 | @param manager The manager to create image request operation. 180 | @param progress The block invoked (on main thread) during image request. 181 | @param transform The block invoked (on background thread) to do additional image process. 182 | @param transformKey 转换key,链接相同但key不同会有不同的缓存 183 | @param completion The block invoked (on main thread) when image request completed. 184 | */ 185 | - (void)yy_setHighlightedImageWithURL:(nullable NSURL *)imageURL 186 | placeholder:(nullable UIImage *)placeholder 187 | options:(YYWebImageOptions)options 188 | manager:(nullable YYWebImageManager *)manager 189 | progress:(nullable YYWebImageProgressBlock)progress 190 | transform:(nullable YYWebImageTransformBlock)transform 191 | transformKey:(nullable NSString *)transformKey 192 | completion:(nullable YYWebImageCompletionBlock)completion; 193 | 194 | /** 195 | Cancel the current highlighed image request. 196 | */ 197 | - (void)yy_cancelCurrentHighlightedImageRequest; 198 | 199 | @end 200 | 201 | NS_ASSUME_NONNULL_END 202 | -------------------------------------------------------------------------------- /Examples/Pods/YYWebImage/YYWebImage/Categories/_YYWebImageSetter.h: -------------------------------------------------------------------------------- 1 | // 2 | // _YYWebImageSetter.h 3 | // YYWebImage 4 | // 5 | // Created by ibireme on 15/7/15. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | #import 12 | #import 13 | 14 | #if __has_include() 15 | #import 16 | #else 17 | #import "YYWebImageManager.h" 18 | #endif 19 | 20 | NS_ASSUME_NONNULL_BEGIN 21 | 22 | /** 23 | Submits a block for execution on a main queue and waits until the block completes. 24 | */ 25 | static inline void _yy_dispatch_sync_on_main_queue(void (^block)()) { 26 | if (pthread_main_np()) { 27 | block(); 28 | } else { 29 | dispatch_sync(dispatch_get_main_queue(), block); 30 | } 31 | } 32 | 33 | extern NSString *const _YYWebImageFadeAnimationKey; 34 | extern const NSTimeInterval _YYWebImageFadeTime; 35 | extern const NSTimeInterval _YYWebImageProgressiveFadeTime; 36 | 37 | /** 38 | Private class used by web image categories. 39 | Typically, you should not use this class directly. 40 | */ 41 | @interface _YYWebImageSetter : NSObject 42 | /// Current image url. 43 | @property (nullable, nonatomic, readonly) NSURL *imageURL; 44 | /// Current sentinel. 45 | @property (nonatomic, readonly) int32_t sentinel; 46 | 47 | /// Create new operation for web image and return a sentinel value. 48 | - (int32_t)setOperationWithSentinel:(int32_t)sentinel 49 | url:(nullable NSURL *)imageURL 50 | options:(YYWebImageOptions)options 51 | manager:(YYWebImageManager *)manager 52 | progress:(nullable YYWebImageProgressBlock)progress 53 | transform:(nullable YYWebImageTransformBlock)transform 54 | transformKey:(nullable NSString *)transformKey 55 | completion:(nullable YYWebImageCompletionBlock)completion; 56 | 57 | /// Cancel and return a sentinel value. The imageURL will be set to nil. 58 | - (int32_t)cancel; 59 | 60 | /// Cancel and return a sentinel value. The imageURL will be set to new value. 61 | - (int32_t)cancelWithNewURL:(nullable NSURL *)imageURL; 62 | 63 | /// A queue to set operation. 64 | + (dispatch_queue_t)setterQueue; 65 | 66 | @end 67 | 68 | NS_ASSUME_NONNULL_END 69 | -------------------------------------------------------------------------------- /Examples/Pods/YYWebImage/YYWebImage/Categories/_YYWebImageSetter.m: -------------------------------------------------------------------------------- 1 | // 2 | // _YYWebImageSetter.m 3 | // YYWebImage 4 | // 5 | // Created by ibireme on 15/7/15. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import "_YYWebImageSetter.h" 13 | #import "YYWebImageOperation.h" 14 | #import 15 | 16 | NSString *const _YYWebImageFadeAnimationKey = @"YYWebImageFade"; 17 | const NSTimeInterval _YYWebImageFadeTime = 0.2; 18 | const NSTimeInterval _YYWebImageProgressiveFadeTime = 0.4; 19 | 20 | 21 | @implementation _YYWebImageSetter { 22 | dispatch_semaphore_t _lock; 23 | NSURL *_imageURL; 24 | NSOperation *_operation; 25 | int32_t _sentinel; 26 | } 27 | 28 | - (instancetype)init { 29 | self = [super init]; 30 | _lock = dispatch_semaphore_create(1); 31 | return self; 32 | } 33 | 34 | - (NSURL *)imageURL { 35 | dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER); 36 | NSURL *imageURL = _imageURL; 37 | dispatch_semaphore_signal(_lock); 38 | return imageURL; 39 | } 40 | 41 | - (void)dealloc { 42 | OSAtomicIncrement32(&_sentinel); 43 | [_operation cancel]; 44 | } 45 | 46 | - (int32_t)setOperationWithSentinel:(int32_t)sentinel 47 | url:(NSURL *)imageURL 48 | options:(YYWebImageOptions)options 49 | manager:(YYWebImageManager *)manager 50 | progress:(YYWebImageProgressBlock)progress 51 | transform:(YYWebImageTransformBlock)transform 52 | transformKey:(nullable NSString *)transformKey 53 | completion:(YYWebImageCompletionBlock)completion { 54 | if (sentinel != _sentinel) { 55 | if (completion) completion(nil, imageURL, YYWebImageFromNone, YYWebImageStageCancelled, nil); 56 | return _sentinel; 57 | } 58 | 59 | NSOperation *operation = [manager requestImageWithURL:imageURL options:options progress:progress transform:transform transformKey:transformKey completion:completion]; 60 | if (!operation && completion) { 61 | NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : @"YYWebImageOperation create failed." }; 62 | completion(nil, imageURL, YYWebImageFromNone, YYWebImageStageFinished, [NSError errorWithDomain:@"com.ibireme.webimage" code:-1 userInfo:userInfo]); 63 | } 64 | 65 | dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER); 66 | if (sentinel == _sentinel) { 67 | if (_operation) [_operation cancel]; 68 | _operation = operation; 69 | sentinel = OSAtomicIncrement32(&_sentinel); 70 | } else { 71 | [operation cancel]; 72 | } 73 | dispatch_semaphore_signal(_lock); 74 | return sentinel; 75 | } 76 | 77 | - (int32_t)cancel { 78 | return [self cancelWithNewURL:nil]; 79 | } 80 | 81 | - (int32_t)cancelWithNewURL:(NSURL *)imageURL { 82 | int32_t sentinel; 83 | dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER); 84 | if (_operation) { 85 | [_operation cancel]; 86 | _operation = nil; 87 | } 88 | _imageURL = imageURL; 89 | sentinel = OSAtomicIncrement32(&_sentinel); 90 | dispatch_semaphore_signal(_lock); 91 | return sentinel; 92 | } 93 | 94 | + (dispatch_queue_t)setterQueue { 95 | static dispatch_queue_t queue; 96 | static dispatch_once_t onceToken; 97 | dispatch_once(&onceToken, ^{ 98 | queue = dispatch_queue_create("com.ibireme.webimage.setter", DISPATCH_QUEUE_SERIAL); 99 | dispatch_set_target_queue(queue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)); 100 | }); 101 | return queue; 102 | } 103 | 104 | @end 105 | -------------------------------------------------------------------------------- /Examples/Pods/YYWebImage/YYWebImage/YYWebImage.h: -------------------------------------------------------------------------------- 1 | // 2 | // YYWebImage.h 3 | // YYWebImage 4 | // 5 | // Created by ibireme on 15/2/23. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | #if __has_include() 15 | FOUNDATION_EXPORT double YYWebImageVersionNumber; 16 | FOUNDATION_EXPORT const unsigned char YYWebImageVersionString[]; 17 | #import 18 | #import 19 | #import 20 | #import 21 | #import 22 | #import 23 | #import 24 | #import 25 | #else 26 | #import "YYImageCache.h" 27 | #import "YYWebImageOperation.h" 28 | #import "YYWebImageManager.h" 29 | #import "UIImage+YYWebImage.h" 30 | #import "UIImageView+YYWebImage.h" 31 | #import "UIButton+YYWebImage.h" 32 | #import "CALayer+YYWebImage.h" 33 | #import "MKAnnotationView+YYWebImage.h" 34 | #endif 35 | 36 | #if __has_include() 37 | #import 38 | #elif __has_include() 39 | #import 40 | #import 41 | #import 42 | #import 43 | #import 44 | #else 45 | #import "YYImage.h" 46 | #import "YYFrameImage.h" 47 | #import "YYSpriteSheetImage.h" 48 | #import "YYImageCoder.h" 49 | #import "YYAnimatedImageView.h" 50 | #endif 51 | 52 | #if __has_include() 53 | #import 54 | #elif __has_include() 55 | #import 56 | #import 57 | #import 58 | #import 59 | #else 60 | #import "YYCache.h" 61 | #import "YYMemoryCache.h" 62 | #import "YYDiskCache.h" 63 | #import "YYKVStorage.h" 64 | #endif 65 | 66 | -------------------------------------------------------------------------------- /Examples/Pods/YYWebImage/YYWebImage/YYWebImageManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // YYWebImageManager.m 3 | // YYWebImage 4 | // 5 | // Created by ibireme on 15/2/19. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import "YYWebImageManager.h" 13 | #import "YYImageCache.h" 14 | #import "YYWebImageOperation.h" 15 | #import "YYImageCoder.h" 16 | #import 17 | 18 | #define kNetworkIndicatorDelay (1/30.0) 19 | 20 | 21 | /// Returns nil in App Extension. 22 | static UIApplication *_YYSharedApplication() { 23 | static BOOL isAppExtension = NO; 24 | static dispatch_once_t onceToken; 25 | dispatch_once(&onceToken, ^{ 26 | Class cls = NSClassFromString(@"UIApplication"); 27 | if(!cls || ![cls respondsToSelector:@selector(sharedApplication)]) isAppExtension = YES; 28 | if ([[[NSBundle mainBundle] bundlePath] hasSuffix:@".appex"]) isAppExtension = YES; 29 | }); 30 | #pragma clang diagnostic push 31 | #pragma clang diagnostic ignored "-Wundeclared-selector" 32 | return isAppExtension ? nil : [UIApplication performSelector:@selector(sharedApplication)]; 33 | #pragma clang diagnostic pop 34 | } 35 | 36 | 37 | @interface _YYWebImageApplicationNetworkIndicatorInfo : NSObject 38 | @property (nonatomic, assign) NSInteger count; 39 | @property (nonatomic, strong) NSTimer *timer; 40 | @end 41 | @implementation _YYWebImageApplicationNetworkIndicatorInfo 42 | @end 43 | 44 | @implementation YYWebImageManager 45 | 46 | + (instancetype)sharedManager { 47 | static YYWebImageManager *manager; 48 | static dispatch_once_t onceToken; 49 | dispatch_once(&onceToken, ^{ 50 | YYImageCache *cache = [YYImageCache sharedCache]; 51 | NSOperationQueue *queue = [NSOperationQueue new]; 52 | if ([queue respondsToSelector:@selector(setQualityOfService:)]) { 53 | queue.qualityOfService = NSQualityOfServiceBackground; 54 | } 55 | manager = [[self alloc] initWithCache:cache queue:queue]; 56 | }); 57 | return manager; 58 | } 59 | 60 | - (instancetype)init { 61 | @throw [NSException exceptionWithName:@"YYWebImageManager init error" reason:@"Use the designated initializer to init." userInfo:nil]; 62 | return [self initWithCache:nil queue:nil]; 63 | } 64 | 65 | - (instancetype)initWithCache:(YYImageCache *)cache queue:(NSOperationQueue *)queue{ 66 | self = [super init]; 67 | if (!self) return nil; 68 | _cache = cache; 69 | _queue = queue; 70 | _timeout = 15.0; 71 | if (YYImageWebPAvailable()) { 72 | _headers = @{ @"Accept" : @"image/webp,image/*;q=0.8" }; 73 | } else { 74 | _headers = @{ @"Accept" : @"image/*;q=0.8" }; 75 | } 76 | return self; 77 | } 78 | 79 | - (YYWebImageOperation *)requestImageWithURL:(NSURL *)url 80 | options:(YYWebImageOptions)options 81 | progress:(YYWebImageProgressBlock)progress 82 | transform:(YYWebImageTransformBlock)transform 83 | transformKey:(nullable NSString *)transformKey 84 | completion:(YYWebImageCompletionBlock)completion { 85 | 86 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 87 | request.timeoutInterval = _timeout; 88 | request.HTTPShouldHandleCookies = (options & YYWebImageOptionHandleCookies) != 0; 89 | request.allHTTPHeaderFields = [self headersForURL:url]; 90 | request.HTTPShouldUsePipelining = YES; 91 | request.cachePolicy = (options & YYWebImageOptionUseNSURLCache) ? 92 | NSURLRequestUseProtocolCachePolicy : NSURLRequestReloadIgnoringLocalCacheData; 93 | 94 | YYWebImageOperation *operation = [[YYWebImageOperation alloc]initWithRequest:request 95 | options:options 96 | cache:_cache 97 | cacheKey:[self cacheKeyForURL:url transformKey:transformKey] 98 | progress:progress 99 | transform:transform ? transform : _sharedTransformBlock 100 | transformKey:transformKey 101 | completion:completion]; 102 | 103 | if (_username && _password) { 104 | operation.credential = [NSURLCredential credentialWithUser:_username password:_password persistence:NSURLCredentialPersistenceForSession]; 105 | } 106 | if (operation) { 107 | NSOperationQueue *queue = _queue; 108 | if (queue) { 109 | [queue addOperation:operation]; 110 | } else { 111 | [operation start]; 112 | } 113 | } 114 | return operation; 115 | } 116 | 117 | - (NSDictionary *)headersForURL:(NSURL *)url { 118 | if (!url) return nil; 119 | return _headersFilter ? _headersFilter(url, _headers) : _headers; 120 | } 121 | 122 | - (NSString *)cacheKeyForURL:(NSURL *)url transformKey:(nullable NSString *)transformKey { 123 | if (!url) return nil; 124 | NSString *cacheKey = _cacheKeyFilter ? _cacheKeyFilter(url) : url.absoluteString; 125 | if (transformKey) 126 | return [NSString stringWithFormat:@"%@--%@", cacheKey, transformKey]; 127 | else 128 | return cacheKey; 129 | } 130 | 131 | #pragma mark Network Indicator 132 | 133 | + (_YYWebImageApplicationNetworkIndicatorInfo *)_networkIndicatorInfo { 134 | return objc_getAssociatedObject(self, @selector(_networkIndicatorInfo)); 135 | } 136 | 137 | + (void)_setNetworkIndicatorInfo:(_YYWebImageApplicationNetworkIndicatorInfo *)info { 138 | objc_setAssociatedObject(self, @selector(_networkIndicatorInfo), info, OBJC_ASSOCIATION_RETAIN); 139 | } 140 | 141 | + (void)_delaySetActivity:(NSTimer *)timer { 142 | UIApplication *app = _YYSharedApplication(); 143 | if (!app) return; 144 | 145 | NSNumber *visiable = timer.userInfo; 146 | if (app.networkActivityIndicatorVisible != visiable.boolValue) { 147 | [app setNetworkActivityIndicatorVisible:visiable.boolValue]; 148 | } 149 | [timer invalidate]; 150 | } 151 | 152 | + (void)_changeNetworkActivityCount:(NSInteger)delta { 153 | if (!_YYSharedApplication()) return; 154 | 155 | void (^block)() = ^{ 156 | _YYWebImageApplicationNetworkIndicatorInfo *info = [self _networkIndicatorInfo]; 157 | if (!info) { 158 | info = [_YYWebImageApplicationNetworkIndicatorInfo new]; 159 | [self _setNetworkIndicatorInfo:info]; 160 | } 161 | NSInteger count = info.count; 162 | count += delta; 163 | info.count = count; 164 | [info.timer invalidate]; 165 | info.timer = [NSTimer timerWithTimeInterval:kNetworkIndicatorDelay target:self selector:@selector(_delaySetActivity:) userInfo:@(info.count > 0) repeats:NO]; 166 | [[NSRunLoop mainRunLoop] addTimer:info.timer forMode:NSRunLoopCommonModes]; 167 | }; 168 | if ([NSThread isMainThread]) { 169 | block(); 170 | } else { 171 | dispatch_async(dispatch_get_main_queue(), block); 172 | } 173 | } 174 | 175 | + (void)incrementNetworkActivityCount { 176 | [self _changeNetworkActivityCount:1]; 177 | } 178 | 179 | + (void)decrementNetworkActivityCount { 180 | [self _changeNetworkActivityCount:-1]; 181 | } 182 | 183 | + (NSInteger)currentNetworkActivityCount { 184 | _YYWebImageApplicationNetworkIndicatorInfo *info = [self _networkIndicatorInfo]; 185 | return info.count; 186 | } 187 | 188 | @end 189 | -------------------------------------------------------------------------------- /Examples/Pods/YYWebImage/YYWebImage/YYWebImageOperation.h: -------------------------------------------------------------------------------- 1 | // 2 | // YYWebImageOperation.h 3 | // YYWebImage 4 | // 5 | // Created by ibireme on 15/2/15. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | #if __has_include() 15 | #import 16 | #import 17 | #else 18 | #import "YYImageCache.h" 19 | #import "YYWebImageManager.h" 20 | #endif 21 | 22 | NS_ASSUME_NONNULL_BEGIN 23 | 24 | /** 25 | The YYWebImageOperation class is an NSOperation subclass used to fetch image 26 | from URL request. 27 | 28 | @discussion It's an asynchronous operation. You typically execute it by adding 29 | it to an operation queue, or calls 'start' to execute it manually. When the 30 | operation is started, it will: 31 | 32 | 1. Get the image from the cache, if exist, return it with `completion` block. 33 | 2. Start an URL connection to fetch image from the request, invoke the `progress` 34 | to notify request progress (and invoke `completion` block to return the 35 | progressive image if enabled by progressive option). 36 | 3. Process the image by invoke the `transform` block. 37 | 4. Put the image to cache and return it with `completion` block. 38 | 39 | */ 40 | @interface YYWebImageOperation : NSOperation 41 | 42 | @property (nonatomic, strong, readonly) NSURLRequest *request; ///< The image URL request. 43 | @property (nullable, nonatomic, strong, readonly) NSURLResponse *response; ///< The response for request. 44 | @property (nullable, nonatomic, strong, readonly) YYImageCache *cache; ///< The image cache. 45 | @property (nonatomic, strong, readonly) NSString *cacheKey; ///< The image cache key. 46 | @property (nonatomic, readonly) YYWebImageOptions options; ///< The operation's option. 47 | 48 | /** 49 | Whether the URL connection should consult the credential storage for authenticating 50 | the connection. Default is YES. 51 | 52 | @discussion This is the value that is returned in the `NSURLConnectionDelegate` 53 | method `-connectionShouldUseCredentialStorage:`. 54 | */ 55 | @property (nonatomic) BOOL shouldUseCredentialStorage; 56 | 57 | /** 58 | The credential used for authentication challenges in `-connection:didReceiveAuthenticationChallenge:`. 59 | 60 | @discussion This will be overridden by any shared credentials that exist for the 61 | username or password of the request URL, if present. 62 | */ 63 | @property (nullable, nonatomic, strong) NSURLCredential *credential; 64 | 65 | /** 66 | Creates and returns a new operation. 67 | 68 | You should call `start` to execute this operation, or you can add the operation 69 | to an operation queue. 70 | 71 | @param request The Image request. This value should not be nil. 72 | @param options A mask to specify options to use for this operation. 73 | @param cache An image cache. Pass nil to avoid image cache. 74 | @param cacheKey An image cache key. Pass nil to avoid image cache. 75 | @param progress A block invoked in image fetch progress. 76 | The block will be invoked in background thread. Pass nil to avoid it. 77 | @param transform A block invoked before image fetch finished to do additional image process. 78 | The block will be invoked in background thread. Pass nil to avoid it. 79 | @param completion A block invoked when image fetch finished or cancelled. 80 | The block will be invoked in background thread. Pass nil to avoid it. 81 | @param transformKey 转换key,链接相同但key不同会有不同的缓存 82 | 83 | @return The image request opeartion, or nil if an error occurs. 84 | */ 85 | - (instancetype)initWithRequest:(NSURLRequest *)request 86 | options:(YYWebImageOptions)options 87 | cache:(nullable YYImageCache *)cache 88 | cacheKey:(nullable NSString *)cacheKey 89 | progress:(nullable YYWebImageProgressBlock)progress 90 | transform:(nullable YYWebImageTransformBlock)transform 91 | transformKey:(nullable NSString *)transformKey 92 | completion:(nullable YYWebImageCompletionBlock)completion NS_DESIGNATED_INITIALIZER; 93 | 94 | - (instancetype)init UNAVAILABLE_ATTRIBUTE; 95 | + (instancetype)new UNAVAILABLE_ATTRIBUTE; 96 | 97 | @end 98 | 99 | NS_ASSUME_NONNULL_END 100 | -------------------------------------------------------------------------------- /Examples/dots18.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raozhizhen/JMRoundedCorner/d577bb3f7c100c73e0fba426790530856274c60a/Examples/dots18.gif -------------------------------------------------------------------------------- /JMRoundedCorner.podspec: -------------------------------------------------------------------------------- 1 | 2 | Pod::Spec.new do |s| 3 | 4 | s.name = "JMRoundedCorner" 5 | s.version = "1.9.7" 6 | s.summary = "UIView set Corner Radius" 7 | s.homepage = "https://github.com/raozhizhen/JMRoundedCorner.git" 8 | s.license = { :type => "MIT", :file => "LICENSE" } 9 | s.author = { "raozhizhen" => "raozhizhen@gmail.com" } 10 | s.platform = :ios, "7.0" 11 | s.source = { :git => "https://github.com/raozhizhen/JMRoundedCorner.git", :tag => s.version } 12 | s.source_files = "JMRoundedCorner/*.{h,m}" 13 | s.requires_arc = true 14 | end 15 | -------------------------------------------------------------------------------- /JMRoundedCorner/JMRoundedCorner.h: -------------------------------------------------------------------------------- 1 | // 2 | // JMRoundedCorner.h 3 | // JMRoundedCornerDemo 4 | // 5 | // Created by 饶志臻 on 2016/10/9. 6 | // Copyright © 2016年 饶志臻. All rights reserved. 7 | // 8 | 9 | #ifndef JMRoundedCorner_h 10 | #define JMRoundedCorner_h 11 | 12 | #import "UIImage+JMRadius.h" 13 | #import "UIView+JMRadius.h" 14 | #import "UIImageView+JMRadius.h" 15 | #import "UIButton+JMRadius.h" 16 | 17 | #endif /* JMRoundedCorner_h */ 18 | -------------------------------------------------------------------------------- /JMRoundedCorner/UIButton+JMRadius.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIButton+JMRadius.h 3 | // JMRoundedCornerDemo 4 | // 5 | // Created by 饶志臻 on 2016/10/9. 6 | // Copyright © 2016年 饶志臻. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UIImage+JMRadius.h" 11 | 12 | @interface UIButton (JMRadius) 13 | 14 | /**设置圆角背景图,默认 UIViewContentModeScaleAspectFill 模式*/ 15 | - (void)jm_setImageWithCornerRadius:(CGFloat)radius 16 | imageURL:(NSURL *)imageURL 17 | placeholder:(UIImage *)placeholder 18 | size:(CGSize)size 19 | forState:(UIControlState)state; 20 | 21 | /**设置圆角背景图,默认 UIViewContentModeScaleAspectFill 模式*/ 22 | - (void)jm_setImageWithJMRadius:(JMRadius)radius 23 | imageURL:(NSURL *)imageURL 24 | placeholder:(UIImage *)placeholder 25 | size:(CGSize)size 26 | forState:(UIControlState)state; 27 | 28 | /**设置 contentMode 模式的圆角背景图*/ 29 | - (void)jm_setImageWithCornerRadius:(CGFloat)radius 30 | imageURL:(NSURL *)imageURL 31 | placeholder:(UIImage *)placeholder 32 | contentMode:(UIViewContentMode)contentMode 33 | size:(CGSize)size 34 | forState:(UIControlState)state; 35 | 36 | /**设置 contentMode 模式的圆角背景图*/ 37 | - (void)jm_setImageWithJMRadius:(JMRadius)radius 38 | imageURL:(NSURL *)imageURL 39 | placeholder:(UIImage *)placeholder 40 | contentMode:(UIViewContentMode)contentMode 41 | size:(CGSize)size 42 | forState:(UIControlState)state; 43 | 44 | /**配置所有属性配置圆角背景图*/ 45 | - (void)jm_setImageWithJMRadius:(JMRadius)radius 46 | imageURL:(NSURL *)imageURL 47 | placeholder:(UIImage *)placeholder 48 | borderColor:(UIColor *)borderColor 49 | borderWidth:(CGFloat)borderWidth 50 | backgroundColor:(UIColor *)backgroundColor 51 | contentMode:(UIViewContentMode)contentMode 52 | size:(CGSize)size 53 | forState:(UIControlState)state; 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /JMRoundedCorner/UIButton+JMRadius.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIButton+JMRadius.m 3 | // JMRoundedCornerDemo 4 | // 5 | // Created by 饶志臻 on 2016/10/9. 6 | // Copyright © 2016年 饶志臻. All rights reserved. 7 | // 8 | 9 | #import "UIButton+JMRadius.h" 10 | #if __has_include() 11 | #import 12 | #else 13 | #import "UIButton+YYWebImage.h" 14 | #endif 15 | 16 | 17 | @implementation UIButton (JMRadius) 18 | 19 | - (void)jm_setImageWithCornerRadius:(CGFloat)radius imageURL:(NSURL *)imageURL placeholder:(UIImage *)placeholder size:(CGSize)size forState:(UIControlState)state { 20 | [self jm_setImageWithJMRadius:JMRadiusMake(radius, radius, radius, radius) imageURL:imageURL placeholder:placeholder borderColor:nil borderWidth:0 backgroundColor:nil contentMode:UIViewContentModeScaleAspectFill size:size forState:(UIControlState)state]; 21 | } 22 | 23 | - (void)jm_setImageWithJMRadius:(JMRadius)radius imageURL:(NSURL *)imageURL placeholder:(UIImage *)placeholder size:(CGSize)size forState:(UIControlState)state { 24 | [self jm_setImageWithJMRadius:radius imageURL:imageURL placeholder:placeholder borderColor:nil borderWidth:0 backgroundColor:nil contentMode:UIViewContentModeScaleAspectFill size:size forState:(UIControlState)state]; 25 | } 26 | 27 | - (void)jm_setImageWithCornerRadius:(CGFloat)radius imageURL:(NSURL *)imageURL placeholder:(UIImage *)placeholder contentMode:(UIViewContentMode)contentMode size:(CGSize)size forState:(UIControlState)state { 28 | [self jm_setImageWithJMRadius:JMRadiusMake(radius, radius, radius, radius) imageURL:imageURL placeholder:placeholder borderColor:nil borderWidth:0 backgroundColor:nil contentMode:contentMode size:size forState:(UIControlState)state]; 29 | } 30 | 31 | - (void)jm_setImageWithJMRadius:(JMRadius)radius imageURL:(NSURL *)imageURL placeholder:(UIImage *)placeholder contentMode:(UIViewContentMode)contentMode size:(CGSize)size forState:(UIControlState)state { 32 | [self jm_setImageWithJMRadius:radius imageURL:imageURL placeholder:placeholder borderColor:nil borderWidth:0 backgroundColor:nil contentMode:contentMode size:size forState:(UIControlState)state]; 33 | } 34 | 35 | - (void)jm_setImageWithJMRadius:(JMRadius)radius imageURL:(NSURL *)imageURL placeholder:(UIImage *)placeholder borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth backgroundColor:(UIColor *)backgroundColor contentMode:(UIViewContentMode)contentMode size:(CGSize)size forState:(UIControlState)state { 36 | 37 | NSString *transformKey = [NSString stringWithFormat:@"%@%@%.1f%@%li%@", NSStringFromJMRadius(radius), borderColor.description, borderWidth, backgroundColor.description, (long)contentMode,NSStringFromCGSize(size)]; 38 | NSString *transformImageKey = [[YYWebImageManager sharedManager] cacheKeyForURL:imageURL transformKey:transformKey]; 39 | UIImage *cacheImage = [[YYWebImageManager sharedManager].cache getImageForKey:transformImageKey]; 40 | 41 | if (cacheImage) { 42 | [self setImage:cacheImage forState:state]; 43 | return; 44 | } 45 | 46 | NSString *imageKey = [[YYWebImageManager sharedManager] cacheKeyForURL:imageURL transformKey:nil]; 47 | cacheImage = [[YYWebImageManager sharedManager].cache getImageForKey:imageKey]; 48 | 49 | if (cacheImage) { 50 | cacheImage = [UIImage jm_setJMRadius:radius image:cacheImage size:size borderColor:borderColor borderWidth:borderWidth backgroundColor:backgroundColor withContentMode:contentMode]; 51 | [self setImage:cacheImage forState:state]; 52 | return; 53 | } 54 | 55 | UIImage *placeholderImage; 56 | if (placeholder || borderWidth > 0 || backgroundColor) { 57 | placeholderImage = [[YYWebImageManager sharedManager].cache getImageForKey:transformKey]; 58 | if (!placeholderImage) { 59 | placeholderImage = [UIImage jm_setJMRadius:radius image:placeholder size:size borderColor:borderColor borderWidth:borderWidth backgroundColor:backgroundColor withContentMode:contentMode]; 60 | [[YYWebImageManager sharedManager].cache setImage:placeholderImage forKey:transformKey]; 61 | } 62 | } 63 | 64 | [self yy_setImageWithURL:imageURL forState:state placeholder:placeholderImage options:kNilOptions progress:nil transform:^UIImage * _Nullable(UIImage * _Nonnull image, NSURL * _Nonnull url) { 65 | [[YYWebImageManager sharedManager].cache setImage:image forKey:imageKey]; 66 | UIImage *currentImage = [UIImage jm_setJMRadius:radius image:image size:size borderColor:borderColor borderWidth:borderWidth backgroundColor:backgroundColor withContentMode:contentMode]; 67 | return currentImage; 68 | } transformKey:transformKey completion:^(UIImage * _Nullable image, NSURL * _Nonnull url, YYWebImageFromType from, YYWebImageStage stage, NSError * _Nullable error) { 69 | }]; 70 | } 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /JMRoundedCorner/UIImage+JMRadius.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+RoundedCorner.h 3 | // UIImageRoundedCornerDemo 4 | // 5 | // Created by jm on 16/2/22. 6 | // Copyright © 2016年 Jim. All rights reserved. 7 | // 8 | //生成带圆角的图片 9 | 10 | #import 11 | 12 | struct JMRadius { 13 | CGFloat topLeftRadius; 14 | CGFloat topRightRadius; 15 | CGFloat bottomLeftRadius; 16 | CGFloat bottomRightRadius; 17 | }; 18 | typedef struct JMRadius JMRadius; 19 | 20 | static inline JMRadius JMRadiusMake(CGFloat topLeftRadius, CGFloat topRightRadius, CGFloat bottomLeftRadius, CGFloat bottomRightRadius) { 21 | JMRadius radius; 22 | radius.topLeftRadius = topLeftRadius; 23 | radius.topRightRadius = topRightRadius; 24 | radius.bottomLeftRadius = bottomLeftRadius; 25 | radius.bottomRightRadius = bottomRightRadius; 26 | return radius; 27 | } 28 | 29 | static inline NSString * NSStringFromJMRadius(JMRadius radius) { 30 | return [NSString stringWithFormat:@"{%.2f, %.2f, %.2f, %.2f}", radius.topLeftRadius, radius.topRightRadius, radius.bottomLeftRadius, radius.bottomRightRadius]; 31 | } 32 | 33 | @interface UIImage (RoundedCorner) 34 | 35 | - (UIImage *)jm_setRadius:(CGFloat)radius 36 | size:(CGSize)size; 37 | 38 | - (UIImage *)jm_setRadius:(CGFloat)radius 39 | size:(CGSize)size 40 | contentMode:(UIViewContentMode)contentMode; 41 | 42 | + (UIImage *)jm_setRadius:(CGFloat)radius 43 | size:(CGSize)size 44 | borderColor:(UIColor *)borderColor 45 | borderWidth:(CGFloat)borderWidth 46 | backgroundColor:(UIColor *)backgroundColor; 47 | 48 | + (UIImage *)jm_setJMRadius:(JMRadius)radius 49 | image:(UIImage *)image 50 | size:(CGSize)size 51 | borderColor:(UIColor *)borderColor 52 | borderWidth:(CGFloat)borderWidth 53 | backgroundColor:(UIColor *)backgroundColor 54 | withContentMode:(UIViewContentMode)contentMode; 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /JMRoundedCorner/UIImage+JMRadius.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+RoundedCorner.m 3 | // UIImageRoundedCornerDemo 4 | // 5 | // Created by jm on 16/2/22. 6 | // Copyright © 2016年 Jim. All rights reserved. 7 | // 8 | 9 | #import "UIImage+JMRadius.h" 10 | 11 | @implementation UIImage (RoundedCorner) 12 | 13 | - (UIImage *)jm_setRadius:(CGFloat)radius size:(CGSize)size { 14 | return [UIImage jm_setJMRadius:JMRadiusMake(radius, radius, radius, radius) image:self size:size borderColor:nil borderWidth:0 backgroundColor:nil withContentMode:UIViewContentModeScaleToFill]; 15 | } 16 | 17 | - (UIImage *)jm_setRadius:(CGFloat)radius size:(CGSize)size contentMode:(UIViewContentMode)contentMode { 18 | return [UIImage jm_setJMRadius:JMRadiusMake(radius, radius, radius, radius) image:self size:size borderColor:nil borderWidth:0 backgroundColor:nil withContentMode:contentMode]; 19 | } 20 | 21 | + (UIImage *)jm_setRadius:(CGFloat)radius size:(CGSize)size borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth backgroundColor:(UIColor *)backgroundColor { 22 | return [UIImage jm_setJMRadius:JMRadiusMake(radius, radius, radius, radius) image:nil size:size borderColor:borderColor borderWidth:borderWidth backgroundColor:backgroundColor withContentMode:UIViewContentModeScaleToFill]; 23 | } 24 | 25 | + (UIImage *)jm_setJMRadius:(JMRadius)radius image:(UIImage *)image size:(CGSize)size borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth backgroundColor:(UIColor *)backgroundColor withContentMode:(UIViewContentMode)contentMode { 26 | 27 | if (!backgroundColor) { 28 | backgroundColor = [UIColor whiteColor]; 29 | } 30 | if (image) { 31 | image = [image scaleToSize:CGSizeMake(size.width, size.height) withContentMode:contentMode backgroundColor:backgroundColor]; 32 | } else { 33 | image = [UIImage imageWithColor:backgroundColor]; 34 | } 35 | 36 | UIGraphicsBeginImageContextWithOptions(size, NO, UIScreen.mainScreen.scale); 37 | CGContextRef context = UIGraphicsGetCurrentContext(); 38 | CGRect rect = CGRectMake(0, 0, size.width, size.height); 39 | CGContextScaleCTM(context, 1, -1); 40 | CGContextTranslateCTM(context, 0, -rect.size.height); 41 | CGFloat height = size.height; 42 | CGFloat width = size.width; 43 | radius = [UIImage transformationJMRadius:radius size:size borderWidth:borderWidth]; 44 | 45 | UIBezierPath *path = [[UIBezierPath alloc] init]; 46 | [path addArcWithCenter:CGPointMake(width - radius.topRightRadius, height - radius.topRightRadius) radius:radius.topRightRadius startAngle:0 endAngle:M_PI_2 clockwise:YES]; 47 | [path addArcWithCenter:CGPointMake(radius.topLeftRadius, height - radius.topLeftRadius) radius:radius.topLeftRadius startAngle:M_PI_2 endAngle:M_PI clockwise:YES]; 48 | [path addArcWithCenter:CGPointMake(radius.bottomLeftRadius, radius.bottomLeftRadius) radius:radius.bottomLeftRadius startAngle:M_PI endAngle:3.0 * M_PI_2 clockwise:YES]; 49 | [path addArcWithCenter:CGPointMake(width - radius.bottomRightRadius, radius.bottomRightRadius) radius:radius.bottomRightRadius startAngle:3.0 * M_PI_2 endAngle:2.0 * M_PI clockwise:YES]; 50 | [path closePath]; 51 | 52 | [path addClip]; 53 | CGContextDrawImage(context, rect, image.CGImage); 54 | path.lineWidth = borderWidth; 55 | [borderColor setStroke]; 56 | [path stroke]; 57 | 58 | UIImage *currentImage = UIGraphicsGetImageFromCurrentImageContext(); 59 | UIGraphicsEndImageContext(); 60 | return currentImage; 61 | } 62 | 63 | + (JMRadius)transformationJMRadius:(JMRadius)radius size:(CGSize)size borderWidth:(CGFloat)borderWidth { 64 | radius.topLeftRadius = minimum(size.width, size.height, radius.topLeftRadius); 65 | radius.topRightRadius = minimum(size.width - radius.topLeftRadius, size.height, radius.topRightRadius); 66 | radius.bottomLeftRadius = minimum(size.width, size.height - radius.topLeftRadius, radius.bottomLeftRadius); 67 | radius.bottomRightRadius = minimum(size.width - radius.bottomLeftRadius, size.height - radius.topRightRadius, radius.bottomRightRadius); 68 | return radius; 69 | } 70 | 71 | static inline CGFloat minimum(CGFloat a, CGFloat b, CGFloat c) { 72 | CGFloat minimum = MIN(MIN(a, b), c); 73 | return MAX(minimum, 0); 74 | } 75 | 76 | - (UIImage *)scaleToSize:(CGSize)size withContentMode:(UIViewContentMode)contentMode backgroundColor:(UIColor *)backgroundColor { 77 | CGRect rect = CGRectMake(0, 0, size.width, size.height); 78 | UIGraphicsBeginImageContextWithOptions(size, NO, UIScreen.mainScreen.scale); 79 | CGContextRef context = UIGraphicsGetCurrentContext(); 80 | CGContextSetFillColorWithColor(context, backgroundColor.CGColor); 81 | CGContextAddRect(context, rect); 82 | CGContextDrawPath(context, kCGPathFill); 83 | [self drawInRect:[self convertRect:rect withContentMode:contentMode]]; 84 | UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext(); 85 | UIGraphicsEndImageContext(); 86 | return scaledImage; 87 | } 88 | 89 | + (UIImage *)imageWithColor:(UIColor *)color { 90 | CGRect rect = CGRectMake(0, 0, 1, 1); 91 | UIGraphicsBeginImageContext(rect.size); 92 | CGContextRef context = UIGraphicsGetCurrentContext(); 93 | CGContextSetFillColorWithColor(context, [color CGColor]); 94 | CGContextFillRect(context, rect); 95 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 96 | UIGraphicsEndImageContext(); 97 | return image; 98 | } 99 | 100 | - (CGRect)convertRect:(CGRect)rect withContentMode:(UIViewContentMode)contentMode { 101 | CGSize size = self.size; 102 | rect = CGRectStandardize(rect); 103 | size.width = size.width < 0 ? -size.width : size.width; 104 | size.height = size.height < 0 ? -size.height : size.height; 105 | CGPoint center = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); 106 | switch (contentMode) { 107 | case UIViewContentModeRedraw: 108 | case UIViewContentModeScaleAspectFit: 109 | case UIViewContentModeScaleAspectFill: { 110 | if (rect.size.width < 0.01 || rect.size.height < 0.01 || 111 | size.width < 0.01 || size.height < 0.01) { 112 | rect.origin = center; 113 | rect.size = CGSizeZero; 114 | } else { 115 | CGFloat scale; 116 | if (contentMode == UIViewContentModeScaleAspectFill) { 117 | if (size.width / size.height < rect.size.width / rect.size.height) { 118 | scale = rect.size.width / size.width; 119 | } else { 120 | scale = rect.size.height / size.height; 121 | } 122 | } else { 123 | if (size.width / size.height < rect.size.width / rect.size.height) { 124 | scale = rect.size.height / size.height; 125 | } else { 126 | scale = rect.size.width / size.width; 127 | } 128 | } 129 | size.width *= scale; 130 | size.height *= scale; 131 | rect.size = size; 132 | rect.origin = CGPointMake(center.x - size.width * 0.5, center.y - size.height * 0.5); 133 | } 134 | } break; 135 | case UIViewContentModeCenter: { 136 | rect.size = size; 137 | rect.origin = CGPointMake(center.x - size.width * 0.5, center.y - size.height * 0.5); 138 | } break; 139 | case UIViewContentModeTop: { 140 | rect.origin.x = center.x - size.width * 0.5; 141 | rect.size = size; 142 | } break; 143 | case UIViewContentModeBottom: { 144 | rect.origin.x = center.x - size.width * 0.5; 145 | rect.origin.y += rect.size.height - size.height; 146 | rect.size = size; 147 | } break; 148 | case UIViewContentModeLeft: { 149 | rect.origin.y = center.y - size.height * 0.5; 150 | rect.size = size; 151 | } break; 152 | case UIViewContentModeRight: { 153 | rect.origin.y = center.y - size.height * 0.5; 154 | rect.origin.x += rect.size.width - size.width; 155 | rect.size = size; 156 | } break; 157 | case UIViewContentModeTopLeft: { 158 | rect.size = size; 159 | } break; 160 | case UIViewContentModeTopRight: { 161 | rect.origin.x += rect.size.width - size.width; 162 | rect.size = size; 163 | } break; 164 | case UIViewContentModeBottomLeft: { 165 | rect.origin.y += rect.size.height - size.height; 166 | rect.size = size; 167 | } break; 168 | case UIViewContentModeBottomRight: { 169 | rect.origin.x += rect.size.width - size.width; 170 | rect.origin.y += rect.size.height - size.height; 171 | rect.size = size; 172 | } break; 173 | case UIViewContentModeScaleToFill: 174 | default: { 175 | rect = rect; 176 | } 177 | } 178 | return rect; 179 | } 180 | 181 | @end 182 | -------------------------------------------------------------------------------- /JMRoundedCorner/UIImageView+JMRadius.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImageView+JMRadius.h 3 | // JMRoundedCornerDemo 4 | // 5 | // Created by 饶志臻 on 2016/10/9. 6 | // Copyright © 2016年 饶志臻. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UIImage+JMRadius.h" 11 | 12 | @interface UIImageView (JMRadius) 13 | 14 | /**设置圆角背景图,默认 UIViewContentModeScaleAspectFill 模式*/ 15 | - (void)jm_setImageWithCornerRadius:(CGFloat)radius 16 | imageURL:(NSURL *)imageURL 17 | placeholder:(UIImage *)placeholder 18 | size:(CGSize)size; 19 | 20 | /**设置圆角背景图,默认 UIViewContentModeScaleAspectFill 模式*/ 21 | - (void)jm_setImageWithJMRadius:(JMRadius)radius 22 | imageURL:(NSURL *)imageURL 23 | placeholder:(UIImage *)placeholder 24 | size:(CGSize)size; 25 | 26 | /**设置 contentMode 模式的圆角背景图*/ 27 | - (void)jm_setImageWithCornerRadius:(CGFloat)radius 28 | imageURL:(NSURL *)imageURL 29 | placeholder:(UIImage *)placeholder 30 | contentMode:(UIViewContentMode)contentMode 31 | size:(CGSize)size; 32 | 33 | /**设置 contentMode 模式的圆角背景图*/ 34 | - (void)jm_setImageWithJMRadius:(JMRadius)radius 35 | imageURL:(NSURL *)imageURL 36 | placeholder:(UIImage *)placeholder 37 | contentMode:(UIViewContentMode)contentMode 38 | size:(CGSize)size; 39 | 40 | /**配置所有属性配置圆角背景图*/ 41 | - (void)jm_setImageWithJMRadius:(JMRadius)radius 42 | imageURL:(NSURL *)imageURL 43 | placeholder:(UIImage *)placeholder 44 | borderColor:(UIColor *)borderColor 45 | borderWidth:(CGFloat)borderWidth 46 | backgroundColor:(UIColor *)backgroundColor 47 | contentMode:(UIViewContentMode)contentMode 48 | size:(CGSize)size; 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /JMRoundedCorner/UIImageView+JMRadius.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImageView+JMRadius.m 3 | // JMRoundedCornerDemo 4 | // 5 | // Created by 饶志臻 on 2016/10/9. 6 | // Copyright © 2016年 饶志臻. All rights reserved. 7 | // 8 | 9 | #import "UIImageView+JMRadius.h" 10 | #if __has_include() 11 | #import 12 | #else 13 | #import "UIImageView+YYWebImage.h" 14 | #endif 15 | 16 | @implementation UIImageView (JMRadius) 17 | 18 | - (void)jm_setImageWithCornerRadius:(CGFloat)radius imageURL:(NSURL *)imageURL placeholder:(UIImage *)placeholder size:(CGSize)size { 19 | [self jm_setImageWithJMRadius:JMRadiusMake(radius, radius, radius, radius) imageURL:imageURL placeholder:placeholder borderColor:nil borderWidth:0 backgroundColor:nil contentMode:UIViewContentModeScaleAspectFill size:size]; 20 | } 21 | 22 | - (void)jm_setImageWithJMRadius:(JMRadius)radius imageURL:(NSURL *)imageURL placeholder:(UIImage *)placeholder size:(CGSize)size { 23 | [self jm_setImageWithJMRadius:radius imageURL:imageURL placeholder:placeholder borderColor:nil borderWidth:0 backgroundColor:nil contentMode:UIViewContentModeScaleAspectFill size:size]; 24 | } 25 | 26 | - (void)jm_setImageWithCornerRadius:(CGFloat)radius imageURL:(NSURL *)imageURL placeholder:(UIImage *)placeholder contentMode:(UIViewContentMode)contentMode size:(CGSize)size { 27 | [self jm_setImageWithJMRadius:JMRadiusMake(radius, radius, radius, radius) imageURL:imageURL placeholder:placeholder borderColor:nil borderWidth:0 backgroundColor:nil contentMode:contentMode size:size]; 28 | } 29 | 30 | - (void)jm_setImageWithJMRadius:(JMRadius)radius imageURL:(NSURL *)imageURL placeholder:(UIImage *)placeholder contentMode:(UIViewContentMode)contentMode size:(CGSize)size { 31 | [self jm_setImageWithJMRadius:radius imageURL:imageURL placeholder:placeholder borderColor:nil borderWidth:0 backgroundColor:nil contentMode:contentMode size:size]; 32 | } 33 | 34 | - (void)jm_setImageWithJMRadius:(JMRadius)radius imageURL:(NSURL *)imageURL placeholder:(UIImage *)placeholder borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth backgroundColor:(UIColor *)backgroundColor contentMode:(UIViewContentMode)contentMode size:(CGSize)size { 35 | 36 | NSString *transformKey = [NSString stringWithFormat:@"%@%@%.1f%@%li%@", NSStringFromJMRadius(radius), borderColor.description, borderWidth, backgroundColor.description, (long)contentMode,NSStringFromCGSize(size)]; 37 | NSString *transformImageKey = [[YYWebImageManager sharedManager] cacheKeyForURL:imageURL transformKey:transformKey]; 38 | UIImage *cacheImage = [[YYWebImageManager sharedManager].cache getImageForKey:transformImageKey]; 39 | 40 | if (cacheImage) { 41 | self.image = cacheImage; 42 | return; 43 | } 44 | 45 | NSString *imageKey = [[YYWebImageManager sharedManager] cacheKeyForURL:imageURL transformKey:nil]; 46 | cacheImage = [[YYWebImageManager sharedManager].cache getImageForKey:imageKey]; 47 | 48 | if (cacheImage) { 49 | self.image = [UIImage jm_setJMRadius:radius image:cacheImage size:size borderColor:borderColor borderWidth:borderWidth backgroundColor:backgroundColor withContentMode:contentMode]; 50 | return; 51 | } 52 | 53 | UIImage *placeholderImage; 54 | if (placeholder || borderWidth > 0 || backgroundColor) { 55 | placeholderImage = [[YYWebImageManager sharedManager].cache getImageForKey:transformKey]; 56 | if (!placeholderImage) { 57 | placeholderImage = [UIImage jm_setJMRadius:radius image:placeholder size:size borderColor:borderColor borderWidth:borderWidth backgroundColor:backgroundColor withContentMode:contentMode]; 58 | [[YYWebImageManager sharedManager].cache setImage:placeholderImage forKey:transformKey]; 59 | } 60 | } 61 | 62 | [self yy_setImageWithURL:imageURL placeholder:placeholderImage options:kNilOptions progress:nil transform:^UIImage * _Nullable(UIImage * _Nonnull image, NSURL * _Nonnull url) { 63 | [[YYWebImageManager sharedManager].cache setImage:image forKey:imageKey]; 64 | UIImage *currentImage = [UIImage jm_setJMRadius:radius image:image size:size borderColor:borderColor borderWidth:borderWidth backgroundColor:backgroundColor withContentMode:contentMode]; 65 | return currentImage; 66 | } transformKey:transformKey completion:^(UIImage * _Nullable image, NSURL * _Nonnull url, YYWebImageFromType from, YYWebImageStage stage, NSError * _Nullable error) { 67 | }]; 68 | } 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /JMRoundedCorner/UIView+JMRadius.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+RoundedCorner.h 3 | // UIImageRoundedCornerDemo 4 | // 5 | // Created by jm on 16/2/25. 6 | // Copyright © 2016年 Jim. All rights reserved. 7 | // 8 | //使用这个类就可以了 9 | 10 | #import 11 | #import "UIImage+JMRadius.h" 12 | 13 | @interface UIView (RoundedCorner) 14 | 15 | typedef void (^JMRoundedCornerCompletionBlock)(UIImage * image); 16 | 17 | /**设置圆角背景图,默认 UIViewContentModeScaleAspectFill 模式*/ 18 | - (void)jm_setImageWithCornerRadius:(CGFloat)radius 19 | image:(UIImage *)image; 20 | 21 | /**设置圆角背景图,默认 UIViewContentModeScaleAspectFill 模式*/ 22 | - (void)jm_setImageWithJMRadius:(JMRadius)radius 23 | image:(UIImage *)image; 24 | 25 | /**设置 contentMode 模式的圆角背景图*/ 26 | - (void)jm_setImageWithCornerRadius:(CGFloat)radius 27 | image:(UIImage *)image 28 | contentMode:(UIViewContentMode)contentMode; 29 | 30 | /**设置 contentMode 模式的圆角背景图*/ 31 | - (void)jm_setImageWithJMRadius:(JMRadius)radius 32 | image:(UIImage *)image 33 | contentMode:(UIViewContentMode)contentMode; 34 | 35 | /**设置圆角边框*/ 36 | - (void)jm_setImageWithCornerRadius:(CGFloat)radius 37 | borderColor:(UIColor *)borderColor 38 | borderWidth:(CGFloat)borderWidth 39 | backgroundColor:(UIColor *)backgroundColor; 40 | 41 | /**设置圆角边框*/ 42 | - (void)jm_setImageWithJMRadius:(JMRadius)radius 43 | borderColor:(UIColor *)borderColor 44 | borderWidth:(CGFloat)borderWidth 45 | backgroundColor:(UIColor *)backgroundColor; 46 | 47 | /**配置所有属性配置圆角背景图*/ 48 | - (void)jm_setImageWithJMRadius:(JMRadius)radius 49 | image:(UIImage *)image 50 | borderColor:(UIColor *)borderColor 51 | borderWidth:(CGFloat)borderWidth 52 | backgroundColor:(UIColor *)backgroundColor 53 | contentMode:(UIViewContentMode)contentMode; 54 | 55 | /**配置所有属性配置圆角背景图*/ 56 | - (void)jm_setImageWithJMRadius:(JMRadius)radius 57 | image:(UIImage *)image 58 | borderColor:(UIColor *)borderColor 59 | borderWidth:(CGFloat)borderWidth 60 | backgroundColor:(UIColor *)backgroundColor 61 | contentMode:(UIViewContentMode)contentMode 62 | size:(CGSize)size 63 | forState:(UIControlState)state 64 | completion:(JMRoundedCornerCompletionBlock)completion; 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /JMRoundedCorner/UIView+JMRadius.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+RoundedCorner.m 3 | // UIImageRoundedCornerDemo 4 | // 5 | // Created by jm on 16/2/25. 6 | // Copyright © 2016年 Jim. All rights reserved. 7 | // 8 | 9 | #import "UIView+JMRadius.h" 10 | #import 11 | 12 | static NSOperationQueue *jm_operationQueue; 13 | static char jm_operationKey; 14 | 15 | @implementation UIView (RoundedCorner) 16 | 17 | - (void)jm_setImageWithCornerRadius:(CGFloat)radius image:(UIImage *)image { 18 | [self jm_setImageWithCornerRadius:radius image:image borderColor:nil borderWidth:0 backgroundColor:nil contentMode:UIViewContentModeScaleAspectFill]; 19 | } 20 | 21 | - (void)jm_setImageWithJMRadius:(JMRadius)radius image:(UIImage *)image { 22 | [self jm_setImageWithJMRadius:radius image:image borderColor:nil borderWidth:0 backgroundColor:nil contentMode:UIViewContentModeScaleAspectFill]; 23 | } 24 | 25 | - (void)jm_setImageWithCornerRadius:(CGFloat)radius image:(UIImage *)image contentMode:(UIViewContentMode)contentMode { 26 | [self jm_setImageWithCornerRadius:radius image:image borderColor:nil borderWidth:0 backgroundColor:nil contentMode:contentMode]; 27 | } 28 | 29 | - (void)jm_setImageWithJMRadius:(JMRadius)radius image:(UIImage *)image contentMode:(UIViewContentMode)contentMode { 30 | [self jm_setImageWithJMRadius:radius image:image borderColor:nil borderWidth:0 backgroundColor:nil contentMode:contentMode]; 31 | } 32 | 33 | - (void)jm_setImageWithCornerRadius:(CGFloat)radius borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth backgroundColor:(UIColor *)backgroundColor { 34 | [self jm_setImageWithCornerRadius:radius image:nil borderColor:borderColor borderWidth:borderWidth backgroundColor:backgroundColor contentMode:UIViewContentModeScaleAspectFill]; 35 | } 36 | 37 | - (void)jm_setImageWithJMRadius:(JMRadius)radius borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth backgroundColor:(UIColor *)backgroundColor { 38 | [self jm_setImageWithJMRadius:radius image:nil borderColor:borderColor borderWidth:borderWidth backgroundColor:backgroundColor contentMode:UIViewContentModeScaleAspectFill]; 39 | } 40 | 41 | - (void)jm_setImageWithCornerRadius:(CGFloat)radius image:(UIImage *)image borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth backgroundColor:(UIColor *)backgroundColor contentMode:(UIViewContentMode)contentMode { 42 | [self jm_setImageWithJMRadius:JMRadiusMake(radius, radius, radius, radius) image:image borderColor:borderColor borderWidth:borderWidth backgroundColor:backgroundColor contentMode:contentMode]; 43 | } 44 | 45 | + (void)load { 46 | jm_operationQueue = [[NSOperationQueue alloc] init]; 47 | } 48 | 49 | - (NSOperation *)jm_getOperation { 50 | id operation = objc_getAssociatedObject(self, &jm_operationKey); 51 | return operation; 52 | } 53 | 54 | - (void)jm_setImageWithOperation:(NSOperation *)operation { 55 | objc_setAssociatedObject(self, &jm_operationKey, operation, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 56 | } 57 | 58 | - (void)jm_cancelOperation { 59 | NSOperation *operation = [self jm_getOperation]; 60 | [operation cancel]; 61 | [self jm_setImageWithOperation:nil]; 62 | } 63 | 64 | - (void)jm_setImageWithJMRadius:(JMRadius)radius image:(UIImage *)image borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth backgroundColor:(UIColor *)backgroundColor contentMode:(UIViewContentMode)contentMode { 65 | [self jm_cancelOperation]; 66 | 67 | [self jm_setImageWithJMRadius:radius image:image borderColor:borderColor borderWidth:borderWidth backgroundColor:backgroundColor contentMode:contentMode size:CGSizeZero forState:UIControlStateNormal completion:nil]; 68 | } 69 | 70 | - (void)jm_setImageWithJMRadius:(JMRadius)radius image:(UIImage *)image borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth backgroundColor:(UIColor *)backgroundColor contentMode:(UIViewContentMode)contentMode size:(CGSize)size forState:(UIControlState)state completion:(JMRoundedCornerCompletionBlock)completion { 71 | 72 | __block CGSize _size = size; 73 | 74 | __weak typeof(self) weakSelf = self; 75 | NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{ 76 | 77 | if ([[weakSelf jm_getOperation] isCancelled]) return; 78 | 79 | if (CGSizeEqualToSize(_size, CGSizeZero)) { 80 | dispatch_sync(dispatch_get_main_queue(), ^{ 81 | _size = weakSelf.bounds.size; 82 | }); 83 | } 84 | CGSize pixelSize = CGSizeMake(pixel(_size.width), pixel(_size.height)); 85 | UIImage *currentImage = [UIImage jm_setJMRadius:radius image:(UIImage *)image size:pixelSize borderColor:borderColor borderWidth:borderWidth backgroundColor:backgroundColor withContentMode:contentMode]; 86 | 87 | [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 88 | __strong typeof(weakSelf) self = weakSelf; 89 | if ([[self jm_getOperation] isCancelled]) return; 90 | self.frame = CGRectMake(pixel(self.frame.origin.x), pixel(self.frame.origin.y), pixelSize.width, pixelSize.height); 91 | if ([self isKindOfClass:[UIImageView class]]) { 92 | ((UIImageView *)self).image = currentImage; 93 | } else if ([self isKindOfClass:[UIButton class]] && image) { 94 | [((UIButton *)self) setBackgroundImage:currentImage forState:state]; 95 | } else if ([self isKindOfClass:[UILabel class]]) { 96 | self.layer.backgroundColor = [UIColor colorWithPatternImage:currentImage].CGColor; 97 | } else { 98 | self.layer.contents = (__bridge id _Nullable)(currentImage.CGImage); 99 | } 100 | if (completion) completion(currentImage); 101 | }]; 102 | }]; 103 | 104 | [self jm_setImageWithOperation:blockOperation]; 105 | [jm_operationQueue addOperation:blockOperation]; 106 | } 107 | 108 | static inline CGFloat pixel(CGFloat num) { 109 | CGFloat unit = 1.0 / [UIScreen mainScreen].scale; 110 | CGFloat remain = fmod(num, unit); 111 | return num - remain + (remain >= unit / 2.0? unit: 0); 112 | } 113 | 114 | @end 115 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 饶志臻 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JMRoundedCorner 2 | 3 | [![LICENSE](https://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://raw.githubusercontent.com/raozhizhen/JMRoundedCorner/master/LICENSE)  4 | [![CocoaPods](http://img.shields.io/cocoapods/v/JMRoundedCorner.svg?style=flat)](http://cocoapods.org/?q=JMRoundedCorner)  5 | [![SUPPORT](https://img.shields.io/badge/support-iOS%207%2B%20-blue.svg?style=flat)](https://en.wikipedia.org/wiki/IOS_7)  6 | [![BLOG](https://img.shields.io/badge/blog-raozhizhen.com-orange.svg?style=flat)](http://raozhizhen.com)  7 | 8 | iOS 9.0 之后 UIButton 设置圆角会触发离屏渲染,而 UIImageView 里 png 图片设置圆角不会触发离屏渲染了,所以你还在等什么,上 iOS 9 吧。 9 | 10 | 11 | ## 避免离屏渲染 12 | 13 | 如果你的 view 不需要让子视图超出部分不显示,且不需要给 view 的 image 绘制圆角,可以查看 cornerRadius 属性的注释: 14 | 15 | > By default, the corner radius does not apply to the image in the layer’s contents property; it applies only to the background color and border of the layer. However, setting the masksToBounds property to true causes the content to be clipped to the rounded corners. 16 | 17 | 这个属性会影响 layer 的背景颜色和 border,所以如下代码即可避免离屏渲染。 18 | 19 | ```objc 20 | view.layer.cornerRadius = radius; 21 | view.layer.backgroundColor = backgroundColor.CGColor; 22 | ``` 23 | 24 | 25 | ## 使用 26 | 27 | 在工程的 Podfile 文件中添加如下行: 28 | 29 | ```ruby 30 | pod 'JMRoundedCorner', :git => 'https://github.com/raozhizhen/JMRoundedCorner.git', :tag => '1.9.6' 31 | pod 'YYWebImage', :git => 'https://github.com/raozhizhen/YYWebImage.git', :tag => '1.0.5' 32 | ``` 33 | 34 | 在代码中引入: 35 | 36 | ``` objc 37 | #import 38 | ``` 39 | 40 | 41 | ## 代码示例 42 | 43 | ```objc 44 | [_avatarView jm_setImageWithCornerRadius:10 image:[UIImage imageNamed:@"avatar"]]; 45 | // or 46 | [_avatarView jm_setImageWithCornerRadius:20 imageURL:_avatarURL placeholder:@"avatar" size:CGSizeMake(40, 40)]; 47 | ``` 48 | 49 | 支持通过 JMRadius 设置4个角为不同的弧度,角度优先级为左上 > 右上 > 左下 > 右下: 50 | 51 | ```objc 52 | [_avatarView jm_setImageWithJMRadius:JMRadiusMake(20, 20, 20, 20) 53 | imageURL:_avatarURL 54 | placeholder:@"avatar" 55 | borderColor:[UIColor redColor] 56 | borderWidth:1 57 | backgroundColor:[UIColor blueColor] 58 | contentMode:UIViewContentModeScaleAspectFill 59 | size:CGSizeMake(40, 40)]; 60 | ``` 61 | 62 | 63 | ## 性能上的优缺点 64 | 65 | * 优点:没有了离屏渲染,调整了 image 的像素大小以避免不必要的缩放; 66 | * 缺点:会造成图层混合,且因为只是绘制了一个带圆角的图片,所以不能使子视图超出圆角部分不显示。 67 | 68 | 69 | ## 注意事项 70 | 71 | 内存会持续提升,是正常现象,点击 home 键内存会回到正常水平,并非内存泄漏,只是绘制的缓存,在内存不足时会自动释放。 72 | 73 | 不要设置 view 的 backgroundColor,需要设置的话可以通过带 backgroundColor 参数的接口进行设置,例如: 74 | 75 | ```objc 76 | - (void)jm_setImageWithCornerRadius:(CGFloat)radius 77 | borderColor:(UIColor *)borderColor 78 | borderWidth:(CGFloat)borderWidth 79 | backgroundColor:(UIColor *)backgroundColor; 80 | ``` 81 | 82 | 控制器输出以下错误,这是 Xcode 7 的 [BUG](https://forums.developer.apple.com/thread/13683)。 83 | 84 | ``` 85 | : CGContextSaveGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable. 86 | ``` 87 | 88 | ## 更新日志 89 | 90 | * 2016/10/10 1.9.0 版本: 依赖 **[YYWebImage](https://github.com/ibireme/YYWebImage)** 实现网络图片圆角处理和圆角图片缓存。 91 | * 2016/4/25 1.2.1 版本: 使用 NSOperationQueue 代替 dispatch_queue,当重复设置圆角的时候会自动 cancel 上一次操作,感谢 **[kudocc](https://github.com/kudocc)** 的 pull request。 92 | * 2016/3/12 1.1.0 版本: 接口带上了 jm_ 前缀,JMRadius 添加圆角优先级。 93 | * 2016/3/3 1.0.3 版本: 修复 label 里如果没有汉字,文字就不显示的 BUG,以及做了使 view 落在像素点上的优化。 94 | * 2016/2/28 1.0.0 版本:发布正式版本。 95 | * 2016/2/26 0.0.4 版本:去掉了 size 参数及支持 JMRadius 设置4个角为不同的弧度。 96 | * 2016/2/25 0.0.3 版本:去掉了 UIImageView 这个中间控件。 97 | * 2016/2/24 0.0.2 版本:支持设置背景图片的绘制模式(cotentmode)。 98 | * 2016/2/23 0.0.1 版本:绘制一个圆角 image。 99 | 100 | 101 | ## 感谢 102 | 103 | * [reviewcode.cn](http://www.reviewcode.cn/article.html?reviewId=7) 104 | * [Getting Pixels Onto the Screen](https://www.objc.io/issues/3-views/moving-pixels-onto-the-screen/) 105 | 106 | 107 | ## 联系我 108 | 109 | * QQ:337519524 110 | * 邮箱:raozhizhen@gmail.com 111 | 112 | 113 | ## 许可证 114 | 115 | JMRoundedCorner 使用 MIT 许可证,详情见 LICENSE 文件。 116 | --------------------------------------------------------------------------------