├── .gitattributes ├── .gitignore ├── AutoLayout进阶(一)Aspect Ratio ├── AutoLayout进阶(一)Aspect Ratio.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata └── AutoLayout进阶(一)Aspect Ratio │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── ViewController.h │ ├── ViewController.m │ ├── image1.jpeg │ └── main.m ├── AutoLayout进阶(三)Content Compression Resistance Priority ├── AutoLayout进阶(三)Content Compression Resistance Priority.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata └── AutoLayout进阶(三)Content Compression Resistance Priority │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── ViewController.h │ ├── ViewController.m │ └── main.m ├── AutoLayout进阶(二)Content Hugging Priority ├── AutoLayout进阶(二)Content Hugging Priority.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata └── AutoLayout进阶(二)Content Hugging Priority │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── ViewController.h │ ├── ViewController.m │ └── main.m ├── AutoLayout进阶(五)UITableViewCell自动高度 ├── AutoLayout进阶(五)UITableViewCell自动高度.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata └── AutoLayout进阶(五)UITableViewCell自动高度 │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Classes │ ├── DemoCell.h │ ├── DemoCell.m │ ├── DemoCell.xib │ ├── DemoModel.h │ ├── DemoModel.m │ ├── ViewController.h │ ├── ViewController.m │ └── demo.json │ ├── Info.plist │ ├── Vendor │ ├── JPFPSStatus │ │ ├── JPFPSStatus.h │ │ └── JPFPSStatus.m │ ├── SDWebImage │ │ ├── MKAnnotationView+WebCache.h │ │ ├── MKAnnotationView+WebCache.m │ │ ├── NSData+ImageContentType.h │ │ ├── NSData+ImageContentType.m │ │ ├── NSImage+WebCache.h │ │ ├── NSImage+WebCache.m │ │ ├── SDImageCache.h │ │ ├── SDImageCache.m │ │ ├── SDImageCacheConfig.h │ │ ├── SDImageCacheConfig.m │ │ ├── SDWebImageCoder.h │ │ ├── SDWebImageCoder.m │ │ ├── SDWebImageCodersManager.h │ │ ├── SDWebImageCodersManager.m │ │ ├── SDWebImageCompat.h │ │ ├── SDWebImageCompat.m │ │ ├── SDWebImageDownloader.h │ │ ├── SDWebImageDownloader.m │ │ ├── SDWebImageDownloaderOperation.h │ │ ├── SDWebImageDownloaderOperation.m │ │ ├── SDWebImageGIFCoder.h │ │ ├── SDWebImageGIFCoder.m │ │ ├── SDWebImageImageIOCoder.h │ │ ├── SDWebImageImageIOCoder.m │ │ ├── SDWebImageManager.h │ │ ├── SDWebImageManager.m │ │ ├── SDWebImageOperation.h │ │ ├── SDWebImagePrefetcher.h │ │ ├── SDWebImagePrefetcher.m │ │ ├── SDWebImageWebPCoder.h │ │ ├── SDWebImageWebPCoder.m │ │ ├── UIButton+WebCache.h │ │ ├── UIButton+WebCache.m │ │ ├── UIImage+ForceDecode.h │ │ ├── UIImage+ForceDecode.m │ │ ├── UIImage+GIF.h │ │ ├── UIImage+GIF.m │ │ ├── UIImage+MultiFormat.h │ │ ├── UIImage+MultiFormat.m │ │ ├── UIImage+WebP.h │ │ ├── UIImage+WebP.m │ │ ├── UIImageView+HighlightedWebCache.h │ │ ├── UIImageView+HighlightedWebCache.m │ │ ├── UIImageView+WebCache.h │ │ ├── UIImageView+WebCache.m │ │ ├── UIView+WebCache.h │ │ ├── UIView+WebCache.m │ │ ├── UIView+WebCacheOperation.h │ │ └── UIView+WebCacheOperation.m │ └── YYModel │ │ ├── NSObject+YYModel.h │ │ ├── NSObject+YYModel.m │ │ ├── YYClassInfo.h │ │ ├── YYClassInfo.m │ │ └── YYModel.h │ └── main.m ├── AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用 ├── AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata └── AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用 │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── ViewController.h │ ├── ViewController.m │ ├── icon.jpeg │ └── main.m ├── LICENSE └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | # CocoaPods 32 | # 33 | # We recommend against adding the Pods directory to your .gitignore. However 34 | # you should judge for yourself, the pros and cons are mentioned at: 35 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 36 | # 37 | # Pods/ 38 | 39 | # Carthage 40 | # 41 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 42 | # Carthage/Checkouts 43 | 44 | Carthage/Build 45 | 46 | # fastlane 47 | # 48 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 49 | # screenshots whenever they are needed. 50 | # For more information about the recommended setup visit: 51 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 52 | 53 | fastlane/report.xml 54 | fastlane/Preview.html 55 | fastlane/screenshots 56 | fastlane/test_output 57 | 58 | # Code Injection 59 | # 60 | # After new code Injection tools there's a generated folder /iOSInjectionProject 61 | # https://github.com/johnno1962/injectionforxcode 62 | 63 | iOSInjectionProject/ 64 | -------------------------------------------------------------------------------- /AutoLayout进阶(一)Aspect Ratio/AutoLayout进阶(一)Aspect Ratio.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /AutoLayout进阶(一)Aspect Ratio/AutoLayout进阶(一)Aspect Ratio/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // AutoLayout进阶(一)Aspect Ratio 4 | // 5 | // Created by zhuxiaohui on 2017/11/18. 6 | // Copyright © 2017年 com.it7090. All rights reserved. 7 | // https://github.com/CoderZhuXH/AutoLayout 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /AutoLayout进阶(一)Aspect Ratio/AutoLayout进阶(一)Aspect Ratio/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // AutoLayout进阶(一)Aspect Ratio 4 | // 5 | // Created by zhuxiaohui on 2017/11/18. 6 | // Copyright © 2017年 com.it7090. All rights reserved. 7 | // https://github.com/CoderZhuXH/AutoLayout 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /AutoLayout进阶(一)Aspect Ratio/AutoLayout进阶(一)Aspect Ratio/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /AutoLayout进阶(一)Aspect Ratio/AutoLayout进阶(一)Aspect Ratio/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 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /AutoLayout进阶(一)Aspect Ratio/AutoLayout进阶(一)Aspect Ratio/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 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /AutoLayout进阶(一)Aspect Ratio/AutoLayout进阶(一)Aspect Ratio/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /AutoLayout进阶(一)Aspect Ratio/AutoLayout进阶(一)Aspect Ratio/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // AutoLayout进阶(一)Aspect Ratio 4 | // 5 | // Created by zhuxiaohui on 2017/11/18. 6 | // Copyright © 2017年 com.it7090. All rights reserved. 7 | // https://github.com/CoderZhuXH/AutoLayout 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /AutoLayout进阶(一)Aspect Ratio/AutoLayout进阶(一)Aspect Ratio/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // AutoLayout进阶(一)Aspect Ratio 4 | // 5 | // Created by zhuxiaohui on 2017/11/18. 6 | // Copyright © 2017年 com.it7090. All rights reserved. 7 | // https://github.com/CoderZhuXH/AutoLayout 8 | 9 | #import "ViewController.h" 10 | 11 | static CGFloat changeValue = -18;//记录变化值 12 | 13 | @interface ViewController () 14 | @property (weak, nonatomic) IBOutlet UIImageView *imgView; 15 | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *imgViewWidth; 16 | @end 17 | 18 | @implementation ViewController 19 | 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | 23 | [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(action) userInfo:nil repeats:YES]; 24 | } 25 | 26 | -(void)action{ 27 | _imgViewWidth.constant += changeValue; 28 | if(_imgViewWidth.constant<=150){//最小宽度 29 | changeValue = 18; 30 | }else if(_imgViewWidth.constant>320){//最大宽度 31 | changeValue = -18;; 32 | } 33 | } 34 | 35 | - (void)didReceiveMemoryWarning { 36 | [super didReceiveMemoryWarning]; 37 | // Dispose of any resources that can be recreated. 38 | } 39 | 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /AutoLayout进阶(一)Aspect Ratio/AutoLayout进阶(一)Aspect Ratio/image1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderZhuXH/AutoLayout/ee78cf85c2ff608c7d53db1793d8bd3b77861e8e/AutoLayout进阶(一)Aspect Ratio/AutoLayout进阶(一)Aspect Ratio/image1.jpeg -------------------------------------------------------------------------------- /AutoLayout进阶(一)Aspect Ratio/AutoLayout进阶(一)Aspect Ratio/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // AutoLayout进阶(一)Aspect Ratio 4 | // 5 | // Created by zhuxiaohui on 2017/11/18. 6 | // Copyright © 2017年 com.it7090. 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 | -------------------------------------------------------------------------------- /AutoLayout进阶(三)Content Compression Resistance Priority/AutoLayout进阶(三)Content Compression Resistance Priority.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /AutoLayout进阶(三)Content Compression Resistance Priority/AutoLayout进阶(三)Content Compression Resistance Priority/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // AutoLayout进阶(三)Content Compression Resistance Priority 4 | // 5 | // Created by zhuxiaohui on 2017/11/18. 6 | // Copyright © 2017年 com.it7090. All rights reserved. 7 | // https://github.com/CoderZhuXH/AutoLayout 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /AutoLayout进阶(三)Content Compression Resistance Priority/AutoLayout进阶(三)Content Compression Resistance Priority/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // AutoLayout进阶(三)Content Compression Resistance Priority 4 | // 5 | // Created by zhuxiaohui on 2017/11/18. 6 | // Copyright © 2017年 com.it7090. All rights reserved. 7 | // https://github.com/CoderZhuXH/AutoLayout 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /AutoLayout进阶(三)Content Compression Resistance Priority/AutoLayout进阶(三)Content Compression Resistance Priority/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 | } -------------------------------------------------------------------------------- /AutoLayout进阶(三)Content Compression Resistance Priority/AutoLayout进阶(三)Content Compression Resistance Priority/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 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /AutoLayout进阶(三)Content Compression Resistance Priority/AutoLayout进阶(三)Content Compression Resistance Priority/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 | 34 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /AutoLayout进阶(三)Content Compression Resistance Priority/AutoLayout进阶(三)Content Compression Resistance Priority/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /AutoLayout进阶(三)Content Compression Resistance Priority/AutoLayout进阶(三)Content Compression Resistance Priority/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // AutoLayout进阶(三)Content Compression Resistance Priority 4 | // 5 | // Created by zhuxiaohui on 2017/11/18. 6 | // Copyright © 2017年 com.it7090. All rights reserved. 7 | // https://github.com/CoderZhuXH/AutoLayout 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /AutoLayout进阶(三)Content Compression Resistance Priority/AutoLayout进阶(三)Content Compression Resistance Priority/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // AutoLayout进阶(三)Content Compression Resistance Priority 4 | // 5 | // Created by zhuxiaohui on 2017/11/18. 6 | // Copyright © 2017年 com.it7090. All rights reserved. 7 | // https://github.com/CoderZhuXH/AutoLayout 8 | 9 | #import "ViewController.h" 10 | 11 | @interface ViewController () 12 | 13 | @end 14 | 15 | @implementation ViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view, typically from a nib. 20 | } 21 | 22 | 23 | - (void)didReceiveMemoryWarning { 24 | [super didReceiveMemoryWarning]; 25 | // Dispose of any resources that can be recreated. 26 | } 27 | 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /AutoLayout进阶(三)Content Compression Resistance Priority/AutoLayout进阶(三)Content Compression Resistance Priority/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // AutoLayout进阶(三)Content Compression Resistance Priority 4 | // 5 | // Created by zhuxiaohui on 2017/11/18. 6 | // Copyright © 2017年 com.it7090. 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 | -------------------------------------------------------------------------------- /AutoLayout进阶(二)Content Hugging Priority/AutoLayout进阶(二)Content Hugging Priority.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /AutoLayout进阶(二)Content Hugging Priority/AutoLayout进阶(二)Content Hugging Priority/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // AutoLayout进阶(二)Content Hugging Priority 4 | // 5 | // Created by zhuxiaohui on 2017/11/18. 6 | // Copyright © 2017年 com.it7090. All rights reserved. 7 | // https://github.com/CoderZhuXH/AutoLayout 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /AutoLayout进阶(二)Content Hugging Priority/AutoLayout进阶(二)Content Hugging Priority/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // AutoLayout进阶(二)Content Hugging Priority 4 | // 5 | // Created by zhuxiaohui on 2017/11/18. 6 | // Copyright © 2017年 com.it7090. All rights reserved. 7 | // https://github.com/CoderZhuXH/AutoLayout 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /AutoLayout进阶(二)Content Hugging Priority/AutoLayout进阶(二)Content Hugging Priority/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 | } -------------------------------------------------------------------------------- /AutoLayout进阶(二)Content Hugging Priority/AutoLayout进阶(二)Content Hugging Priority/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 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /AutoLayout进阶(二)Content Hugging Priority/AutoLayout进阶(二)Content Hugging Priority/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 | 28 | 35 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /AutoLayout进阶(二)Content Hugging Priority/AutoLayout进阶(二)Content Hugging Priority/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /AutoLayout进阶(二)Content Hugging Priority/AutoLayout进阶(二)Content Hugging Priority/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // AutoLayout进阶(二)Content Hugging Priority 4 | // 5 | // Created by zhuxiaohui on 2017/11/18. 6 | // Copyright © 2017年 com.it7090. All rights reserved. 7 | // https://github.com/CoderZhuXH/AutoLayout 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /AutoLayout进阶(二)Content Hugging Priority/AutoLayout进阶(二)Content Hugging Priority/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // AutoLayout进阶(二)Content Hugging Priority 4 | // 5 | // Created by zhuxiaohui on 2017/11/18. 6 | // Copyright © 2017年 com.it7090. All rights reserved. 7 | // https://github.com/CoderZhuXH/AutoLayout 8 | 9 | #import "ViewController.h" 10 | 11 | @interface ViewController () 12 | 13 | @end 14 | 15 | @implementation ViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view, typically from a nib. 20 | } 21 | 22 | 23 | - (void)didReceiveMemoryWarning { 24 | [super didReceiveMemoryWarning]; 25 | // Dispose of any resources that can be recreated. 26 | } 27 | 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /AutoLayout进阶(二)Content Hugging Priority/AutoLayout进阶(二)Content Hugging Priority/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // AutoLayout进阶(二)Content Hugging Priority 4 | // 5 | // Created by zhuxiaohui on 2017/11/18. 6 | // Copyright © 2017年 com.it7090. 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 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // AutoLayout进阶(五)UITableViewCell自动高度 4 | // 5 | // Created by zhuxiaohui on 2017/11/22. 6 | // Copyright © 2017年 com.it7090. 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 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // AutoLayout进阶(五)UITableViewCell自动高度 4 | // 5 | // Created by zhuxiaohui on 2017/11/22. 6 | // Copyright © 2017年 com.it7090. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "JPFPSStatus.h" 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 20 | // Override point for customization after application launch. 21 | 22 | #if defined(DEBUG)||defined(_DEBUG) 23 | [[JPFPSStatus sharedInstance] open]; 24 | #endif 25 | 26 | return YES; 27 | } 28 | 29 | 30 | - (void)applicationWillResignActive:(UIApplication *)application { 31 | // 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. 32 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 33 | } 34 | 35 | 36 | - (void)applicationDidEnterBackground:(UIApplication *)application { 37 | // 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. 38 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 39 | } 40 | 41 | 42 | - (void)applicationWillEnterForeground:(UIApplication *)application { 43 | // 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. 44 | } 45 | 46 | 47 | - (void)applicationDidBecomeActive:(UIApplication *)application { 48 | // 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. 49 | } 50 | 51 | 52 | - (void)applicationWillTerminate:(UIApplication *)application { 53 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 54 | } 55 | 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/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 | } -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/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 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/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 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Classes/DemoCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // DemoCell.h 3 | // AutoLayout进阶(五)UITableViewCell自动高度 4 | // 5 | // Created by zhuxiaohui on 2017/11/22. 6 | // Copyright © 2017年 com.it7090. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DemoModel.h" 11 | @interface DemoCell : UITableViewCell 12 | 13 | @property (nonatomic, strong) DemoModel *model; 14 | @end 15 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Classes/DemoCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // DemoCell.m 3 | // AutoLayout进阶(五)UITableViewCell自动高度 4 | // 5 | // Created by zhuxiaohui on 2017/11/22. 6 | // Copyright © 2017年 com.it7090. All rights reserved. 7 | // 8 | 9 | #import "DemoCell.h" 10 | #import "UIImageView+WebCache.h" 11 | 12 | @interface DemoCell() 13 | @property (weak, nonatomic) IBOutlet UIImageView *iconView; 14 | @property (weak, nonatomic) IBOutlet UILabel *nameLab; 15 | @property (weak, nonatomic) IBOutlet UILabel *timeLab; 16 | @property (weak, nonatomic) IBOutlet UILabel *titleLab; 17 | @property (weak, nonatomic) IBOutlet UILabel *contentLab; 18 | @property (weak, nonatomic) IBOutlet UILabel *commentLab; 19 | @property (weak, nonatomic) IBOutlet UILabel *praiseLab; 20 | 21 | @end 22 | 23 | @implementation DemoCell 24 | 25 | - (void)awakeFromNib { 26 | [super awakeFromNib]; 27 | 28 | // Initialization code 29 | } 30 | 31 | -(void)setModel:(DemoModel *)model{ 32 | _model = model; 33 | 34 | [_iconView sd_setImageWithURL:[NSURL URLWithString:model.icon]]; 35 | _nameLab.text = model.name; 36 | _timeLab.text = model.update_time; 37 | _contentLab.text = model.brief; 38 | _titleLab.text = model.title; 39 | _commentLab.text = [NSString stringWithFormat:@"%ld评论",model.comment]; 40 | _praiseLab.text = [NSString stringWithFormat:@"%ld赞",model.praise]; 41 | 42 | 43 | for (int i = 0; i<3; i++) { 44 | UIImageView *imgView = [self viewWithTag:10+i]; 45 | imgView.image = nil; 46 | } 47 | for (int i = 0; i 10 | 11 | @interface DemoModel : NSObject 12 | @property (nonatomic, copy) NSString *brief; 13 | @property (nonatomic, copy) NSString *update_time; 14 | @property (nonatomic, copy) NSString *title; 15 | @property (nonatomic, copy) NSString *cate_name; 16 | @property (nonatomic, copy) NSString *icon; 17 | @property (nonatomic, assign) NSInteger praise; 18 | @property (nonatomic, assign) NSInteger comment; 19 | @property (nonatomic, copy) NSString *name; 20 | @property (nonatomic, strong) NSArray *images; 21 | @end 22 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Classes/DemoModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // DemoModel.m 3 | // AutoLayout进阶(五)UITableViewCell自动高度 4 | // 5 | // Created by zhuxiaohui on 2017/11/27. 6 | // Copyright © 2017年 com.it7090. All rights reserved. 7 | // 8 | 9 | #import "DemoModel.h" 10 | 11 | @implementation DemoModel 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Classes/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // AutoLayout进阶(五)UITableViewCell自动高度 4 | // 5 | // Created by zhuxiaohui on 2017/11/22. 6 | // Copyright © 2017年 com.it7090. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Classes/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // AutoLayout进阶(五)UITableViewCell自动高度 4 | // 5 | // Created by zhuxiaohui on 2017/11/22. 6 | // Copyright © 2017年 com.it7090. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "DemoModel.h" 11 | #import "YYModel.h" 12 | #import "DemoCell.h" 13 | #import "JPFPSStatus.h" 14 | 15 | 16 | static NSString *const id_DemoCell = @"DemoCell"; 17 | 18 | @interface ViewController () 19 | @property (nonatomic, strong) NSArray *dataArray; 20 | @property (nonatomic, strong) UITableView *tableView; 21 | 22 | @end 23 | 24 | @implementation ViewController 25 | 26 | - (void)viewDidLoad { 27 | [super viewDidLoad]; 28 | 29 | [self.view addSubview:self.tableView]; 30 | 31 | [self.tableView registerNib:[UINib nibWithNibName:id_DemoCell bundle:nil] forCellReuseIdentifier:id_DemoCell]; 32 | 33 | /** FPS */ 34 | [[JPFPSStatus sharedInstance] openWithHandler:^(NSInteger fpsValue) { 35 | NSLog(@"FPS = %ld" ,fpsValue); 36 | }]; 37 | 38 | } 39 | 40 | #pragma mark - tableView 41 | -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 42 | { 43 | return self.dataArray.count; 44 | } 45 | 46 | -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 47 | { 48 | DemoCell *cell = [tableView dequeueReusableCellWithIdentifier:id_DemoCell]; 49 | if (!cell) { 50 | cell = [[DemoCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:id_DemoCell]; 51 | } 52 | cell.selectionStyle = UITableViewCellSelectionStyleNone; 53 | DemoModel *model = self.dataArray[indexPath.row]; 54 | cell.model = model; 55 | return cell; 56 | } 57 | #pragma mark - lazy 58 | -(UITableView *)tableView{ 59 | if(!_tableView){ 60 | _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height) style:UITableViewStylePlain]; 61 | _tableView.delegate = self; 62 | _tableView.dataSource = self; 63 | _tableView.estimatedRowHeight = 250; 64 | _tableView.rowHeight = UITableViewAutomaticDimension; 65 | 66 | } 67 | return _tableView; 68 | } 69 | 70 | 71 | /** 从文件加载数据 */ 72 | -(NSArray *)dataArray{ 73 | if(!_dataArray){ 74 | NSString *path = [[NSBundle mainBundle] pathForResource:@"demo" ofType:@"json"]; 75 | NSDictionary *json = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfFile:path] options:0 error:nil]; 76 | _dataArray = [NSArray yy_modelArrayWithClass:[DemoModel class] json:json[@"data"]]; 77 | } 78 | return _dataArray; 79 | } 80 | - (void)didReceiveMemoryWarning { 81 | [super didReceiveMemoryWarning]; 82 | // Dispose of any resources that can be recreated. 83 | } 84 | 85 | 86 | @end 87 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Classes/demo.json: -------------------------------------------------------------------------------- 1 | { 2 | "status" : 200, 3 | "message" : "", 4 | "data" : [ 5 | { 6 | "brief" : "我觉得手机摄影要高大上,挖掘自己喜欢的题材非常重要。不要去模仿知乎或者instagram上热门的题材和风格,觉得一定要带点胶片的褪色感,一定要拍出对称的结构或者华丽的光影才高大上。手机摄影的潜力是巨大的,但你首先要忠于自己的感受?一味地模仿会限制你自己的感知力和创造力,最终风格固化,题材单一,失去激情,这比照片一时半会儿看起来low一点,更要命", 7 | "update_time" : "2017-07-20", 8 | "id" : "176", 9 | "title" : "手机摄影如何拍出高大上的感觉,老是想拍出那种感觉,但是往往就是效果不够好,有什么建议?", 10 | "images":["http://p3.pstatp.com/large/4a3400003b44cdf18f8f","http://p3.pstatp.com/large/4a3500003b3237592583","http://p3.pstatp.com/large/4750000702115ccba293"], 11 | "cate_name" : "数码", 12 | "icon" : "http://p3.pstatp.com/thumb/24980004368bcd3e07ba", 13 | "praise" : "206", 14 | "comment":"1003", 15 | "name":"我爱宅基地很犀利的基地9527" 16 | }, 17 | { 18 | "brief" : "这款手机已经完全失去了性价比,一个满血的960在gpu和基带方面都和820有差距,别说是残血的了,2999这个价位可以选的骁龙652 653的现货手机一大把一大把,颜值未必比荣耀差", 19 | "update_time" : "2017-01-14", 20 | "id" : "567", 21 | "title" : "今天荣耀v9又被秒空了,但是黄牛却抢到了,那么是不是黄牛会囤货到下半年?", 22 | "images":["http://p9.pstatp.com/large/18a200026ef750731290"], 23 | "cate_name" : "数码", 24 | "icon" : "http://p3.pstatp.com/thumb/97d000b5359c303705e", 25 | "praise" : "1234", 26 | "comment":"7683", 27 | "name":"搞机新视角" 28 | }, 29 | { 30 | "brief" : "自己是07年接触森海这个品牌,因为接触这个牌子,也知道产业内比较有口碑的品牌也就是森海,AKG,BOSE,铁三角,索大好,拜亚动力,舒尔,国产的话算有漫步者和硕美科(硕美科感觉听音乐不咋地,玩游戏还可以)吧。漫步者和硕美科不太熟不说,国外的这几个品牌各个价位的产品都有,为什么好多“专业”推荐耳机的文章都避开这些品牌,然后又说那些耳机效果是怎么怎么的好?", 31 | "update_time" : "2017-01-14", 32 | "id" : "145", 33 | "title" : "为什么推荐耳机的文章很少推荐森海,铁三角,索尼这几个牌子?", 34 | "images":["https://p3.pstatp.com/large/13540012dcd344662a77","http://p1.pstatp.com/large/24990005f329bb6bd863","http://p1.pstatp.com/large/16aa001445c6ee98bba3"], 35 | "cate_name" : "数码", 36 | "icon" : "http://p9.pstatp.com/thumb/1bf40002619fed1affcc", 37 | "praise" : "1234", 38 | "comment":"7683", 39 | "name":"就是那片海就是屋前的那片海" 40 | }, 41 | { 42 | "brief" : "格力年终奖手机发放之后,有网友发现在二手电商平台当中出现了多台仅售17XX元的格力手机二代,这个价格还不到官方售价(3599元)的一半!格力电器董明珠对于手机贱卖一事格外看重,董明珠在格力内部发声称“要让这么做的员工再花高价把手机买回来”。?", 43 | "update_time" : "2017-01-14", 44 | "id" : "145", 45 | "title" : "董明珠称要让员工高价赎回闲鱼“贱卖”的格力手机,这事儿你怎么看??", 46 | "images":["https://p3.pstatp.com/large/150d0011502070c03b6b","http://p1.pstatp.com/large/24990005f329bb6bd863"], 47 | "cate_name" : "数码", 48 | "icon" : "http://p3.pstatp.com/thumb/135300136d077ba655b4", 49 | "praise" : "1234", 50 | "comment":"7683", 51 | "name":"往事如意爱迪生" 52 | }, 53 | { 54 | "brief" : "如何用手机把在线视频连到电视上,其实很简单,慢慢看。前提是你用的是智能互联网电视。一般互联网电视上都会装有视频APP,比如说泰捷视频,VST全聚合等资源丰富的电视视频应用?", 55 | "update_time" : "2017-09-23", 56 | "id" : "1423", 57 | "title" : "怎么用手机把在线视频连到电视上看?", 58 | "images":["https://p3.pstatp.com/large/16ab0005d85e5bbb3ec2","http://p3.pstatp.com/large/3ea50000fc65860b4670","http://p3.pstatp.com/large/3ea400076d18e72c3349"], 59 | "cate_name" : "数码", 60 | "icon" : "http://p1.pstatp.com/thumb/46f10001712ad996d699", 61 | "praise" : "2637", 62 | "comment":"567", 63 | "name":"村东一枝花" 64 | }, 65 | { 66 | "brief" : "本人同时有移动联通电信的号码,移动是浙江的号码,现在离开那里了,舍不得换,回来老家办理了电信宽带套餐169的,宽带电话一起用,联通是在支付宝上办理的蚂蚁宝卡,今天刚收到,还没有使用!", 67 | "update_time" : "2017-09-23", 68 | "id" : "1433", 69 | "title" : "同时拥有移动、联通、电信号码是什么体验?", 70 | "images":["https://p3.pstatp.com/origin/3a1e00130653f5b404ba"], 71 | "cate_name" : "数码", 72 | "icon" : "http://p3.pstatp.com/thumb/3e780008bb5e7b9f0d1d", 73 | "praise" : "2637", 74 | "comment":"566", 75 | "name":"商联电子商务" 76 | }, 77 | { 78 | "brief" : "你有没有这样的感觉,现在讲到国产讲到电器都是华为啊联想啊格力啊,但是我记得我家买的第一台冰箱明明是海尔啊。这些年海尔发展的怎么样啊?", 79 | "update_time" : "2017-09-23", 80 | "id" : "1433", 81 | "title" : "为什么现在总听到华为和格力,小时候的海尔干什么去了?", 82 | "images":["https://p3.pstatp.com/large/e5900134a7010f90f85"], 83 | "cate_name" : "数码", 84 | "icon" : "http://p9.pstatp.com/thumb/3222/1284672452", 85 | "praise" : "2637", 86 | "comment":"566", 87 | "name":"海尔官方帐号" 88 | }, 89 | { 90 | "brief" : "我注册了世纪佳缘,经常收到很多女生的私信,但是需要付费才能看,这些可以相信吗?", 91 | "update_time" : "2017-09-27", 92 | "id" : "1433", 93 | "title" : "我注册了世纪佳缘,经常收到很多女生的私信,但是需要付费才能看,这些可以相信吗?", 94 | "images":["https://p3.pstatp.com/large/3a2000164290896d0452"], 95 | "cate_name" : "娱乐", 96 | "icon" : "http://p3.pstatp.com/thumb/2c5e0004aa2326ff3916", 97 | "praise" : "2637", 98 | "comment":"566", 99 | "name":"财智成功" 100 | }, 101 | { 102 | "brief" : "11月22日,科大讯飞南京区域中心落户建邺,布局人工智能产业链 10月24日,创新工场宣布将南京创新工场首期注册资本增加至1000万元。 10月9日,雷军现身南京并宣布小米华东总部落户南京,而未来这里将成为小米手机研发的中心。 加上之前的阿里和京东,为什么互联网大厂都看上了南京?南京会成为下一个互联网中心吗?", 103 | "update_time" : "2017-09-29", 104 | "id" : "1433", 105 | "title" : "为什么阿里、小米、京东,科大讯飞、创新工场都选择在南京建立研发中心?南京会成为下一个互联网中心吗", 106 | "images":["https://p3.pstatp.com/large/4ad00009e6f65e635227","https://p3.pstatp.com/large/4acc001d23313a36318e"], 107 | "cate_name" : "数码", 108 | "icon" : "http://p9.pstatp.com/thumb/9780/4106115658", 109 | "praise" : "1637", 110 | "comment":"5616", 111 | "name":"智能硬件" 112 | } 113 | ], 114 | "url" : "" 115 | } 116 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSAppTransportSecurity 6 | 7 | NSAllowsArbitraryLoads 8 | 9 | 10 | CFBundleDevelopmentRegion 11 | $(DEVELOPMENT_LANGUAGE) 12 | CFBundleExecutable 13 | $(EXECUTABLE_NAME) 14 | CFBundleIdentifier 15 | $(PRODUCT_BUNDLE_IDENTIFIER) 16 | CFBundleInfoDictionaryVersion 17 | 6.0 18 | CFBundleName 19 | $(PRODUCT_NAME) 20 | CFBundlePackageType 21 | APPL 22 | CFBundleShortVersionString 23 | 1.0 24 | CFBundleVersion 25 | 1 26 | LSRequiresIPhoneOS 27 | 28 | UILaunchStoryboardName 29 | LaunchScreen 30 | UIMainStoryboardFile 31 | Main 32 | UIRequiredDeviceCapabilities 33 | 34 | armv7 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/JPFPSStatus/JPFPSStatus.h: -------------------------------------------------------------------------------- 1 | // 2 | // JPFPSStatus.h 3 | // JPFPSStatus 4 | // 5 | // Created by coderyi on 16/6/4. 6 | // Copyright © 2016年 http://coderyi.com . All rights reserved. 7 | // @ https://github.com/joggerplus/JPFPSStatus 8 | 9 | #import 10 | #import 11 | @interface JPFPSStatus : NSObject 12 | 13 | @property (nonatomic,strong)UILabel *fpsLabel; 14 | 15 | + (JPFPSStatus *)sharedInstance; 16 | 17 | - (void)open; 18 | - (void)openWithHandler:(void (^)(NSInteger fpsValue))handler; 19 | - (void)close; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/JPFPSStatus/JPFPSStatus.m: -------------------------------------------------------------------------------- 1 | // 2 | // JPFPSStatus.m 3 | // JPFPSStatus 4 | // 5 | // Created by coderyi on 16/6/4. 6 | // Copyright © 2016年 http://coderyi.com . All rights reserved. 7 | // @ https://github.com/joggerplus/JPFPSStatus 8 | 9 | #import "JPFPSStatus.h" 10 | 11 | @interface JPFPSStatus (){ 12 | CADisplayLink *displayLink; 13 | NSTimeInterval lastTime; 14 | NSUInteger count; 15 | } 16 | @property(nonatomic,copy) void (^fpsHandler)(NSInteger fpsValue); 17 | 18 | @end 19 | 20 | @implementation JPFPSStatus 21 | @synthesize fpsLabel; 22 | 23 | - (void)dealloc { 24 | [displayLink setPaused:YES]; 25 | [displayLink removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; 26 | } 27 | 28 | + (JPFPSStatus *)sharedInstance { 29 | static JPFPSStatus *sharedInstance; 30 | static dispatch_once_t onceToken; 31 | dispatch_once(&onceToken, ^{ 32 | sharedInstance = [[JPFPSStatus alloc] init]; 33 | }); 34 | return sharedInstance; 35 | } 36 | 37 | - (id)init { 38 | self = [super init]; 39 | if (self) { 40 | [[NSNotificationCenter defaultCenter] addObserver: self 41 | selector: @selector(applicationDidBecomeActiveNotification) 42 | name: UIApplicationDidBecomeActiveNotification 43 | object: nil]; 44 | 45 | [[NSNotificationCenter defaultCenter] addObserver: self 46 | selector: @selector(applicationWillResignActiveNotification) 47 | name: UIApplicationWillResignActiveNotification 48 | object: nil]; 49 | 50 | // Track FPS using display link 51 | displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkTick:)]; 52 | [displayLink setPaused:YES]; 53 | [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; 54 | 55 | // fpsLabel 56 | fpsLabel = [[UILabel alloc] initWithFrame:CGRectMake(([[UIScreen mainScreen] bounds].size.width-50)/2+50, 0, 50, 20)]; 57 | BOOL isiPhoneX = (([[UIScreen mainScreen] bounds].size.width == 375.f && [[UIScreen mainScreen] bounds].size.height == 812.f) || ([[UIScreen mainScreen] bounds].size.height == 375.f && [[UIScreen mainScreen] bounds].size.width == 812.f)); 58 | if (isiPhoneX) { 59 | fpsLabel.frame = CGRectMake(([[UIScreen mainScreen] bounds].size.width-50)/2+50, 24, 50, 20); 60 | } 61 | fpsLabel.font=[UIFont boldSystemFontOfSize:12]; 62 | fpsLabel.textColor=[UIColor colorWithRed:0.33 green:0.84 blue:0.43 alpha:1.00]; 63 | fpsLabel.backgroundColor=[UIColor clearColor]; 64 | fpsLabel.textAlignment=NSTextAlignmentRight; 65 | fpsLabel.tag=101; 66 | 67 | } 68 | return self; 69 | } 70 | 71 | - (void)displayLinkTick:(CADisplayLink *)link { 72 | if (lastTime == 0) { 73 | lastTime = link.timestamp; 74 | return; 75 | } 76 | 77 | count++; 78 | NSTimeInterval interval = link.timestamp - lastTime; 79 | if (interval < 1) return; 80 | lastTime = link.timestamp; 81 | float fps = count / interval; 82 | count = 0; 83 | 84 | NSString *text = [NSString stringWithFormat:@"%d FPS",(int)round(fps)]; 85 | [fpsLabel setText: text]; 86 | if (_fpsHandler) { 87 | _fpsHandler((int)round(fps)); 88 | } 89 | 90 | } 91 | 92 | - (void)open { 93 | 94 | NSArray *rootVCViewSubViews=[[UIApplication sharedApplication].delegate window].rootViewController.view.subviews; 95 | for (UIView *label in rootVCViewSubViews) { 96 | if ([label isKindOfClass:[UILabel class]]&& label.tag==101) { 97 | return; 98 | } 99 | } 100 | 101 | [displayLink setPaused:NO]; 102 | [[((NSObject *)([UIApplication sharedApplication].delegate)) window].rootViewController.view addSubview:fpsLabel]; 103 | } 104 | 105 | - (void)openWithHandler:(void (^)(NSInteger fpsValue))handler{ 106 | [[JPFPSStatus sharedInstance] open]; 107 | _fpsHandler=handler; 108 | } 109 | 110 | - (void)close { 111 | 112 | [displayLink setPaused:YES]; 113 | 114 | NSArray *rootVCViewSubViews=[[UIApplication sharedApplication].delegate window].rootViewController.view.subviews; 115 | for (UIView *label in rootVCViewSubViews) { 116 | if ([label isKindOfClass:[UILabel class]]&& label.tag==101) { 117 | [label removeFromSuperview]; 118 | return; 119 | } 120 | } 121 | 122 | } 123 | 124 | - (void)applicationDidBecomeActiveNotification { 125 | [displayLink setPaused:NO]; 126 | } 127 | 128 | - (void)applicationWillResignActiveNotification { 129 | [displayLink setPaused:YES]; 130 | } 131 | 132 | @end 133 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/MKAnnotationView+WebCache.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "SDWebImageCompat.h" 10 | 11 | #if SD_UIKIT || SD_MAC 12 | 13 | #import 14 | #import "SDWebImageManager.h" 15 | 16 | /** 17 | * Integrates SDWebImage async downloading and caching of remote images with MKAnnotationView. 18 | */ 19 | @interface MKAnnotationView (WebCache) 20 | 21 | /** 22 | * Set the imageView `image` with an `url`. 23 | * 24 | * The download is asynchronous and cached. 25 | * 26 | * @param url The url for the image. 27 | */ 28 | - (void)sd_setImageWithURL:(nullable NSURL *)url NS_REFINED_FOR_SWIFT; 29 | 30 | /** 31 | * Set the imageView `image` with an `url` and a placeholder. 32 | * 33 | * The download is asynchronous and cached. 34 | * 35 | * @param url The url for the image. 36 | * @param placeholder The image to be set initially, until the image request finishes. 37 | * @see sd_setImageWithURL:placeholderImage:options: 38 | */ 39 | - (void)sd_setImageWithURL:(nullable NSURL *)url 40 | placeholderImage:(nullable UIImage *)placeholder NS_REFINED_FOR_SWIFT; 41 | 42 | /** 43 | * Set the imageView `image` with an `url`, placeholder and custom options. 44 | * 45 | * The download is asynchronous and cached. 46 | * 47 | * @param url The url for the image. 48 | * @param placeholder The image to be set initially, until the image request finishes. 49 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 50 | */ 51 | 52 | - (void)sd_setImageWithURL:(nullable NSURL *)url 53 | placeholderImage:(nullable UIImage *)placeholder 54 | options:(SDWebImageOptions)options NS_REFINED_FOR_SWIFT; 55 | 56 | /** 57 | * Set the imageView `image` with an `url`. 58 | * 59 | * The download is asynchronous and cached. 60 | * 61 | * @param url The url for the image. 62 | * @param completedBlock A block called when operation has been completed. This block has no return value 63 | * and takes the requested UIImage as first parameter. In case of error the image parameter 64 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean 65 | * indicating if the image was retrieved from the local cache or from the network. 66 | * The fourth parameter is the original image url. 67 | */ 68 | - (void)sd_setImageWithURL:(nullable NSURL *)url 69 | completed:(nullable SDExternalCompletionBlock)completedBlock; 70 | 71 | /** 72 | * Set the imageView `image` with an `url`, placeholder. 73 | * 74 | * The download is asynchronous and cached. 75 | * 76 | * @param url The url for the image. 77 | * @param placeholder The image to be set initially, until the image request finishes. 78 | * @param completedBlock A block called when operation has been completed. This block has no return value 79 | * and takes the requested UIImage as first parameter. In case of error the image parameter 80 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean 81 | * indicating if the image was retrieved from the local cache or from the network. 82 | * The fourth parameter is the original image url. 83 | */ 84 | - (void)sd_setImageWithURL:(nullable NSURL *)url 85 | placeholderImage:(nullable UIImage *)placeholder 86 | completed:(nullable SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT; 87 | 88 | /** 89 | * Set the imageView `image` with an `url`, placeholder and custom options. 90 | * 91 | * The download is asynchronous and cached. 92 | * 93 | * @param url The url for the image. 94 | * @param placeholder The image to be set initially, until the image request finishes. 95 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 96 | * @param completedBlock A block called when operation has been completed. This block has no return value 97 | * and takes the requested UIImage as first parameter. In case of error the image parameter 98 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean 99 | * indicating if the image was retrieved from the local cache or from the network. 100 | * The fourth parameter is the original image url. 101 | */ 102 | - (void)sd_setImageWithURL:(nullable NSURL *)url 103 | placeholderImage:(nullable UIImage *)placeholder 104 | options:(SDWebImageOptions)options 105 | completed:(nullable SDExternalCompletionBlock)completedBlock; 106 | 107 | @end 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/MKAnnotationView+WebCache.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "MKAnnotationView+WebCache.h" 10 | 11 | #if SD_UIKIT || SD_MAC 12 | 13 | #import "objc/runtime.h" 14 | #import "UIView+WebCacheOperation.h" 15 | #import "UIView+WebCache.h" 16 | 17 | @implementation MKAnnotationView (WebCache) 18 | 19 | - (void)sd_setImageWithURL:(nullable NSURL *)url { 20 | [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:nil]; 21 | } 22 | 23 | - (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder { 24 | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:nil]; 25 | } 26 | 27 | - (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options { 28 | [self sd_setImageWithURL:url placeholderImage:placeholder options:options completed:nil]; 29 | } 30 | 31 | - (void)sd_setImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock { 32 | [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:completedBlock]; 33 | } 34 | 35 | - (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock { 36 | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:completedBlock]; 37 | } 38 | 39 | - (void)sd_setImageWithURL:(nullable NSURL *)url 40 | placeholderImage:(nullable UIImage *)placeholder 41 | options:(SDWebImageOptions)options 42 | completed:(nullable SDExternalCompletionBlock)completedBlock { 43 | __weak typeof(self)weakSelf = self; 44 | [self sd_internalSetImageWithURL:url 45 | placeholderImage:placeholder 46 | options:options 47 | operationKey:nil 48 | setImageBlock:^(UIImage *image, NSData *imageData) { 49 | weakSelf.image = image; 50 | } 51 | progress:nil 52 | completed:completedBlock]; 53 | } 54 | 55 | @end 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/NSData+ImageContentType.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * (c) Fabrice Aneche 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | #import 11 | #import "SDWebImageCompat.h" 12 | 13 | typedef NS_ENUM(NSInteger, SDImageFormat) { 14 | SDImageFormatUndefined = -1, 15 | SDImageFormatJPEG = 0, 16 | SDImageFormatPNG, 17 | SDImageFormatGIF, 18 | SDImageFormatTIFF, 19 | SDImageFormatWebP 20 | }; 21 | 22 | @interface NSData (ImageContentType) 23 | 24 | /** 25 | * Return image format 26 | * 27 | * @param data the input image data 28 | * 29 | * @return the image format as `SDImageFormat` (enum) 30 | */ 31 | + (SDImageFormat)sd_imageFormatForImageData:(nullable NSData *)data; 32 | 33 | /** 34 | Convert SDImageFormat to UTType 35 | 36 | @param format Format as SDImageFormat 37 | @return The UTType as CFStringRef 38 | */ 39 | + (nonnull CFStringRef)sd_UTTypeFromSDImageFormat:(SDImageFormat)format; 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/NSData+ImageContentType.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * (c) Fabrice Aneche 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | #import "NSData+ImageContentType.h" 11 | #if SD_MAC 12 | #import 13 | #else 14 | #import 15 | #endif 16 | 17 | @implementation NSData (ImageContentType) 18 | 19 | + (SDImageFormat)sd_imageFormatForImageData:(nullable NSData *)data { 20 | if (!data) { 21 | return SDImageFormatUndefined; 22 | } 23 | 24 | uint8_t c; 25 | [data getBytes:&c length:1]; 26 | switch (c) { 27 | case 0xFF: 28 | return SDImageFormatJPEG; 29 | case 0x89: 30 | return SDImageFormatPNG; 31 | case 0x47: 32 | return SDImageFormatGIF; 33 | case 0x49: 34 | case 0x4D: 35 | return SDImageFormatTIFF; 36 | case 0x52: 37 | // R as RIFF for WEBP 38 | if (data.length < 12) { 39 | return SDImageFormatUndefined; 40 | } 41 | 42 | NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding]; 43 | if ([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) { 44 | return SDImageFormatWebP; 45 | } 46 | } 47 | return SDImageFormatUndefined; 48 | } 49 | 50 | + (nonnull CFStringRef)sd_UTTypeFromSDImageFormat:(SDImageFormat)format { 51 | CFStringRef UTType; 52 | switch (format) { 53 | case SDImageFormatJPEG: 54 | UTType = kUTTypeJPEG; 55 | break; 56 | case SDImageFormatPNG: 57 | UTType = kUTTypePNG; 58 | break; 59 | case SDImageFormatGIF: 60 | UTType = kUTTypeGIF; 61 | break; 62 | case SDImageFormatTIFF: 63 | UTType = kUTTypeTIFF; 64 | break; 65 | default: 66 | // default is kUTTypePNG 67 | UTType = kUTTypePNG; 68 | break; 69 | } 70 | return UTType; 71 | } 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/NSImage+WebCache.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "SDWebImageCompat.h" 10 | 11 | #if SD_MAC 12 | 13 | #import 14 | 15 | @interface NSImage (WebCache) 16 | 17 | - (CGImageRef)CGImage; 18 | - (NSArray *)images; 19 | - (BOOL)isGIF; 20 | 21 | @end 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/NSImage+WebCache.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "NSImage+WebCache.h" 10 | 11 | #if SD_MAC 12 | 13 | @implementation NSImage (WebCache) 14 | 15 | - (CGImageRef)CGImage { 16 | NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height); 17 | CGImageRef cgImage = [self CGImageForProposedRect:&imageRect context:NULL hints:nil]; 18 | return cgImage; 19 | } 20 | 21 | - (NSArray *)images { 22 | return nil; 23 | } 24 | 25 | - (BOOL)isGIF { 26 | return NO; 27 | } 28 | 29 | @end 30 | 31 | #endif 32 | 33 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/SDImageCacheConfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import 10 | #import "SDWebImageCompat.h" 11 | 12 | @interface SDImageCacheConfig : NSObject 13 | 14 | /** 15 | * Decompressing images that are downloaded and cached can improve performance but can consume lot of memory. 16 | * Defaults to YES. Set this to NO if you are experiencing a crash due to excessive memory consumption. 17 | */ 18 | @property (assign, nonatomic) BOOL shouldDecompressImages; 19 | 20 | /** 21 | * disable iCloud backup [defaults to YES] 22 | */ 23 | @property (assign, nonatomic) BOOL shouldDisableiCloud; 24 | 25 | /** 26 | * use memory cache [defaults to YES] 27 | */ 28 | @property (assign, nonatomic) BOOL shouldCacheImagesInMemory; 29 | 30 | /** 31 | * The reading options while reading cache from disk. 32 | * Defaults to 0. You can set this to mapped file to improve performance. 33 | */ 34 | @property (assign, nonatomic) NSDataReadingOptions diskCacheReadingOptions; 35 | 36 | /** 37 | * The maximum length of time to keep an image in the cache, in seconds. 38 | */ 39 | @property (assign, nonatomic) NSInteger maxCacheAge; 40 | 41 | /** 42 | * The maximum size of the cache, in bytes. 43 | */ 44 | @property (assign, nonatomic) NSUInteger maxCacheSize; 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/SDImageCacheConfig.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "SDImageCacheConfig.h" 10 | 11 | static const NSInteger kDefaultCacheMaxCacheAge = 60 * 60 * 24 * 7; // 1 week 12 | 13 | @implementation SDImageCacheConfig 14 | 15 | - (instancetype)init { 16 | if (self = [super init]) { 17 | _shouldDecompressImages = YES; 18 | _shouldDisableiCloud = YES; 19 | _shouldCacheImagesInMemory = YES; 20 | _diskCacheReadingOptions = 0; 21 | _maxCacheAge = kDefaultCacheMaxCacheAge; 22 | _maxCacheSize = 0; 23 | } 24 | return self; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/SDWebImageCoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import 10 | #import "SDWebImageCompat.h" 11 | #import "NSData+ImageContentType.h" 12 | 13 | /** 14 | A Boolean value indicating whether to scale down large images during decompressing. (NSNumber) 15 | */ 16 | FOUNDATION_EXPORT NSString * _Nonnull const SDWebImageCoderScaleDownLargeImagesKey; 17 | 18 | /** 19 | Return the shared device-dependent RGB color space created with CGColorSpaceCreateDeviceRGB. 20 | 21 | @return The device-dependent RGB color space 22 | */ 23 | CG_EXTERN CGColorSpaceRef _Nonnull SDCGColorSpaceGetDeviceRGB(void); 24 | 25 | /** 26 | Check whether CGImageRef contains alpha channel. 27 | 28 | @param imageRef The CGImageRef 29 | @return Return YES if CGImageRef contains alpha channel, otherwise return NO 30 | */ 31 | CG_EXTERN BOOL SDCGImageRefContainsAlpha(_Nullable CGImageRef imageRef); 32 | 33 | 34 | /** 35 | This is the image coder protocol to provide custom image decoding/encoding. 36 | @note Pay attention that these methods are not called from main queue. 37 | */ 38 | @protocol SDWebImageCoder 39 | 40 | #pragma mark - Decoding 41 | /** 42 | Returns YES if this coder can decode some data. Otherwise, the data should be passed to another coder. 43 | 44 | @param data The image data so we can look at it 45 | @return YES if this coder can decode the data, NO otherwise 46 | */ 47 | - (BOOL)canDecodeFromData:(nullable NSData *)data; 48 | 49 | /** 50 | Decode the image data to image. 51 | 52 | @param data The image data to be decoded 53 | @return The decoded image from data 54 | */ 55 | - (nullable UIImage *)decodedImageWithData:(nullable NSData *)data; 56 | 57 | /** 58 | Decompress the image with original image and image data. 59 | 60 | @param image The original image to be decompressed 61 | @param data The pointer to original image data. The pointer itself is nonnull but image data can be null. This data will set to cache if needed. If you do not need to modify data at the sametime, ignore this param. 62 | @param optionsDict A dictionary containing any decompressing options. Pass {SDWebImageCoderScaleDownLargeImagesKey: @(YES)} to scale down large images 63 | @return The decompressed image 64 | */ 65 | - (nullable UIImage *)decompressedImageWithImage:(nullable UIImage *)image 66 | data:(NSData * _Nullable * _Nonnull)data 67 | options:(nullable NSDictionary*)optionsDict; 68 | 69 | #pragma mark - Encoding 70 | 71 | /** 72 | Returns YES if this coder can encode some image. Otherwise, it should be passed to another coder. 73 | 74 | @param format The image format 75 | @return YES if this coder can encode the image, NO otherwise 76 | */ 77 | - (BOOL)canEncodeToFormat:(SDImageFormat)format; 78 | 79 | /** 80 | Encode the image to image data. 81 | 82 | @param image The image to be encoded 83 | @param format The image format to encode, you should note `SDImageFormatUndefined` format is also possible 84 | @return The encoded image data 85 | */ 86 | - (nullable NSData *)encodedDataWithImage:(nullable UIImage *)image format:(SDImageFormat)format; 87 | 88 | @end 89 | 90 | 91 | /** 92 | This is the image coder protocol to provide custom progressive image decoding. 93 | @note Pay attention that these methods are not called from main queue. 94 | */ 95 | @protocol SDWebImageProgressiveCoder 96 | 97 | /** 98 | Returns YES if this coder can incremental decode some data. Otherwise, it should be passed to another coder. 99 | 100 | @param data The image data so we can look at it 101 | @return YES if this coder can decode the data, NO otherwise 102 | */ 103 | - (BOOL)canIncrementallyDecodeFromData:(nullable NSData *)data; 104 | 105 | /** 106 | Incremental decode the image data to image. 107 | 108 | @param data The image data has been downloaded so far 109 | @param finished Whether the download has finished 110 | @warning because incremental decoding need to keep the decoded context, we will alloc a new instance with the same class for each download operation to avoid conflicts 111 | @return The decoded image from data 112 | */ 113 | - (nullable UIImage *)incrementallyDecodedImageWithData:(nullable NSData *)data finished:(BOOL)finished; 114 | 115 | @end 116 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/SDWebImageCoder.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "SDWebImageCoder.h" 10 | 11 | NSString * const SDWebImageCoderScaleDownLargeImagesKey = @"scaleDownLargeImages"; 12 | 13 | CGColorSpaceRef SDCGColorSpaceGetDeviceRGB(void) { 14 | static CGColorSpaceRef colorSpace; 15 | static dispatch_once_t onceToken; 16 | dispatch_once(&onceToken, ^{ 17 | colorSpace = CGColorSpaceCreateDeviceRGB(); 18 | }); 19 | return colorSpace; 20 | } 21 | 22 | BOOL SDCGImageRefContainsAlpha(CGImageRef imageRef) { 23 | if (!imageRef) { 24 | return NO; 25 | } 26 | CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef); 27 | BOOL hasAlpha = !(alphaInfo == kCGImageAlphaNone || 28 | alphaInfo == kCGImageAlphaNoneSkipFirst || 29 | alphaInfo == kCGImageAlphaNoneSkipLast); 30 | return hasAlpha; 31 | } 32 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/SDWebImageCodersManager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import 10 | #import "SDWebImageCoder.h" 11 | 12 | /** 13 | Global object holding the array of coders, so that we avoid passing them from object to object. 14 | Uses a priority queue behind scenes, which means the latest added coders have priority. 15 | This is done so when encoding/decoding something, we go through the list and ask each coder if they can handle the current data. 16 | That way, users can add their custom coders while preserving our existing prebuilt ones 17 | 18 | Note: the `coders` getter will return the coders in their reversed order 19 | Example: 20 | - by default we internally set coders = `IOCoder`, `WebPCoder` 21 | - calling `coders` will return `@[WebPCoder, IOCoder]` 22 | - call `[addCoder:[MyCrazyCoder new]]` 23 | - calling `coders` now returns `@[MyCrazyCoder, WebPCoder, IOCoder]` 24 | 25 | Coders 26 | ------ 27 | A coder must conform to the `SDWebImageCoder` protocol or even to `SDWebImageProgressiveCoder` if it supports progressive decoding 28 | Conformance is important because that way, they will implement `canDecodeFromData` or `canEncodeToFormat` 29 | Those methods are called on each coder in the array (using the priority order) until one of them returns YES. 30 | That means that coder can decode that data / encode to that format 31 | */ 32 | @interface SDWebImageCodersManager : NSObject 33 | 34 | /** 35 | Shared reusable instance 36 | */ 37 | + (nonnull instancetype)sharedInstance; 38 | 39 | /** 40 | All coders in coders manager. The coders array is a priority queue, which means the later added coder will have the highest priority 41 | */ 42 | @property (nonatomic, strong, readwrite, nullable) NSArray* coders; 43 | 44 | /** 45 | Add a new coder to the end of coders array. Which has the highest priority. 46 | 47 | @param coder coder 48 | */ 49 | - (void)addCoder:(nonnull id)coder; 50 | 51 | /** 52 | Remove a coder in the coders array. 53 | 54 | @param coder coder 55 | */ 56 | - (void)removeCoder:(nonnull id)coder; 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/SDWebImageCodersManager.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "SDWebImageCodersManager.h" 10 | #import "SDWebImageImageIOCoder.h" 11 | #import "SDWebImageGIFCoder.h" 12 | #ifdef SD_WEBP 13 | #import "SDWebImageWebPCoder.h" 14 | #endif 15 | 16 | @interface SDWebImageCodersManager () 17 | 18 | @property (nonatomic, strong, nonnull) NSMutableArray* mutableCoders; 19 | @property (SDDispatchQueueSetterSementics, nonatomic, nullable) dispatch_queue_t mutableCodersAccessQueue; 20 | 21 | @end 22 | 23 | @implementation SDWebImageCodersManager 24 | 25 | + (nonnull instancetype)sharedInstance { 26 | static dispatch_once_t once; 27 | static id instance; 28 | dispatch_once(&once, ^{ 29 | instance = [self new]; 30 | }); 31 | return instance; 32 | } 33 | 34 | - (instancetype)init { 35 | if (self = [super init]) { 36 | // initialize with default coders 37 | _mutableCoders = [@[[SDWebImageImageIOCoder sharedCoder]] mutableCopy]; 38 | #ifdef SD_WEBP 39 | [_mutableCoders addObject:[SDWebImageWebPCoder sharedCoder]]; 40 | #endif 41 | _mutableCodersAccessQueue = dispatch_queue_create("com.hackemist.SDWebImageCodersManager", DISPATCH_QUEUE_CONCURRENT); 42 | } 43 | return self; 44 | } 45 | 46 | - (void)dealloc { 47 | SDDispatchQueueRelease(_mutableCodersAccessQueue); 48 | } 49 | 50 | #pragma mark - Coder IO operations 51 | 52 | - (void)addCoder:(nonnull id)coder { 53 | if ([coder conformsToProtocol:@protocol(SDWebImageCoder)]) { 54 | dispatch_barrier_sync(self.mutableCodersAccessQueue, ^{ 55 | [self.mutableCoders addObject:coder]; 56 | }); 57 | } 58 | } 59 | 60 | - (void)removeCoder:(nonnull id)coder { 61 | dispatch_barrier_sync(self.mutableCodersAccessQueue, ^{ 62 | [self.mutableCoders removeObject:coder]; 63 | }); 64 | } 65 | 66 | - (NSArray *)coders { 67 | __block NSArray *sortedCoders = nil; 68 | dispatch_sync(self.mutableCodersAccessQueue, ^{ 69 | sortedCoders = (NSArray *)[[[self.mutableCoders copy] reverseObjectEnumerator] allObjects]; 70 | }); 71 | return sortedCoders; 72 | } 73 | 74 | - (void)setCoders:(NSArray *)coders { 75 | dispatch_barrier_sync(self.mutableCodersAccessQueue, ^{ 76 | self.mutableCoders = [coders mutableCopy]; 77 | }); 78 | } 79 | 80 | #pragma mark - SDWebImageCoder 81 | - (BOOL)canDecodeFromData:(NSData *)data { 82 | for (id coder in self.coders) { 83 | if ([coder canDecodeFromData:data]) { 84 | return YES; 85 | } 86 | } 87 | return NO; 88 | } 89 | 90 | - (BOOL)canEncodeToFormat:(SDImageFormat)format { 91 | for (id coder in self.coders) { 92 | if ([coder canEncodeToFormat:format]) { 93 | return YES; 94 | } 95 | } 96 | return NO; 97 | } 98 | 99 | - (UIImage *)decodedImageWithData:(NSData *)data { 100 | if (!data) { 101 | return nil; 102 | } 103 | for (id coder in self.coders) { 104 | if ([coder canDecodeFromData:data]) { 105 | return [coder decodedImageWithData:data]; 106 | } 107 | } 108 | return nil; 109 | } 110 | 111 | - (UIImage *)decompressedImageWithImage:(UIImage *)image 112 | data:(NSData *__autoreleasing _Nullable *)data 113 | options:(nullable NSDictionary*)optionsDict { 114 | if (!image) { 115 | return nil; 116 | } 117 | for (id coder in self.coders) { 118 | if ([coder canDecodeFromData:*data]) { 119 | return [coder decompressedImageWithImage:image data:data options:optionsDict]; 120 | } 121 | } 122 | return nil; 123 | } 124 | 125 | - (NSData *)encodedDataWithImage:(UIImage *)image format:(SDImageFormat)format { 126 | if (!image) { 127 | return nil; 128 | } 129 | for (id coder in self.coders) { 130 | if ([coder canEncodeToFormat:format]) { 131 | return [coder encodedDataWithImage:image format:format]; 132 | } 133 | } 134 | return nil; 135 | } 136 | 137 | @end 138 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/SDWebImageCompat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * (c) Jamie Pinkham 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | #import 11 | 12 | #ifdef __OBJC_GC__ 13 | #error SDWebImage does not support Objective-C Garbage Collection 14 | #endif 15 | 16 | // Apple's defines from TargetConditionals.h are a bit weird. 17 | // Seems like TARGET_OS_MAC is always defined (on all platforms). 18 | // To determine if we are running on OSX, we can only rely on TARGET_OS_IPHONE=0 and all the other platforms 19 | #if !TARGET_OS_IPHONE && !TARGET_OS_IOS && !TARGET_OS_TV && !TARGET_OS_WATCH 20 | #define SD_MAC 1 21 | #else 22 | #define SD_MAC 0 23 | #endif 24 | 25 | // iOS and tvOS are very similar, UIKit exists on both platforms 26 | // Note: watchOS also has UIKit, but it's very limited 27 | #if TARGET_OS_IOS || TARGET_OS_TV 28 | #define SD_UIKIT 1 29 | #else 30 | #define SD_UIKIT 0 31 | #endif 32 | 33 | #if TARGET_OS_IOS 34 | #define SD_IOS 1 35 | #else 36 | #define SD_IOS 0 37 | #endif 38 | 39 | #if TARGET_OS_TV 40 | #define SD_TV 1 41 | #else 42 | #define SD_TV 0 43 | #endif 44 | 45 | #if TARGET_OS_WATCH 46 | #define SD_WATCH 1 47 | #else 48 | #define SD_WATCH 0 49 | #endif 50 | 51 | 52 | #if SD_MAC 53 | #import 54 | #ifndef UIImage 55 | #define UIImage NSImage 56 | #endif 57 | #ifndef UIImageView 58 | #define UIImageView NSImageView 59 | #endif 60 | #ifndef UIView 61 | #define UIView NSView 62 | #endif 63 | #else 64 | #if __IPHONE_OS_VERSION_MIN_REQUIRED != 20000 && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0 65 | #error SDWebImage doesn't support Deployment Target version < 5.0 66 | #endif 67 | 68 | #if SD_UIKIT 69 | #import 70 | #endif 71 | #if SD_WATCH 72 | #import 73 | #endif 74 | #endif 75 | 76 | #ifndef NS_ENUM 77 | #define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type 78 | #endif 79 | 80 | #ifndef NS_OPTIONS 81 | #define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type 82 | #endif 83 | 84 | #if OS_OBJECT_USE_OBJC 85 | #undef SDDispatchQueueRelease 86 | #undef SDDispatchQueueSetterSementics 87 | #define SDDispatchQueueRelease(q) 88 | #define SDDispatchQueueSetterSementics strong 89 | #else 90 | #undef SDDispatchQueueRelease 91 | #undef SDDispatchQueueSetterSementics 92 | #define SDDispatchQueueRelease(q) (dispatch_release(q)) 93 | #define SDDispatchQueueSetterSementics assign 94 | #endif 95 | 96 | FOUNDATION_EXPORT UIImage *SDScaledImageForKey(NSString *key, UIImage *image); 97 | 98 | typedef void(^SDWebImageNoParamsBlock)(void); 99 | 100 | FOUNDATION_EXPORT NSString *const SDWebImageErrorDomain; 101 | 102 | #ifndef dispatch_main_async_safe 103 | #define dispatch_main_async_safe(block)\ 104 | if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(dispatch_get_main_queue())) == 0) {\ 105 | block();\ 106 | } else {\ 107 | dispatch_async(dispatch_get_main_queue(), block);\ 108 | } 109 | #endif 110 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/SDWebImageCompat.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "SDWebImageCompat.h" 10 | #import "UIImage+MultiFormat.h" 11 | 12 | #if !__has_feature(objc_arc) 13 | #error SDWebImage is ARC only. Either turn on ARC for the project or use -fobjc-arc flag 14 | #endif 15 | 16 | inline UIImage *SDScaledImageForKey(NSString * _Nullable key, UIImage * _Nullable image) { 17 | if (!image) { 18 | return nil; 19 | } 20 | 21 | #if SD_MAC 22 | return image; 23 | #elif SD_UIKIT || SD_WATCH 24 | if ((image.images).count > 0) { 25 | NSMutableArray *scaledImages = [NSMutableArray array]; 26 | 27 | for (UIImage *tempImage in image.images) { 28 | [scaledImages addObject:SDScaledImageForKey(key, tempImage)]; 29 | } 30 | 31 | UIImage *animatedImage = [UIImage animatedImageWithImages:scaledImages duration:image.duration]; 32 | if (animatedImage) { 33 | animatedImage.sd_imageLoopCount = image.sd_imageLoopCount; 34 | } 35 | return animatedImage; 36 | } else { 37 | #if SD_WATCH 38 | if ([[WKInterfaceDevice currentDevice] respondsToSelector:@selector(screenScale)]) { 39 | #elif SD_UIKIT 40 | if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) { 41 | #endif 42 | CGFloat scale = 1; 43 | if (key.length >= 8) { 44 | NSRange range = [key rangeOfString:@"@2x."]; 45 | if (range.location != NSNotFound) { 46 | scale = 2.0; 47 | } 48 | 49 | range = [key rangeOfString:@"@3x."]; 50 | if (range.location != NSNotFound) { 51 | scale = 3.0; 52 | } 53 | } 54 | 55 | UIImage *scaledImage = [[UIImage alloc] initWithCGImage:image.CGImage scale:scale orientation:image.imageOrientation]; 56 | image = scaledImage; 57 | } 58 | return image; 59 | } 60 | #endif 61 | } 62 | 63 | NSString *const SDWebImageErrorDomain = @"SDWebImageErrorDomain"; 64 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/SDWebImageDownloaderOperation.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import 10 | #import "SDWebImageDownloader.h" 11 | #import "SDWebImageOperation.h" 12 | 13 | FOUNDATION_EXPORT NSString * _Nonnull const SDWebImageDownloadStartNotification; 14 | FOUNDATION_EXPORT NSString * _Nonnull const SDWebImageDownloadReceiveResponseNotification; 15 | FOUNDATION_EXPORT NSString * _Nonnull const SDWebImageDownloadStopNotification; 16 | FOUNDATION_EXPORT NSString * _Nonnull const SDWebImageDownloadFinishNotification; 17 | 18 | 19 | 20 | /** 21 | Describes a downloader operation. If one wants to use a custom downloader op, it needs to inherit from `NSOperation` and conform to this protocol 22 | */ 23 | @protocol SDWebImageDownloaderOperationInterface 24 | 25 | - (nonnull instancetype)initWithRequest:(nullable NSURLRequest *)request 26 | inSession:(nullable NSURLSession *)session 27 | options:(SDWebImageDownloaderOptions)options; 28 | 29 | - (nullable id)addHandlersForProgress:(nullable SDWebImageDownloaderProgressBlock)progressBlock 30 | completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock; 31 | 32 | - (BOOL)shouldDecompressImages; 33 | - (void)setShouldDecompressImages:(BOOL)value; 34 | 35 | - (nullable NSURLCredential *)credential; 36 | - (void)setCredential:(nullable NSURLCredential *)value; 37 | 38 | @end 39 | 40 | 41 | @interface SDWebImageDownloaderOperation : NSOperation 42 | 43 | /** 44 | * The request used by the operation's task. 45 | */ 46 | @property (strong, nonatomic, readonly, nullable) NSURLRequest *request; 47 | 48 | /** 49 | * The operation's task 50 | */ 51 | @property (strong, nonatomic, readonly, nullable) NSURLSessionTask *dataTask; 52 | 53 | 54 | @property (assign, nonatomic) BOOL shouldDecompressImages; 55 | 56 | /** 57 | * Was used to determine whether the URL connection should consult the credential storage for authenticating the connection. 58 | * @deprecated Not used for a couple of versions 59 | */ 60 | @property (nonatomic, assign) BOOL shouldUseCredentialStorage __deprecated_msg("Property deprecated. Does nothing. Kept only for backwards compatibility"); 61 | 62 | /** 63 | * The credential used for authentication challenges in `-connection:didReceiveAuthenticationChallenge:`. 64 | * 65 | * This will be overridden by any shared credentials that exist for the username or password of the request URL, if present. 66 | */ 67 | @property (nonatomic, strong, nullable) NSURLCredential *credential; 68 | 69 | /** 70 | * The SDWebImageDownloaderOptions for the receiver. 71 | */ 72 | @property (assign, nonatomic, readonly) SDWebImageDownloaderOptions options; 73 | 74 | /** 75 | * The expected size of data. 76 | */ 77 | @property (assign, nonatomic) NSInteger expectedSize; 78 | 79 | /** 80 | * The response returned by the operation's connection. 81 | */ 82 | @property (strong, nonatomic, nullable) NSURLResponse *response; 83 | 84 | /** 85 | * Initializes a `SDWebImageDownloaderOperation` object 86 | * 87 | * @see SDWebImageDownloaderOperation 88 | * 89 | * @param request the URL request 90 | * @param session the URL session in which this operation will run 91 | * @param options downloader options 92 | * 93 | * @return the initialized instance 94 | */ 95 | - (nonnull instancetype)initWithRequest:(nullable NSURLRequest *)request 96 | inSession:(nullable NSURLSession *)session 97 | options:(SDWebImageDownloaderOptions)options NS_DESIGNATED_INITIALIZER; 98 | 99 | /** 100 | * Adds handlers for progress and completion. Returns a tokent that can be passed to -cancel: to cancel this set of 101 | * callbacks. 102 | * 103 | * @param progressBlock the block executed when a new chunk of data arrives. 104 | * @note the progress block is executed on a background queue 105 | * @param completedBlock the block executed when the download is done. 106 | * @note the completed block is executed on the main queue for success. If errors are found, there is a chance the block will be executed on a background queue 107 | * 108 | * @return the token to use to cancel this set of handlers 109 | */ 110 | - (nullable id)addHandlersForProgress:(nullable SDWebImageDownloaderProgressBlock)progressBlock 111 | completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock; 112 | 113 | /** 114 | * Cancels a set of callbacks. Once all callbacks are canceled, the operation is cancelled. 115 | * 116 | * @param token the token representing a set of callbacks to cancel 117 | * 118 | * @return YES if the operation was stopped because this was the last token to be canceled. NO otherwise. 119 | */ 120 | - (BOOL)cancel:(nullable id)token; 121 | 122 | @end 123 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/SDWebImageGIFCoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import 10 | #import "SDWebImageCoder.h" 11 | 12 | /** 13 | Built in coder using ImageIO that supports GIF encoding/decoding 14 | @note `SDWebImageIOCoder` supports GIF but only as static (will use the 1st frame). 15 | @note Use `SDWebImageGIFCoder` for fully animated GIFs - less performant than `FLAnimatedImage` 16 | @note The recommended approach for animated GIFs is using `FLAnimatedImage` 17 | */ 18 | @interface SDWebImageGIFCoder : NSObject 19 | 20 | + (nonnull instancetype)sharedCoder; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/SDWebImageGIFCoder.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "SDWebImageGIFCoder.h" 10 | #import "NSImage+WebCache.h" 11 | #import 12 | #import "NSData+ImageContentType.h" 13 | #import "UIImage+MultiFormat.h" 14 | 15 | @implementation SDWebImageGIFCoder 16 | 17 | + (instancetype)sharedCoder { 18 | static SDWebImageGIFCoder *coder; 19 | static dispatch_once_t onceToken; 20 | dispatch_once(&onceToken, ^{ 21 | coder = [[SDWebImageGIFCoder alloc] init]; 22 | }); 23 | return coder; 24 | } 25 | 26 | #pragma mark - Decode 27 | - (BOOL)canDecodeFromData:(nullable NSData *)data { 28 | return ([NSData sd_imageFormatForImageData:data] == SDImageFormatGIF); 29 | } 30 | 31 | - (UIImage *)decodedImageWithData:(NSData *)data { 32 | if (!data) { 33 | return nil; 34 | } 35 | 36 | #if SD_MAC 37 | return [[UIImage alloc] initWithData:data]; 38 | #else 39 | 40 | CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL); 41 | 42 | size_t count = CGImageSourceGetCount(source); 43 | 44 | UIImage *animatedImage; 45 | 46 | if (count <= 1) { 47 | animatedImage = [[UIImage alloc] initWithData:data]; 48 | } else { 49 | NSMutableArray *images = [NSMutableArray array]; 50 | 51 | NSTimeInterval duration = 0.0f; 52 | 53 | for (size_t i = 0; i < count; i++) { 54 | CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL); 55 | if (!image) { 56 | continue; 57 | } 58 | 59 | duration += [self sd_frameDurationAtIndex:i source:source]; 60 | #if SD_WATCH 61 | CGFloat scale = 1; 62 | scale = [WKInterfaceDevice currentDevice].screenScale; 63 | #elif SD_UIKIT 64 | CGFloat scale = 1; 65 | scale = [UIScreen mainScreen].scale; 66 | #endif 67 | [images addObject:[UIImage imageWithCGImage:image scale:scale orientation:UIImageOrientationUp]]; 68 | 69 | CGImageRelease(image); 70 | } 71 | 72 | if (!duration) { 73 | duration = (1.0f / 10.0f) * count; 74 | } 75 | 76 | animatedImage = [UIImage animatedImageWithImages:images duration:duration]; 77 | 78 | NSUInteger loopCount = 0; 79 | NSDictionary *imageProperties = (__bridge_transfer NSDictionary *)CGImageSourceCopyProperties(source, nil); 80 | NSDictionary *gifProperties = [imageProperties valueForKey:(__bridge_transfer NSString *)kCGImagePropertyGIFDictionary]; 81 | if (gifProperties) { 82 | NSNumber *gifLoopCount = [gifProperties valueForKey:(__bridge_transfer NSString *)kCGImagePropertyGIFLoopCount]; 83 | if (gifLoopCount) { 84 | loopCount = gifLoopCount.unsignedIntegerValue; 85 | } 86 | } 87 | animatedImage.sd_imageLoopCount = loopCount; 88 | } 89 | 90 | CFRelease(source); 91 | 92 | return animatedImage; 93 | #endif 94 | } 95 | 96 | - (float)sd_frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source { 97 | float frameDuration = 0.1f; 98 | CFDictionaryRef cfFrameProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil); 99 | NSDictionary *frameProperties = (__bridge NSDictionary *)cfFrameProperties; 100 | NSDictionary *gifProperties = frameProperties[(NSString *)kCGImagePropertyGIFDictionary]; 101 | 102 | NSNumber *delayTimeUnclampedProp = gifProperties[(NSString *)kCGImagePropertyGIFUnclampedDelayTime]; 103 | if (delayTimeUnclampedProp) { 104 | frameDuration = [delayTimeUnclampedProp floatValue]; 105 | } else { 106 | NSNumber *delayTimeProp = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime]; 107 | if (delayTimeProp) { 108 | frameDuration = [delayTimeProp floatValue]; 109 | } 110 | } 111 | 112 | // Many annoying ads specify a 0 duration to make an image flash as quickly as possible. 113 | // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify 114 | // a duration of <= 10 ms. See and 115 | // for more information. 116 | 117 | if (frameDuration < 0.011f) { 118 | frameDuration = 0.100f; 119 | } 120 | 121 | CFRelease(cfFrameProperties); 122 | return frameDuration; 123 | } 124 | 125 | - (UIImage *)decompressedImageWithImage:(UIImage *)image 126 | data:(NSData *__autoreleasing _Nullable *)data 127 | options:(nullable NSDictionary*)optionsDict { 128 | // GIF do not decompress 129 | return image; 130 | } 131 | 132 | #pragma mark - Encode 133 | - (BOOL)canEncodeToFormat:(SDImageFormat)format { 134 | return (format == SDImageFormatGIF); 135 | } 136 | 137 | - (NSData *)encodedDataWithImage:(UIImage *)image format:(SDImageFormat)format { 138 | if (!image) { 139 | return nil; 140 | } 141 | 142 | if (format != SDImageFormatGIF) { 143 | return nil; 144 | } 145 | 146 | NSMutableData *imageData = [NSMutableData data]; 147 | NSUInteger frameCount = 0; // assume static images by default 148 | CFStringRef imageUTType = [NSData sd_UTTypeFromSDImageFormat:format]; 149 | #if SD_MAC 150 | NSBitmapImageRep *bitmapRep; 151 | for (NSImageRep *imageRep in image.representations) { 152 | if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) { 153 | bitmapRep = (NSBitmapImageRep *)imageRep; 154 | break; 155 | } 156 | } 157 | if (bitmapRep) { 158 | frameCount = [[bitmapRep valueForProperty:NSImageFrameCount] unsignedIntegerValue]; 159 | } 160 | #else 161 | frameCount = image.images.count; 162 | #endif 163 | 164 | // Create an image destination. GIF does not support EXIF image orientation 165 | CGImageDestinationRef imageDestination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imageData, imageUTType, frameCount, NULL); 166 | if (!imageDestination) { 167 | // Handle failure. 168 | return nil; 169 | } 170 | 171 | if (frameCount == 0) { 172 | // for static single GIF images 173 | CGImageDestinationAddImage(imageDestination, image.CGImage, nil); 174 | } else { 175 | // for animated GIF images 176 | NSUInteger loopCount = image.sd_imageLoopCount; 177 | NSDictionary *gifProperties = @{(__bridge_transfer NSString *)kCGImagePropertyGIFDictionary: @{(__bridge_transfer NSString *)kCGImagePropertyGIFLoopCount : @(loopCount)}}; 178 | CGImageDestinationSetProperties(imageDestination, (__bridge CFDictionaryRef)gifProperties); 179 | for (size_t i = 0; i < frameCount; i++) { 180 | @autoreleasepool { 181 | #if SD_MAC 182 | // NSBitmapImageRep need to manually change frame. "Good taste" API 183 | [bitmapRep setProperty:NSImageCurrentFrame withValue:@(i)]; 184 | float frameDuration = [[bitmapRep valueForProperty:NSImageCurrentFrameDuration] floatValue]; 185 | CGImageRef frameImageRef = bitmapRep.CGImage; 186 | #else 187 | float frameDuration = image.duration / frameCount; 188 | CGImageRef frameImageRef = image.images[i].CGImage; 189 | #endif 190 | NSDictionary *frameProperties = @{(__bridge_transfer NSString *)kCGImagePropertyGIFDictionary : @{(__bridge_transfer NSString *)kCGImagePropertyGIFUnclampedDelayTime : @(frameDuration)}}; 191 | CGImageDestinationAddImage(imageDestination, frameImageRef, (__bridge CFDictionaryRef)frameProperties); 192 | } 193 | } 194 | } 195 | // Finalize the destination. 196 | if (CGImageDestinationFinalize(imageDestination) == NO) { 197 | // Handle failure. 198 | imageData = nil; 199 | } 200 | 201 | CFRelease(imageDestination); 202 | 203 | return [imageData copy]; 204 | } 205 | 206 | @end 207 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/SDWebImageImageIOCoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import 10 | #import "SDWebImageCoder.h" 11 | 12 | /** 13 | Built in coder that supports PNG, JPEG, TIFF, includes support for progressive decoding 14 | Also supports static GIF (meaning will only handle the 1st frame). 15 | For a full GIF support, we recommend `FLAnimatedImage` or our less performant `SDWebImageGIFCoder` 16 | */ 17 | @interface SDWebImageImageIOCoder : NSObject 18 | 19 | + (nonnull instancetype)sharedCoder; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/SDWebImageOperation.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import 10 | 11 | @protocol SDWebImageOperation 12 | 13 | - (void)cancel; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/SDWebImagePrefetcher.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import 10 | #import "SDWebImageManager.h" 11 | 12 | @class SDWebImagePrefetcher; 13 | 14 | @protocol SDWebImagePrefetcherDelegate 15 | 16 | @optional 17 | 18 | /** 19 | * Called when an image was prefetched. 20 | * 21 | * @param imagePrefetcher The current image prefetcher 22 | * @param imageURL The image url that was prefetched 23 | * @param finishedCount The total number of images that were prefetched (successful or not) 24 | * @param totalCount The total number of images that were to be prefetched 25 | */ 26 | - (void)imagePrefetcher:(nonnull SDWebImagePrefetcher *)imagePrefetcher didPrefetchURL:(nullable NSURL *)imageURL finishedCount:(NSUInteger)finishedCount totalCount:(NSUInteger)totalCount; 27 | 28 | /** 29 | * Called when all images are prefetched. 30 | * @param imagePrefetcher The current image prefetcher 31 | * @param totalCount The total number of images that were prefetched (whether successful or not) 32 | * @param skippedCount The total number of images that were skipped 33 | */ 34 | - (void)imagePrefetcher:(nonnull SDWebImagePrefetcher *)imagePrefetcher didFinishWithTotalCount:(NSUInteger)totalCount skippedCount:(NSUInteger)skippedCount; 35 | 36 | @end 37 | 38 | typedef void(^SDWebImagePrefetcherProgressBlock)(NSUInteger noOfFinishedUrls, NSUInteger noOfTotalUrls); 39 | typedef void(^SDWebImagePrefetcherCompletionBlock)(NSUInteger noOfFinishedUrls, NSUInteger noOfSkippedUrls); 40 | 41 | /** 42 | * Prefetch some URLs in the cache for future use. Images are downloaded in low priority. 43 | */ 44 | @interface SDWebImagePrefetcher : NSObject 45 | 46 | /** 47 | * The web image manager 48 | */ 49 | @property (strong, nonatomic, readonly, nonnull) SDWebImageManager *manager; 50 | 51 | /** 52 | * Maximum number of URLs to prefetch at the same time. Defaults to 3. 53 | */ 54 | @property (nonatomic, assign) NSUInteger maxConcurrentDownloads; 55 | 56 | /** 57 | * SDWebImageOptions for prefetcher. Defaults to SDWebImageLowPriority. 58 | */ 59 | @property (nonatomic, assign) SDWebImageOptions options; 60 | 61 | /** 62 | * Queue options for Prefetcher. Defaults to Main Queue. 63 | */ 64 | @property (SDDispatchQueueSetterSementics, nonatomic, nonnull) dispatch_queue_t prefetcherQueue; 65 | 66 | @property (weak, nonatomic, nullable) id delegate; 67 | 68 | /** 69 | * Return the global image prefetcher instance. 70 | */ 71 | + (nonnull instancetype)sharedImagePrefetcher; 72 | 73 | /** 74 | * Allows you to instantiate a prefetcher with any arbitrary image manager. 75 | */ 76 | - (nonnull instancetype)initWithImageManager:(nonnull SDWebImageManager *)manager NS_DESIGNATED_INITIALIZER; 77 | 78 | /** 79 | * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching, 80 | * currently one image is downloaded at a time, 81 | * and skips images for failed downloads and proceed to the next image in the list. 82 | * Any previously-running prefetch operations are canceled. 83 | * 84 | * @param urls list of URLs to prefetch 85 | */ 86 | - (void)prefetchURLs:(nullable NSArray *)urls; 87 | 88 | /** 89 | * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching, 90 | * currently one image is downloaded at a time, 91 | * and skips images for failed downloads and proceed to the next image in the list. 92 | * Any previously-running prefetch operations are canceled. 93 | * 94 | * @param urls list of URLs to prefetch 95 | * @param progressBlock block to be called when progress updates; 96 | * first parameter is the number of completed (successful or not) requests, 97 | * second parameter is the total number of images originally requested to be prefetched 98 | * @param completionBlock block to be called when prefetching is completed 99 | * first param is the number of completed (successful or not) requests, 100 | * second parameter is the number of skipped requests 101 | */ 102 | - (void)prefetchURLs:(nullable NSArray *)urls 103 | progress:(nullable SDWebImagePrefetcherProgressBlock)progressBlock 104 | completed:(nullable SDWebImagePrefetcherCompletionBlock)completionBlock; 105 | 106 | /** 107 | * Remove and cancel queued list 108 | */ 109 | - (void)cancelPrefetching; 110 | 111 | 112 | @end 113 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/SDWebImagePrefetcher.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "SDWebImagePrefetcher.h" 10 | 11 | @interface SDWebImagePrefetcher () 12 | 13 | @property (strong, nonatomic, nonnull) SDWebImageManager *manager; 14 | @property (strong, nonatomic, nullable) NSArray *prefetchURLs; 15 | @property (assign, nonatomic) NSUInteger requestedCount; 16 | @property (assign, nonatomic) NSUInteger skippedCount; 17 | @property (assign, nonatomic) NSUInteger finishedCount; 18 | @property (assign, nonatomic) NSTimeInterval startedTime; 19 | @property (copy, nonatomic, nullable) SDWebImagePrefetcherCompletionBlock completionBlock; 20 | @property (copy, nonatomic, nullable) SDWebImagePrefetcherProgressBlock progressBlock; 21 | 22 | @end 23 | 24 | @implementation SDWebImagePrefetcher 25 | 26 | + (nonnull instancetype)sharedImagePrefetcher { 27 | static dispatch_once_t once; 28 | static id instance; 29 | dispatch_once(&once, ^{ 30 | instance = [self new]; 31 | }); 32 | return instance; 33 | } 34 | 35 | - (nonnull instancetype)init { 36 | return [self initWithImageManager:[SDWebImageManager new]]; 37 | } 38 | 39 | - (nonnull instancetype)initWithImageManager:(SDWebImageManager *)manager { 40 | if ((self = [super init])) { 41 | _manager = manager; 42 | _options = SDWebImageLowPriority; 43 | _prefetcherQueue = dispatch_get_main_queue(); 44 | self.maxConcurrentDownloads = 3; 45 | } 46 | return self; 47 | } 48 | 49 | - (void)setMaxConcurrentDownloads:(NSUInteger)maxConcurrentDownloads { 50 | self.manager.imageDownloader.maxConcurrentDownloads = maxConcurrentDownloads; 51 | } 52 | 53 | - (NSUInteger)maxConcurrentDownloads { 54 | return self.manager.imageDownloader.maxConcurrentDownloads; 55 | } 56 | 57 | - (void)startPrefetchingAtIndex:(NSUInteger)index { 58 | if (index >= self.prefetchURLs.count) return; 59 | self.requestedCount++; 60 | [self.manager loadImageWithURL:self.prefetchURLs[index] options:self.options progress:nil completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { 61 | if (!finished) return; 62 | self.finishedCount++; 63 | 64 | if (image) { 65 | if (self.progressBlock) { 66 | self.progressBlock(self.finishedCount,(self.prefetchURLs).count); 67 | } 68 | } 69 | else { 70 | if (self.progressBlock) { 71 | self.progressBlock(self.finishedCount,(self.prefetchURLs).count); 72 | } 73 | // Add last failed 74 | self.skippedCount++; 75 | } 76 | if ([self.delegate respondsToSelector:@selector(imagePrefetcher:didPrefetchURL:finishedCount:totalCount:)]) { 77 | [self.delegate imagePrefetcher:self 78 | didPrefetchURL:self.prefetchURLs[index] 79 | finishedCount:self.finishedCount 80 | totalCount:self.prefetchURLs.count 81 | ]; 82 | } 83 | if (self.prefetchURLs.count > self.requestedCount) { 84 | dispatch_async(self.prefetcherQueue, ^{ 85 | [self startPrefetchingAtIndex:self.requestedCount]; 86 | }); 87 | } else if (self.finishedCount == self.requestedCount) { 88 | [self reportStatus]; 89 | if (self.completionBlock) { 90 | self.completionBlock(self.finishedCount, self.skippedCount); 91 | self.completionBlock = nil; 92 | } 93 | self.progressBlock = nil; 94 | } 95 | }]; 96 | } 97 | 98 | - (void)reportStatus { 99 | NSUInteger total = (self.prefetchURLs).count; 100 | if ([self.delegate respondsToSelector:@selector(imagePrefetcher:didFinishWithTotalCount:skippedCount:)]) { 101 | [self.delegate imagePrefetcher:self 102 | didFinishWithTotalCount:(total - self.skippedCount) 103 | skippedCount:self.skippedCount 104 | ]; 105 | } 106 | } 107 | 108 | - (void)prefetchURLs:(nullable NSArray *)urls { 109 | [self prefetchURLs:urls progress:nil completed:nil]; 110 | } 111 | 112 | - (void)prefetchURLs:(nullable NSArray *)urls 113 | progress:(nullable SDWebImagePrefetcherProgressBlock)progressBlock 114 | completed:(nullable SDWebImagePrefetcherCompletionBlock)completionBlock { 115 | [self cancelPrefetching]; // Prevent duplicate prefetch request 116 | self.startedTime = CFAbsoluteTimeGetCurrent(); 117 | self.prefetchURLs = urls; 118 | self.completionBlock = completionBlock; 119 | self.progressBlock = progressBlock; 120 | 121 | if (urls.count == 0) { 122 | if (completionBlock) { 123 | completionBlock(0,0); 124 | } 125 | } else { 126 | // Starts prefetching from the very first image on the list with the max allowed concurrency 127 | NSUInteger listCount = self.prefetchURLs.count; 128 | for (NSUInteger i = 0; i < self.maxConcurrentDownloads && self.requestedCount < listCount; i++) { 129 | [self startPrefetchingAtIndex:i]; 130 | } 131 | } 132 | } 133 | 134 | - (void)cancelPrefetching { 135 | self.prefetchURLs = nil; 136 | self.skippedCount = 0; 137 | self.requestedCount = 0; 138 | self.finishedCount = 0; 139 | [self.manager cancelAll]; 140 | } 141 | 142 | @end 143 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/SDWebImageWebPCoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #ifdef SD_WEBP 10 | 11 | #import 12 | #import "SDWebImageCoder.h" 13 | 14 | /** 15 | Built in coder that supports WebP and animated WebP 16 | */ 17 | @interface SDWebImageWebPCoder : NSObject 18 | 19 | + (nonnull instancetype)sharedCoder; 20 | 21 | @end 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/UIButton+WebCache.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "UIButton+WebCache.h" 10 | 11 | #if SD_UIKIT 12 | 13 | #import "objc/runtime.h" 14 | #import "UIView+WebCacheOperation.h" 15 | #import "UIView+WebCache.h" 16 | 17 | static char imageURLStorageKey; 18 | 19 | typedef NSMutableDictionary SDStateImageURLDictionary; 20 | 21 | static inline NSString * imageURLKeyForState(UIControlState state) { 22 | return [NSString stringWithFormat:@"image_%lu", (unsigned long)state]; 23 | } 24 | 25 | static inline NSString * backgroundImageURLKeyForState(UIControlState state) { 26 | return [NSString stringWithFormat:@"backgroundImage_%lu", (unsigned long)state]; 27 | } 28 | 29 | @implementation UIButton (WebCache) 30 | 31 | #pragma mark - Image 32 | 33 | - (nullable NSURL *)sd_currentImageURL { 34 | NSURL *url = self.imageURLStorage[imageURLKeyForState(self.state)]; 35 | 36 | if (!url) { 37 | url = self.imageURLStorage[imageURLKeyForState(UIControlStateNormal)]; 38 | } 39 | 40 | return url; 41 | } 42 | 43 | - (nullable NSURL *)sd_imageURLForState:(UIControlState)state { 44 | return self.imageURLStorage[imageURLKeyForState(state)]; 45 | } 46 | 47 | - (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state { 48 | [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil]; 49 | } 50 | 51 | - (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder { 52 | [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil]; 53 | } 54 | 55 | - (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options { 56 | [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil]; 57 | } 58 | 59 | - (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state completed:(nullable SDExternalCompletionBlock)completedBlock { 60 | [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:completedBlock]; 61 | } 62 | 63 | - (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock { 64 | [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:completedBlock]; 65 | } 66 | 67 | - (void)sd_setImageWithURL:(nullable NSURL *)url 68 | forState:(UIControlState)state 69 | placeholderImage:(nullable UIImage *)placeholder 70 | options:(SDWebImageOptions)options 71 | completed:(nullable SDExternalCompletionBlock)completedBlock { 72 | if (!url) { 73 | [self.imageURLStorage removeObjectForKey:imageURLKeyForState(state)]; 74 | } else { 75 | self.imageURLStorage[imageURLKeyForState(state)] = url; 76 | } 77 | 78 | __weak typeof(self)weakSelf = self; 79 | [self sd_internalSetImageWithURL:url 80 | placeholderImage:placeholder 81 | options:options 82 | operationKey:[NSString stringWithFormat:@"UIButtonImageOperation%@", @(state)] 83 | setImageBlock:^(UIImage *image, NSData *imageData) { 84 | [weakSelf setImage:image forState:state]; 85 | } 86 | progress:nil 87 | completed:completedBlock]; 88 | } 89 | 90 | #pragma mark - Background image 91 | 92 | - (nullable NSURL *)sd_currentBackgroundImageURL { 93 | NSURL *url = self.imageURLStorage[backgroundImageURLKeyForState(self.state)]; 94 | 95 | if (!url) { 96 | url = self.imageURLStorage[backgroundImageURLKeyForState(UIControlStateNormal)]; 97 | } 98 | 99 | return url; 100 | } 101 | 102 | - (nullable NSURL *)sd_backgroundImageURLForState:(UIControlState)state { 103 | return self.imageURLStorage[backgroundImageURLKeyForState(state)]; 104 | } 105 | 106 | - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state { 107 | [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil]; 108 | } 109 | 110 | - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder { 111 | [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil]; 112 | } 113 | 114 | - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options { 115 | [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil]; 116 | } 117 | 118 | - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state completed:(nullable SDExternalCompletionBlock)completedBlock { 119 | [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:completedBlock]; 120 | } 121 | 122 | - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock { 123 | [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:completedBlock]; 124 | } 125 | 126 | - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url 127 | forState:(UIControlState)state 128 | placeholderImage:(nullable UIImage *)placeholder 129 | options:(SDWebImageOptions)options 130 | completed:(nullable SDExternalCompletionBlock)completedBlock { 131 | if (!url) { 132 | [self.imageURLStorage removeObjectForKey:backgroundImageURLKeyForState(state)]; 133 | } else { 134 | self.imageURLStorage[backgroundImageURLKeyForState(state)] = url; 135 | } 136 | 137 | __weak typeof(self)weakSelf = self; 138 | [self sd_internalSetImageWithURL:url 139 | placeholderImage:placeholder 140 | options:options 141 | operationKey:[NSString stringWithFormat:@"UIButtonBackgroundImageOperation%@", @(state)] 142 | setImageBlock:^(UIImage *image, NSData *imageData) { 143 | [weakSelf setBackgroundImage:image forState:state]; 144 | } 145 | progress:nil 146 | completed:completedBlock]; 147 | } 148 | 149 | - (void)sd_setImageLoadOperation:(id)operation forState:(UIControlState)state { 150 | [self sd_setImageLoadOperation:operation forKey:[NSString stringWithFormat:@"UIButtonImageOperation%@", @(state)]]; 151 | } 152 | 153 | - (void)sd_cancelImageLoadForState:(UIControlState)state { 154 | [self sd_cancelImageLoadOperationWithKey:[NSString stringWithFormat:@"UIButtonImageOperation%@", @(state)]]; 155 | } 156 | 157 | - (void)sd_setBackgroundImageLoadOperation:(id)operation forState:(UIControlState)state { 158 | [self sd_setImageLoadOperation:operation forKey:[NSString stringWithFormat:@"UIButtonBackgroundImageOperation%@", @(state)]]; 159 | } 160 | 161 | - (void)sd_cancelBackgroundImageLoadForState:(UIControlState)state { 162 | [self sd_cancelImageLoadOperationWithKey:[NSString stringWithFormat:@"UIButtonBackgroundImageOperation%@", @(state)]]; 163 | } 164 | 165 | - (SDStateImageURLDictionary *)imageURLStorage { 166 | SDStateImageURLDictionary *storage = objc_getAssociatedObject(self, &imageURLStorageKey); 167 | if (!storage) { 168 | storage = [NSMutableDictionary dictionary]; 169 | objc_setAssociatedObject(self, &imageURLStorageKey, storage, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 170 | } 171 | 172 | return storage; 173 | } 174 | 175 | @end 176 | 177 | #endif 178 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/UIImage+ForceDecode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "SDWebImageCompat.h" 10 | 11 | @interface UIImage (ForceDecode) 12 | 13 | + (nullable UIImage *)decodedImageWithImage:(nullable UIImage *)image; 14 | 15 | + (nullable UIImage *)decodedAndScaledDownImageWithImage:(nullable UIImage *)image; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/UIImage+ForceDecode.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "UIImage+ForceDecode.h" 10 | #import "SDWebImageCodersManager.h" 11 | 12 | @implementation UIImage (ForceDecode) 13 | 14 | + (UIImage *)decodedImageWithImage:(UIImage *)image { 15 | if (!image) { 16 | return nil; 17 | } 18 | NSData *tempData; 19 | return [[SDWebImageCodersManager sharedInstance] decompressedImageWithImage:image data:&tempData options:@{SDWebImageCoderScaleDownLargeImagesKey: @(NO)}]; 20 | } 21 | 22 | + (UIImage *)decodedAndScaledDownImageWithImage:(UIImage *)image { 23 | if (!image) { 24 | return nil; 25 | } 26 | NSData *tempData; 27 | return [[SDWebImageCodersManager sharedInstance] decompressedImageWithImage:image data:&tempData options:@{SDWebImageCoderScaleDownLargeImagesKey: @(YES)}]; 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/UIImage+GIF.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * (c) Laurin Brandner 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | #import "SDWebImageCompat.h" 11 | 12 | @interface UIImage (GIF) 13 | 14 | /** 15 | * Creates an animated UIImage from an NSData. 16 | * For static GIF, will create an UIImage with `images` array set to nil. For animated GIF, will create an UIImage with valid `images` array. 17 | */ 18 | + (UIImage *)sd_animatedGIFWithData:(NSData *)data; 19 | 20 | /** 21 | * Checks if an UIImage instance is a GIF. Will use the `images` array. 22 | */ 23 | - (BOOL)isGIF; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/UIImage+GIF.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * (c) Laurin Brandner 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | #import "UIImage+GIF.h" 11 | #import "SDWebImageGIFCoder.h" 12 | #import "NSImage+WebCache.h" 13 | 14 | @implementation UIImage (GIF) 15 | 16 | + (UIImage *)sd_animatedGIFWithData:(NSData *)data { 17 | if (!data) { 18 | return nil; 19 | } 20 | return [[SDWebImageGIFCoder sharedCoder] decodedImageWithData:data]; 21 | } 22 | 23 | - (BOOL)isGIF { 24 | return (self.images != nil); 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/UIImage+MultiFormat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "SDWebImageCompat.h" 10 | #import "NSData+ImageContentType.h" 11 | 12 | @interface UIImage (MultiFormat) 13 | 14 | 15 | /** 16 | * For static image format, this value is always 0. 17 | * For animated image format, 0 means infinite looping. 18 | * Note that because of the limitations of categories this property can get out of sync 19 | * if you create another instance with CGImage or other methods. 20 | */ 21 | @property (nonatomic, assign) NSUInteger sd_imageLoopCount; 22 | 23 | + (nullable UIImage *)sd_imageWithData:(nullable NSData *)data; 24 | - (nullable NSData *)sd_imageData; 25 | - (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/UIImage+MultiFormat.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "UIImage+MultiFormat.h" 10 | 11 | #import "objc/runtime.h" 12 | #import "SDWebImageCodersManager.h" 13 | 14 | @implementation UIImage (MultiFormat) 15 | 16 | - (NSUInteger)sd_imageLoopCount { 17 | NSUInteger imageLoopCount = 0; 18 | NSNumber *value = objc_getAssociatedObject(self, @selector(sd_imageLoopCount)); 19 | if ([value isKindOfClass:[NSNumber class]]) { 20 | imageLoopCount = value.unsignedIntegerValue; 21 | } 22 | return imageLoopCount; 23 | } 24 | 25 | - (void)setSd_imageLoopCount:(NSUInteger)sd_imageLoopCount { 26 | NSNumber *value = @(sd_imageLoopCount); 27 | objc_setAssociatedObject(self, @selector(sd_imageLoopCount), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 28 | } 29 | 30 | + (nullable UIImage *)sd_imageWithData:(nullable NSData *)data { 31 | return [[SDWebImageCodersManager sharedInstance] decodedImageWithData:data]; 32 | } 33 | 34 | - (nullable NSData *)sd_imageData { 35 | return [self sd_imageDataAsFormat:SDImageFormatUndefined]; 36 | } 37 | 38 | - (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat { 39 | NSData *imageData = nil; 40 | if (self) { 41 | imageData = [[SDWebImageCodersManager sharedInstance] encodedDataWithImage:self format:imageFormat]; 42 | } 43 | return imageData; 44 | } 45 | 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/UIImage+WebP.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #ifdef SD_WEBP 10 | 11 | #import "SDWebImageCompat.h" 12 | 13 | @interface UIImage (WebP) 14 | 15 | /** 16 | * Get the current WebP image loop count, the default value is 0. 17 | * For static WebP image, the value is 0. 18 | * For animated WebP image, 0 means repeat the animation indefinitely. 19 | * Note that because of the limitations of categories this property can get out of sync 20 | * if you create another instance with CGImage or other methods. 21 | * @return WebP image loop count 22 | * @deprecated use `sd_imageLoopCount` instead. 23 | */ 24 | - (NSInteger)sd_webpLoopCount __deprecated_msg("Method deprecated. Use `sd_imageLoopCount` in `UIImage+MultiFormat.h`"); 25 | 26 | + (nullable UIImage *)sd_imageWithWebPData:(nullable NSData *)data; 27 | 28 | @end 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/UIImage+WebP.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #ifdef SD_WEBP 10 | 11 | #import "UIImage+WebP.h" 12 | #import "SDWebImageWebPCoder.h" 13 | #import "UIImage+MultiFormat.h" 14 | 15 | @implementation UIImage (WebP) 16 | 17 | - (NSInteger)sd_webpLoopCount { 18 | return self.sd_imageLoopCount; 19 | } 20 | 21 | + (nullable UIImage *)sd_imageWithWebPData:(nullable NSData *)data { 22 | if (!data) { 23 | return nil; 24 | } 25 | return [[SDWebImageWebPCoder sharedCoder] decodedImageWithData:data]; 26 | } 27 | 28 | @end 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/UIImageView+HighlightedWebCache.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "SDWebImageCompat.h" 10 | 11 | #if SD_UIKIT 12 | 13 | #import "SDWebImageManager.h" 14 | 15 | /** 16 | * Integrates SDWebImage async downloading and caching of remote images with UIImageView for highlighted state. 17 | */ 18 | @interface UIImageView (HighlightedWebCache) 19 | 20 | /** 21 | * Set the imageView `highlightedImage` with an `url`. 22 | * 23 | * The download is asynchronous and cached. 24 | * 25 | * @param url The url for the image. 26 | */ 27 | - (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url NS_REFINED_FOR_SWIFT; 28 | 29 | /** 30 | * Set the imageView `highlightedImage` with an `url` and custom options. 31 | * 32 | * The download is asynchronous and cached. 33 | * 34 | * @param url The url for the image. 35 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 36 | */ 37 | - (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url 38 | options:(SDWebImageOptions)options NS_REFINED_FOR_SWIFT; 39 | 40 | /** 41 | * Set the imageView `highlightedImage` with an `url`. 42 | * 43 | * The download is asynchronous and cached. 44 | * 45 | * @param url The url for the image. 46 | * @param completedBlock A block called when operation has been completed. This block has no return value 47 | * and takes the requested UIImage as first parameter. In case of error the image parameter 48 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean 49 | * indicating if the image was retrieved from the local cache or from the network. 50 | * The fourth parameter is the original image url. 51 | */ 52 | - (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url 53 | completed:(nullable SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT; 54 | 55 | /** 56 | * Set the imageView `highlightedImage` with an `url` and custom options. 57 | * 58 | * The download is asynchronous and cached. 59 | * 60 | * @param url The url for the image. 61 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 62 | * @param completedBlock A block called when operation has been completed. This block has no return value 63 | * and takes the requested UIImage as first parameter. In case of error the image parameter 64 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean 65 | * indicating if the image was retrieved from the local cache or from the network. 66 | * The fourth parameter is the original image url. 67 | */ 68 | - (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url 69 | options:(SDWebImageOptions)options 70 | completed:(nullable SDExternalCompletionBlock)completedBlock; 71 | 72 | /** 73 | * Set the imageView `highlightedImage` with an `url` and custom options. 74 | * 75 | * The download is asynchronous and cached. 76 | * 77 | * @param url The url for the image. 78 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 79 | * @param progressBlock A block called while image is downloading 80 | * @note the progress block is executed on a background queue 81 | * @param completedBlock A block called when operation has been completed. This block has no return value 82 | * and takes the requested UIImage as first parameter. In case of error the image parameter 83 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean 84 | * indicating if the image was retrieved from the local cache or from the network. 85 | * The fourth parameter is the original image url. 86 | */ 87 | - (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url 88 | options:(SDWebImageOptions)options 89 | progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock 90 | completed:(nullable SDExternalCompletionBlock)completedBlock; 91 | 92 | @end 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/UIImageView+HighlightedWebCache.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "UIImageView+HighlightedWebCache.h" 10 | 11 | #if SD_UIKIT 12 | 13 | #import "UIView+WebCacheOperation.h" 14 | #import "UIView+WebCache.h" 15 | 16 | @implementation UIImageView (HighlightedWebCache) 17 | 18 | - (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url { 19 | [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:nil]; 20 | } 21 | 22 | - (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url options:(SDWebImageOptions)options { 23 | [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:nil]; 24 | } 25 | 26 | - (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock { 27 | [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:completedBlock]; 28 | } 29 | 30 | - (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock { 31 | [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:completedBlock]; 32 | } 33 | 34 | - (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url 35 | options:(SDWebImageOptions)options 36 | progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock 37 | completed:(nullable SDExternalCompletionBlock)completedBlock { 38 | __weak typeof(self)weakSelf = self; 39 | [self sd_internalSetImageWithURL:url 40 | placeholderImage:nil 41 | options:options 42 | operationKey:@"UIImageViewImageOperationHighlighted" 43 | setImageBlock:^(UIImage *image, NSData *imageData) { 44 | weakSelf.highlightedImage = image; 45 | } 46 | progress:progressBlock 47 | completed:completedBlock]; 48 | } 49 | 50 | @end 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/UIImageView+WebCache.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "UIImageView+WebCache.h" 10 | 11 | #if SD_UIKIT || SD_MAC 12 | 13 | #import "objc/runtime.h" 14 | #import "UIView+WebCacheOperation.h" 15 | #import "UIView+WebCache.h" 16 | 17 | @implementation UIImageView (WebCache) 18 | 19 | - (void)sd_setImageWithURL:(nullable NSURL *)url { 20 | [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil]; 21 | } 22 | 23 | - (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder { 24 | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil]; 25 | } 26 | 27 | - (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options { 28 | [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil]; 29 | } 30 | 31 | - (void)sd_setImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock { 32 | [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock]; 33 | } 34 | 35 | - (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock { 36 | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock]; 37 | } 38 | 39 | - (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock { 40 | [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock]; 41 | } 42 | 43 | - (void)sd_setImageWithURL:(nullable NSURL *)url 44 | placeholderImage:(nullable UIImage *)placeholder 45 | options:(SDWebImageOptions)options 46 | progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock 47 | completed:(nullable SDExternalCompletionBlock)completedBlock { 48 | [self sd_internalSetImageWithURL:url 49 | placeholderImage:placeholder 50 | options:options 51 | operationKey:nil 52 | setImageBlock:nil 53 | progress:progressBlock 54 | completed:completedBlock]; 55 | } 56 | 57 | - (void)sd_setImageWithPreviousCachedImageWithURL:(nullable NSURL *)url 58 | placeholderImage:(nullable UIImage *)placeholder 59 | options:(SDWebImageOptions)options 60 | progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock 61 | completed:(nullable SDExternalCompletionBlock)completedBlock { 62 | NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:url]; 63 | UIImage *lastPreviousCachedImage = [[SDImageCache sharedImageCache] imageFromCacheForKey:key]; 64 | 65 | [self sd_setImageWithURL:url placeholderImage:lastPreviousCachedImage ?: placeholder options:options progress:progressBlock completed:completedBlock]; 66 | } 67 | 68 | #if SD_UIKIT 69 | 70 | #pragma mark - Animation of multiple images 71 | 72 | - (void)sd_setAnimationImagesWithURLs:(nonnull NSArray *)arrayOfURLs { 73 | [self sd_cancelCurrentAnimationImagesLoad]; 74 | __weak __typeof(self)wself = self; 75 | 76 | NSMutableArray> *operationsArray = [[NSMutableArray alloc] init]; 77 | 78 | [arrayOfURLs enumerateObjectsUsingBlock:^(NSURL *logoImageURL, NSUInteger idx, BOOL * _Nonnull stop) { 79 | id operation = [SDWebImageManager.sharedManager loadImageWithURL:logoImageURL options:0 progress:nil completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { 80 | if (!wself) return; 81 | dispatch_main_async_safe(^{ 82 | __strong UIImageView *sself = wself; 83 | [sself stopAnimating]; 84 | if (sself && image) { 85 | NSMutableArray *currentImages = [[sself animationImages] mutableCopy]; 86 | if (!currentImages) { 87 | currentImages = [[NSMutableArray alloc] init]; 88 | } 89 | 90 | // We know what index objects should be at when they are returned so 91 | // we will put the object at the index, filling any empty indexes 92 | // with the image that was returned too "early". These images will 93 | // be overwritten. (does not require additional sorting datastructure) 94 | while ([currentImages count] < idx) { 95 | [currentImages addObject:image]; 96 | } 97 | 98 | currentImages[idx] = image; 99 | 100 | sself.animationImages = currentImages; 101 | [sself setNeedsLayout]; 102 | } 103 | [sself startAnimating]; 104 | }); 105 | }]; 106 | [operationsArray addObject:operation]; 107 | }]; 108 | 109 | [self sd_setImageLoadOperation:[operationsArray copy] forKey:@"UIImageViewAnimationImages"]; 110 | } 111 | 112 | - (void)sd_cancelCurrentAnimationImagesLoad { 113 | [self sd_cancelImageLoadOperationWithKey:@"UIImageViewAnimationImages"]; 114 | } 115 | #endif 116 | 117 | @end 118 | 119 | #endif 120 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/UIView+WebCache.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "SDWebImageCompat.h" 10 | 11 | #if SD_UIKIT || SD_MAC 12 | 13 | #import "SDWebImageManager.h" 14 | 15 | typedef void(^SDSetImageBlock)(UIImage * _Nullable image, NSData * _Nullable imageData); 16 | 17 | @interface UIView (WebCache) 18 | 19 | /** 20 | * Get the current image URL. 21 | * 22 | * Note that because of the limitations of categories this property can get out of sync 23 | * if you use setImage: directly. 24 | */ 25 | - (nullable NSURL *)sd_imageURL; 26 | 27 | /** 28 | * Set the imageView `image` with an `url` and optionally a placeholder image. 29 | * 30 | * The download is asynchronous and cached. 31 | * 32 | * @param url The url for the image. 33 | * @param placeholder The image to be set initially, until the image request finishes. 34 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 35 | * @param operationKey A string to be used as the operation key. If nil, will use the class name 36 | * @param setImageBlock Block used for custom set image code 37 | * @param progressBlock A block called while image is downloading 38 | * @note the progress block is executed on a background queue 39 | * @param completedBlock A block called when operation has been completed. This block has no return value 40 | * and takes the requested UIImage as first parameter. In case of error the image parameter 41 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean 42 | * indicating if the image was retrieved from the local cache or from the network. 43 | * The fourth parameter is the original image url. 44 | */ 45 | - (void)sd_internalSetImageWithURL:(nullable NSURL *)url 46 | placeholderImage:(nullable UIImage *)placeholder 47 | options:(SDWebImageOptions)options 48 | operationKey:(nullable NSString *)operationKey 49 | setImageBlock:(nullable SDSetImageBlock)setImageBlock 50 | progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock 51 | completed:(nullable SDExternalCompletionBlock)completedBlock; 52 | 53 | /** 54 | * Cancel the current download 55 | */ 56 | - (void)sd_cancelCurrentImageLoad; 57 | 58 | #if SD_UIKIT 59 | 60 | #pragma mark - Activity indicator 61 | 62 | /** 63 | * Show activity UIActivityIndicatorView 64 | */ 65 | - (void)sd_setShowActivityIndicatorView:(BOOL)show; 66 | 67 | /** 68 | * set desired UIActivityIndicatorViewStyle 69 | * 70 | * @param style The style of the UIActivityIndicatorView 71 | */ 72 | - (void)sd_setIndicatorStyle:(UIActivityIndicatorViewStyle)style; 73 | 74 | - (BOOL)sd_showActivityIndicatorView; 75 | - (void)sd_addActivityIndicator; 76 | - (void)sd_removeActivityIndicator; 77 | 78 | #endif 79 | 80 | @end 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/UIView+WebCache.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "UIView+WebCache.h" 10 | 11 | #if SD_UIKIT || SD_MAC 12 | 13 | #import "objc/runtime.h" 14 | #import "UIView+WebCacheOperation.h" 15 | 16 | static char imageURLKey; 17 | 18 | #if SD_UIKIT 19 | static char TAG_ACTIVITY_INDICATOR; 20 | static char TAG_ACTIVITY_STYLE; 21 | #endif 22 | static char TAG_ACTIVITY_SHOW; 23 | 24 | @implementation UIView (WebCache) 25 | 26 | - (nullable NSURL *)sd_imageURL { 27 | return objc_getAssociatedObject(self, &imageURLKey); 28 | } 29 | 30 | - (void)sd_internalSetImageWithURL:(nullable NSURL *)url 31 | placeholderImage:(nullable UIImage *)placeholder 32 | options:(SDWebImageOptions)options 33 | operationKey:(nullable NSString *)operationKey 34 | setImageBlock:(nullable SDSetImageBlock)setImageBlock 35 | progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock 36 | completed:(nullable SDExternalCompletionBlock)completedBlock { 37 | NSString *validOperationKey = operationKey ?: NSStringFromClass([self class]); 38 | [self sd_cancelImageLoadOperationWithKey:validOperationKey]; 39 | objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 40 | 41 | if (!(options & SDWebImageDelayPlaceholder)) { 42 | dispatch_main_async_safe(^{ 43 | [self sd_setImage:placeholder imageData:nil basedOnClassOrViaCustomSetImageBlock:setImageBlock]; 44 | }); 45 | } 46 | 47 | if (url) { 48 | // check if activityView is enabled or not 49 | if ([self sd_showActivityIndicatorView]) { 50 | [self sd_addActivityIndicator]; 51 | } 52 | 53 | __weak __typeof(self)wself = self; 54 | id operation = [SDWebImageManager.sharedManager loadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { 55 | __strong __typeof (wself) sself = wself; 56 | [sself sd_removeActivityIndicator]; 57 | if (!sself) { 58 | return; 59 | } 60 | dispatch_main_async_safe(^{ 61 | if (!sself) { 62 | return; 63 | } 64 | if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock) { 65 | completedBlock(image, error, cacheType, url); 66 | return; 67 | } else if (image) { 68 | [sself sd_setImage:image imageData:data basedOnClassOrViaCustomSetImageBlock:setImageBlock]; 69 | [sself sd_setNeedsLayout]; 70 | } else { 71 | if ((options & SDWebImageDelayPlaceholder)) { 72 | [sself sd_setImage:placeholder imageData:nil basedOnClassOrViaCustomSetImageBlock:setImageBlock]; 73 | [sself sd_setNeedsLayout]; 74 | } 75 | } 76 | if (completedBlock && finished) { 77 | completedBlock(image, error, cacheType, url); 78 | } 79 | }); 80 | }]; 81 | [self sd_setImageLoadOperation:operation forKey:validOperationKey]; 82 | } else { 83 | dispatch_main_async_safe(^{ 84 | [self sd_removeActivityIndicator]; 85 | if (completedBlock) { 86 | NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}]; 87 | completedBlock(nil, error, SDImageCacheTypeNone, url); 88 | } 89 | }); 90 | } 91 | } 92 | 93 | - (void)sd_cancelCurrentImageLoad { 94 | [self sd_cancelImageLoadOperationWithKey:NSStringFromClass([self class])]; 95 | } 96 | 97 | - (void)sd_setImage:(UIImage *)image imageData:(NSData *)imageData basedOnClassOrViaCustomSetImageBlock:(SDSetImageBlock)setImageBlock { 98 | if (setImageBlock) { 99 | setImageBlock(image, imageData); 100 | return; 101 | } 102 | 103 | #if SD_UIKIT || SD_MAC 104 | if ([self isKindOfClass:[UIImageView class]]) { 105 | UIImageView *imageView = (UIImageView *)self; 106 | imageView.image = image; 107 | } 108 | #endif 109 | 110 | #if SD_UIKIT 111 | if ([self isKindOfClass:[UIButton class]]) { 112 | UIButton *button = (UIButton *)self; 113 | [button setImage:image forState:UIControlStateNormal]; 114 | } 115 | #endif 116 | } 117 | 118 | - (void)sd_setNeedsLayout { 119 | #if SD_UIKIT 120 | [self setNeedsLayout]; 121 | #elif SD_MAC 122 | [self setNeedsLayout:YES]; 123 | #endif 124 | } 125 | 126 | #pragma mark - Activity indicator 127 | 128 | #pragma mark - 129 | #if SD_UIKIT 130 | - (UIActivityIndicatorView *)activityIndicator { 131 | return (UIActivityIndicatorView *)objc_getAssociatedObject(self, &TAG_ACTIVITY_INDICATOR); 132 | } 133 | 134 | - (void)setActivityIndicator:(UIActivityIndicatorView *)activityIndicator { 135 | objc_setAssociatedObject(self, &TAG_ACTIVITY_INDICATOR, activityIndicator, OBJC_ASSOCIATION_RETAIN); 136 | } 137 | #endif 138 | 139 | - (void)sd_setShowActivityIndicatorView:(BOOL)show { 140 | objc_setAssociatedObject(self, &TAG_ACTIVITY_SHOW, @(show), OBJC_ASSOCIATION_RETAIN); 141 | } 142 | 143 | - (BOOL)sd_showActivityIndicatorView { 144 | return [objc_getAssociatedObject(self, &TAG_ACTIVITY_SHOW) boolValue]; 145 | } 146 | 147 | #if SD_UIKIT 148 | - (void)sd_setIndicatorStyle:(UIActivityIndicatorViewStyle)style{ 149 | objc_setAssociatedObject(self, &TAG_ACTIVITY_STYLE, [NSNumber numberWithInt:style], OBJC_ASSOCIATION_RETAIN); 150 | } 151 | 152 | - (int)sd_getIndicatorStyle{ 153 | return [objc_getAssociatedObject(self, &TAG_ACTIVITY_STYLE) intValue]; 154 | } 155 | #endif 156 | 157 | - (void)sd_addActivityIndicator { 158 | #if SD_UIKIT 159 | dispatch_main_async_safe(^{ 160 | if (!self.activityIndicator) { 161 | self.activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:[self sd_getIndicatorStyle]]; 162 | self.activityIndicator.translatesAutoresizingMaskIntoConstraints = NO; 163 | 164 | [self addSubview:self.activityIndicator]; 165 | 166 | [self addConstraint:[NSLayoutConstraint constraintWithItem:self.activityIndicator 167 | attribute:NSLayoutAttributeCenterX 168 | relatedBy:NSLayoutRelationEqual 169 | toItem:self 170 | attribute:NSLayoutAttributeCenterX 171 | multiplier:1.0 172 | constant:0.0]]; 173 | [self addConstraint:[NSLayoutConstraint constraintWithItem:self.activityIndicator 174 | attribute:NSLayoutAttributeCenterY 175 | relatedBy:NSLayoutRelationEqual 176 | toItem:self 177 | attribute:NSLayoutAttributeCenterY 178 | multiplier:1.0 179 | constant:0.0]]; 180 | } 181 | [self.activityIndicator startAnimating]; 182 | }); 183 | #endif 184 | } 185 | 186 | - (void)sd_removeActivityIndicator { 187 | #if SD_UIKIT 188 | dispatch_main_async_safe(^{ 189 | if (self.activityIndicator) { 190 | [self.activityIndicator removeFromSuperview]; 191 | self.activityIndicator = nil; 192 | } 193 | }); 194 | #endif 195 | } 196 | 197 | @end 198 | 199 | #endif 200 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/UIView+WebCacheOperation.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "SDWebImageCompat.h" 10 | 11 | #if SD_UIKIT || SD_MAC 12 | 13 | #import "SDWebImageManager.h" 14 | 15 | @interface UIView (WebCacheOperation) 16 | 17 | /** 18 | * Set the image load operation (storage in a UIView based dictionary) 19 | * 20 | * @param operation the operation 21 | * @param key key for storing the operation 22 | */ 23 | - (void)sd_setImageLoadOperation:(nullable id)operation forKey:(nullable NSString *)key; 24 | 25 | /** 26 | * Cancel all operations for the current UIView and key 27 | * 28 | * @param key key for identifying the operations 29 | */ 30 | - (void)sd_cancelImageLoadOperationWithKey:(nullable NSString *)key; 31 | 32 | /** 33 | * Just remove the operations corresponding to the current UIView and key without cancelling them 34 | * 35 | * @param key key for identifying the operations 36 | */ 37 | - (void)sd_removeImageLoadOperationWithKey:(nullable NSString *)key; 38 | 39 | @end 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/SDWebImage/UIView+WebCacheOperation.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "UIView+WebCacheOperation.h" 10 | 11 | #if SD_UIKIT || SD_MAC 12 | 13 | #import "objc/runtime.h" 14 | 15 | static char loadOperationKey; 16 | 17 | typedef NSMutableDictionary SDOperationsDictionary; 18 | 19 | @implementation UIView (WebCacheOperation) 20 | 21 | - (SDOperationsDictionary *)operationDictionary { 22 | SDOperationsDictionary *operations = objc_getAssociatedObject(self, &loadOperationKey); 23 | if (operations) { 24 | return operations; 25 | } 26 | operations = [NSMutableDictionary dictionary]; 27 | objc_setAssociatedObject(self, &loadOperationKey, operations, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 28 | return operations; 29 | } 30 | 31 | - (void)sd_setImageLoadOperation:(nullable id)operation forKey:(nullable NSString *)key { 32 | if (key) { 33 | [self sd_cancelImageLoadOperationWithKey:key]; 34 | if (operation) { 35 | SDOperationsDictionary *operationDictionary = [self operationDictionary]; 36 | operationDictionary[key] = operation; 37 | } 38 | } 39 | } 40 | 41 | - (void)sd_cancelImageLoadOperationWithKey:(nullable NSString *)key { 42 | // Cancel in progress downloader from queue 43 | SDOperationsDictionary *operationDictionary = [self operationDictionary]; 44 | id operations = operationDictionary[key]; 45 | if (operations) { 46 | if ([operations isKindOfClass:[NSArray class]]) { 47 | for (id operation in operations) { 48 | if (operation) { 49 | [operation cancel]; 50 | } 51 | } 52 | } else if ([operations conformsToProtocol:@protocol(SDWebImageOperation)]){ 53 | [(id) operations cancel]; 54 | } 55 | [operationDictionary removeObjectForKey:key]; 56 | } 57 | } 58 | 59 | - (void)sd_removeImageLoadOperationWithKey:(nullable NSString *)key { 60 | if (key) { 61 | SDOperationsDictionary *operationDictionary = [self operationDictionary]; 62 | [operationDictionary removeObjectForKey:key]; 63 | } 64 | } 65 | 66 | @end 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/Vendor/YYModel/YYModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // YYModel.h 3 | // YYModel 4 | // 5 | // Created by ibireme on 15/5/10. 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 YYModelVersionNumber; 16 | FOUNDATION_EXPORT const unsigned char YYModelVersionString[]; 17 | #import 18 | #import 19 | #else 20 | #import "NSObject+YYModel.h" 21 | #import "YYClassInfo.h" 22 | #endif 23 | -------------------------------------------------------------------------------- /AutoLayout进阶(五)UITableViewCell自动高度/AutoLayout进阶(五)UITableViewCell自动高度/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // AutoLayout进阶(五)UITableViewCell自动高度 4 | // 5 | // Created by zhuxiaohui on 2017/11/22. 6 | // Copyright © 2017年 com.it7090. 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 | -------------------------------------------------------------------------------- /AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用/AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用/AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用 4 | // 5 | // Created by zhuxiaohui on 2017/11/19. 6 | // Copyright © 2017年 com.it7090. All rights reserved. 7 | // https://github.com/CoderZhuXH/AutoLayout 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用/AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用 4 | // 5 | // Created by zhuxiaohui on 2017/11/19. 6 | // Copyright © 2017年 com.it7090. All rights reserved. 7 | // https://github.com/CoderZhuXH/AutoLayout 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用/AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用/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 | } -------------------------------------------------------------------------------- /AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用/AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用/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 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用/AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用/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 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 47 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用/AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用/AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用 4 | // 5 | // Created by zhuxiaohui on 2017/11/19. 6 | // Copyright © 2017年 com.it7090. All rights reserved. 7 | // https://github.com/CoderZhuXH/AutoLayout 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用/AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用 4 | // 5 | // Created by zhuxiaohui on 2017/11/19. 6 | // Copyright © 2017年 com.it7090. All rights reserved. 7 | // https://github.com/CoderZhuXH/AutoLayout 8 | 9 | #import "ViewController.h" 10 | 11 | static NSString *const NameText = @"长昵称这是一个很长的昵称"; 12 | static NSInteger changeLength = -1;//记录单次变化长度 13 | 14 | @interface ViewController () 15 | @property (weak, nonatomic) IBOutlet UILabel *nameLab; 16 | @property (weak, nonatomic) IBOutlet UILabel *timeLab; 17 | 18 | @end 19 | 20 | @implementation ViewController 21 | 22 | - (void)viewDidLoad { 23 | [super viewDidLoad]; 24 | 25 | _nameLab.text = NameText; 26 | _timeLab.text = @"一周以前"; 27 | 28 | [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(action) userInfo:nil repeats:YES]; 29 | } 30 | 31 | -(void)action{ 32 | /** 当前昵称 */ 33 | NSString *name = [NameText substringToIndex:_nameLab.text.length+changeLength]; 34 | NSLog(@"当前昵称:\n%@",name); 35 | 36 | _nameLab.text = name;//设置昵称 37 | 38 | if(_nameLab.text.length<=3){//最小宽度 39 | changeLength = 1; 40 | }else if(_nameLab.text.length==NameText.length){//最大宽度 41 | changeLength = -1;; 42 | } 43 | } 44 | 45 | 46 | - (void)didReceiveMemoryWarning { 47 | [super didReceiveMemoryWarning]; 48 | // Dispose of any resources that can be recreated. 49 | } 50 | 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用/AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用/icon.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderZhuXH/AutoLayout/ee78cf85c2ff608c7d53db1793d8bd3b77861e8e/AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用/AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用/icon.jpeg -------------------------------------------------------------------------------- /AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用/AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // AutoLayout进阶(四)Content Hugging Priority和Content Compression Resistance Priority综合运用 4 | // 5 | // Created by zhuxiaohui on 2017/11/19. 6 | // Copyright © 2017年 com.it7090. 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 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 CoderZhuXH 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AutoLayout 2 | 3 | ### 此项目主要介绍AutoLayout的一些进阶用法 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 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 |
日期文章标题Demo名称文章链接
2017.11.19AutoLayout进阶(一)
Aspect Ratio
AutoLayout进阶(一)
Aspect Ratio
博客链接

简书链接
2017.11.19AutoLayout进阶(二)
Content Hugging Priority
AutoLayout进阶(二)
Content Hugging Priority
博客链接

简书链接
2017.11.19AutoLayout进阶(三)
Content Compression Resistance Priority
AutoLayout进阶(三)
Content Compression Resistance Priority
博客链接

简书链接
2017.11.19AutoLayout进阶(四)
Content Hugging Priority和
Content Compression Resistance Priority
综合运用
AAutoLayout进阶(四)
Content Hugging Priority和
Content Compression Resistance Priority
综合运用
博客链接

简书链接
2017.11.28AutoLayout进阶(五)
UITableViewCell自动高度
AutoLayout进阶(五)
UITableViewCell自动高度
博客链接

简书链接
--------------------------------------------------------------------------------