├── .DS_Store ├── .gitattributes ├── PageController.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── lchenxi.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── lchenxi.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── PageController.xcscheme │ └── xcschememanagement.plist ├── PageController ├── .DS_Store ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── category_edit_add.imageset │ │ ├── Contents.json │ │ ├── category_edit_add@2x.png │ │ └── category_edit_add@3x.png │ ├── category_edit_delect.imageset │ │ ├── Contents.json │ │ ├── category_edit_delect@2x.png │ │ └── category_edit_delect@3x.png │ ├── category_edit_recommend.imageset │ │ ├── Contents.json │ │ ├── category_edit_recommend@2x.png │ │ └── category_edit_recommend@3x.png │ ├── courseVC_item_mask.imageset │ │ ├── Contents.json │ │ ├── courseVC_item_mask@2x.png │ │ └── courseVC_item_mask@3x.png │ ├── courseVC_item_open.imageset │ │ ├── Contents.json │ │ ├── courseVC_item_open@2x.png │ │ └── courseVC_item_open@3x.png │ ├── courseVC_item_vip.imageset │ │ ├── Contents.json │ │ ├── courseVC_item_vip@2x.png │ │ └── courseVC_item_vip@3x.png │ ├── main_homeHead_livingCourse.imageset │ │ ├── Contents.json │ │ ├── main_homeHead_livingCourse@2x.png │ │ └── main_homeHead_livingCourse@3x.png │ ├── main_homeHead_openCourse.imageset │ │ ├── Contents.json │ │ ├── main_homeHead_openCourse@2x.png │ │ └── main_homeHead_openCourse@3x.png │ ├── main_homeHead_skill.imageset │ │ ├── Contents.json │ │ ├── main_homeHead_skill@2x.png │ │ └── main_homeHead_skill@3x.png │ ├── main_homeHead_vipCourse.imageset │ │ ├── Contents.json │ │ ├── main_homeHead_vipCourse@2x.png │ │ └── main_homeHead_vipCourse@3x.png │ ├── main_nav_more.imageset │ │ ├── Contents.json │ │ ├── main_nav_more@2x.png │ │ └── main_nav_more@3x.png │ ├── main_nav_search.imageset │ │ ├── Contents.json │ │ ├── main_nav_search@2x.png │ │ └── main_nav_search@3x.png │ ├── main_nav_whiteMask.imageset │ │ ├── Contents.json │ │ ├── main_nav_whiteMask@2x.png │ │ └── main_nav_whiteMask@3x.png │ ├── recommend_living_left.imageset │ │ ├── Contents.json │ │ ├── recommend_living_left@2x.png │ │ └── recommend_living_left@3x.png │ ├── recommend_living_right.imageset │ │ ├── Contents.json │ │ ├── recommend_living_right@2x.png │ │ └── recommend_living_right@3x.png │ └── recommend_voice_ border.imageset │ │ ├── Contents.json │ │ ├── recommend_voice_ border@2x.png │ │ └── recommend_voice_ border@3x.png ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── Masonry │ ├── Info.plist │ ├── MASCompositeConstraint.h │ ├── MASCompositeConstraint.m │ ├── MASConstraint+Private.h │ ├── MASConstraint.h │ ├── MASConstraint.m │ ├── MASConstraintMaker.h │ ├── MASConstraintMaker.m │ ├── MASLayoutConstraint.h │ ├── MASLayoutConstraint.m │ ├── MASUtilities.h │ ├── MASViewAttribute.h │ ├── MASViewAttribute.m │ ├── MASViewConstraint.h │ ├── MASViewConstraint.m │ ├── Masonry.h │ ├── NSArray+MASAdditions.h │ ├── NSArray+MASAdditions.m │ ├── NSArray+MASShorthandAdditions.h │ ├── NSLayoutConstraint+MASDebugAdditions.h │ ├── NSLayoutConstraint+MASDebugAdditions.m │ ├── View+MASAdditions.h │ ├── View+MASAdditions.m │ ├── View+MASShorthandAdditions.h │ ├── ViewController+MASAdditions.h │ └── ViewController+MASAdditions.m ├── PrefixHeader.pch ├── SDCycleScrollView │ ├── NSString+Common.h │ ├── NSString+Common.m │ ├── PageControl │ │ ├── TAAbstractDotView.h │ │ ├── TAAbstractDotView.m │ │ ├── TAAnimatedDotView.h │ │ ├── TAAnimatedDotView.m │ │ ├── TADotView.h │ │ ├── TADotView.m │ │ ├── TAPageControl.h │ │ └── TAPageControl.m │ ├── SDCollectionViewCell.h │ ├── SDCollectionViewCell.m │ ├── SDCycleScrollView.h │ ├── SDCycleScrollView.m │ ├── UIColor+Hex.h │ ├── UIColor+Hex.m │ ├── UIImage+Alpha.h │ ├── UIImage+Alpha.m │ ├── UIImage+Common.h │ ├── UIImage+Common.m │ ├── UIView+SDExtension.h │ ├── UIView+SDExtension.m │ ├── UIViewController+ChildViewController.h │ └── UIViewController+ChildViewController.m ├── SDWebImage │ ├── FLAnimatedImage │ │ ├── FLAnimatedImage.h │ │ ├── FLAnimatedImage.m │ │ ├── FLAnimatedImageView+WebCache.h │ │ ├── FLAnimatedImageView+WebCache.m │ │ ├── FLAnimatedImageView.h │ │ └── FLAnimatedImageView.m │ ├── 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 │ ├── SDWebImageCompat.h │ ├── SDWebImageCompat.m │ ├── SDWebImageDecoder.h │ ├── SDWebImageDecoder.m │ ├── SDWebImageDownloader.h │ ├── SDWebImageDownloader.m │ ├── SDWebImageDownloaderOperation.h │ ├── SDWebImageDownloaderOperation.m │ ├── SDWebImageHeaders.h │ ├── SDWebImageManager.h │ ├── SDWebImageManager.m │ ├── SDWebImageOperation.h │ ├── SDWebImagePrefetcher.h │ ├── SDWebImagePrefetcher.m │ ├── UIButton+WebCache.h │ ├── UIButton+WebCache.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 ├── TabbarIcon │ ├── Me_shareFriends@2x.png │ ├── Me_shareFriends@3x.png │ ├── back_icon@2x.png │ ├── back_icon_active@2x.png │ ├── home@2x.png │ ├── shareArrow@2x.png │ ├── shareArrow@3x.png │ ├── tabbar_BBS@2x.png │ ├── tabbar_BBS@3x.png │ ├── tabbar_BBS_highlighted@2x.png │ ├── tabbar_BBS_highlighted@3x.png │ ├── tabbar_homePage@2x.png │ ├── tabbar_homePage@3x.png │ ├── tabbar_homePage_highlighted@2x.png │ ├── tabbar_homePage_highlighted@3x.png │ ├── tabbar_me@2x.png │ ├── tabbar_me@3x.png │ ├── tabbar_me_highlighted@2x.png │ ├── tabbar_me_highlighted@3x.png │ ├── tabbar_myCourse@2x.png │ ├── tabbar_myCourse@3x.png │ ├── tabbar_myCourse_highlighted@2x.png │ └── tabbar_myCourse_highlighted@3x.png ├── ViewController.h ├── ViewController.m ├── XLChannelControl │ ├── XLChannelControl.h │ ├── XLChannelControl.m │ ├── XLChannelHeader.h │ ├── XLChannelHeader.m │ ├── XLChannelItem.h │ ├── XLChannelItem.m │ ├── XLChannelView.h │ └── XLChannelView.m ├── XSBaseTableViewCell.h ├── XSBaseTableViewCell.m ├── XSCourseCategoryVC.h ├── XSCourseCategoryVC.m ├── XSCourseCollectionViewCell.h ├── XSCourseCollectionViewCell.m ├── XSHomeHeadView.h ├── XSHomeHeadView.m ├── XSHomePageVC.h ├── XSHomePageVC.m ├── XSMyTabar.h ├── XSMyTabar.m ├── XSNavCourseReusableView.h ├── XSNavCourseReusableView.m ├── XSNavCouseChoseView.h ├── XSNavCouseChoseView.m ├── XSRecommendCell.h ├── XSRecommendCell.m ├── XSRecommendVC.h ├── XSRecommendVC.m ├── XSTabbarMainVC.h ├── XSTabbarMainVC.m └── main.m ├── PageControllerTests ├── Info.plist └── PageControllerTests.m ├── PageControllerUITests ├── Info.plist └── PageControllerUITests.m ├── README.md └── image ├── .DS_Store ├── demo.gif ├── demo2.jpg ├── demo3.gif └── demo4.gif /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/.DS_Store -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto -------------------------------------------------------------------------------- /PageController.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PageController.xcodeproj/project.xcworkspace/xcuserdata/lchenxi.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController.xcodeproj/project.xcworkspace/xcuserdata/lchenxi.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /PageController.xcodeproj/xcuserdata/lchenxi.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /PageController.xcodeproj/xcuserdata/lchenxi.xcuserdatad/xcschemes/PageController.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /PageController.xcodeproj/xcuserdata/lchenxi.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | PageController.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | A953CD421F95BA48002D034F 16 | 17 | primary 18 | 19 | 20 | A953CD5B1F95BA48002D034F 21 | 22 | primary 23 | 24 | 25 | A953CD661F95BA48002D034F 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /PageController/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/.DS_Store -------------------------------------------------------------------------------- /PageController/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // PageController 4 | // 5 | // Created by L_晨曦 on 2017/10/17. 6 | // Copyright © 2017年 L_晨曦. 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 | -------------------------------------------------------------------------------- /PageController/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // PageController 4 | // 5 | // Created by L_晨曦 on 2017/10/17. 6 | // Copyright © 2017年 L_晨曦. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "XSTabbarMainVC.h" 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | 20 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 21 | self.window.backgroundColor = [UIColor whiteColor]; 22 | XSTabbarMainVC *barVC = [[XSTabbarMainVC alloc] init]; 23 | self.window.rootViewController = barVC; 24 | [self.window makeKeyAndVisible]; 25 | 26 | 27 | [UINavigationBar appearance].barTintColor = [UIColor whiteColor]; 28 | [UINavigationBar appearance].tintColor = [UIColor blackColor]; 29 | [UINavigationBar appearance].translucent = NO; 30 | 31 | return YES; 32 | } 33 | 34 | 35 | - (void)applicationWillResignActive:(UIApplication *)application { 36 | // 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. 37 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 38 | } 39 | 40 | 41 | - (void)applicationDidEnterBackground:(UIApplication *)application { 42 | // 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. 43 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 44 | } 45 | 46 | 47 | - (void)applicationWillEnterForeground:(UIApplication *)application { 48 | // 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. 49 | } 50 | 51 | 52 | - (void)applicationDidBecomeActive:(UIApplication *)application { 53 | // 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. 54 | } 55 | 56 | 57 | - (void)applicationWillTerminate:(UIApplication *)application { 58 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 59 | } 60 | 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /PageController/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 | } -------------------------------------------------------------------------------- /PageController/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PageController/Assets.xcassets/category_edit_add.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "category_edit_add@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "category_edit_add@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /PageController/Assets.xcassets/category_edit_add.imageset/category_edit_add@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/category_edit_add.imageset/category_edit_add@2x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/category_edit_add.imageset/category_edit_add@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/category_edit_add.imageset/category_edit_add@3x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/category_edit_delect.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "category_edit_delect@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "category_edit_delect@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /PageController/Assets.xcassets/category_edit_delect.imageset/category_edit_delect@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/category_edit_delect.imageset/category_edit_delect@2x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/category_edit_delect.imageset/category_edit_delect@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/category_edit_delect.imageset/category_edit_delect@3x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/category_edit_recommend.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "category_edit_recommend@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "category_edit_recommend@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /PageController/Assets.xcassets/category_edit_recommend.imageset/category_edit_recommend@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/category_edit_recommend.imageset/category_edit_recommend@2x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/category_edit_recommend.imageset/category_edit_recommend@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/category_edit_recommend.imageset/category_edit_recommend@3x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/courseVC_item_mask.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "courseVC_item_mask@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "courseVC_item_mask@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /PageController/Assets.xcassets/courseVC_item_mask.imageset/courseVC_item_mask@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/courseVC_item_mask.imageset/courseVC_item_mask@2x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/courseVC_item_mask.imageset/courseVC_item_mask@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/courseVC_item_mask.imageset/courseVC_item_mask@3x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/courseVC_item_open.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "courseVC_item_open@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "courseVC_item_open@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /PageController/Assets.xcassets/courseVC_item_open.imageset/courseVC_item_open@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/courseVC_item_open.imageset/courseVC_item_open@2x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/courseVC_item_open.imageset/courseVC_item_open@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/courseVC_item_open.imageset/courseVC_item_open@3x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/courseVC_item_vip.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "courseVC_item_vip@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "courseVC_item_vip@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /PageController/Assets.xcassets/courseVC_item_vip.imageset/courseVC_item_vip@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/courseVC_item_vip.imageset/courseVC_item_vip@2x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/courseVC_item_vip.imageset/courseVC_item_vip@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/courseVC_item_vip.imageset/courseVC_item_vip@3x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/main_homeHead_livingCourse.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "main_homeHead_livingCourse@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "main_homeHead_livingCourse@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /PageController/Assets.xcassets/main_homeHead_livingCourse.imageset/main_homeHead_livingCourse@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/main_homeHead_livingCourse.imageset/main_homeHead_livingCourse@2x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/main_homeHead_livingCourse.imageset/main_homeHead_livingCourse@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/main_homeHead_livingCourse.imageset/main_homeHead_livingCourse@3x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/main_homeHead_openCourse.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "main_homeHead_openCourse@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "main_homeHead_openCourse@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /PageController/Assets.xcassets/main_homeHead_openCourse.imageset/main_homeHead_openCourse@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/main_homeHead_openCourse.imageset/main_homeHead_openCourse@2x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/main_homeHead_openCourse.imageset/main_homeHead_openCourse@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/main_homeHead_openCourse.imageset/main_homeHead_openCourse@3x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/main_homeHead_skill.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "main_homeHead_skill@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "main_homeHead_skill@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /PageController/Assets.xcassets/main_homeHead_skill.imageset/main_homeHead_skill@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/main_homeHead_skill.imageset/main_homeHead_skill@2x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/main_homeHead_skill.imageset/main_homeHead_skill@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/main_homeHead_skill.imageset/main_homeHead_skill@3x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/main_homeHead_vipCourse.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "main_homeHead_vipCourse@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "main_homeHead_vipCourse@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /PageController/Assets.xcassets/main_homeHead_vipCourse.imageset/main_homeHead_vipCourse@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/main_homeHead_vipCourse.imageset/main_homeHead_vipCourse@2x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/main_homeHead_vipCourse.imageset/main_homeHead_vipCourse@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/main_homeHead_vipCourse.imageset/main_homeHead_vipCourse@3x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/main_nav_more.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "main_nav_more@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "main_nav_more@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /PageController/Assets.xcassets/main_nav_more.imageset/main_nav_more@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/main_nav_more.imageset/main_nav_more@2x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/main_nav_more.imageset/main_nav_more@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/main_nav_more.imageset/main_nav_more@3x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/main_nav_search.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "main_nav_search@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "main_nav_search@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /PageController/Assets.xcassets/main_nav_search.imageset/main_nav_search@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/main_nav_search.imageset/main_nav_search@2x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/main_nav_search.imageset/main_nav_search@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/main_nav_search.imageset/main_nav_search@3x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/main_nav_whiteMask.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "main_nav_whiteMask@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "main_nav_whiteMask@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /PageController/Assets.xcassets/main_nav_whiteMask.imageset/main_nav_whiteMask@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/main_nav_whiteMask.imageset/main_nav_whiteMask@2x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/main_nav_whiteMask.imageset/main_nav_whiteMask@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/main_nav_whiteMask.imageset/main_nav_whiteMask@3x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/recommend_living_left.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "recommend_living_left@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "recommend_living_left@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /PageController/Assets.xcassets/recommend_living_left.imageset/recommend_living_left@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/recommend_living_left.imageset/recommend_living_left@2x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/recommend_living_left.imageset/recommend_living_left@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/recommend_living_left.imageset/recommend_living_left@3x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/recommend_living_right.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "recommend_living_right@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "recommend_living_right@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /PageController/Assets.xcassets/recommend_living_right.imageset/recommend_living_right@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/recommend_living_right.imageset/recommend_living_right@2x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/recommend_living_right.imageset/recommend_living_right@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/recommend_living_right.imageset/recommend_living_right@3x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/recommend_voice_ border.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "recommend_voice_ border@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "recommend_voice_ border@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /PageController/Assets.xcassets/recommend_voice_ border.imageset/recommend_voice_ border@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/recommend_voice_ border.imageset/recommend_voice_ border@2x.png -------------------------------------------------------------------------------- /PageController/Assets.xcassets/recommend_voice_ border.imageset/recommend_voice_ border@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/Assets.xcassets/recommend_voice_ border.imageset/recommend_voice_ border@3x.png -------------------------------------------------------------------------------- /PageController/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 | -------------------------------------------------------------------------------- /PageController/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 | -------------------------------------------------------------------------------- /PageController/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /PageController/Masonry/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /PageController/Masonry/MASCompositeConstraint.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASCompositeConstraint.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 21/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASConstraint.h" 10 | #import "MASUtilities.h" 11 | 12 | /** 13 | * A group of MASConstraint objects 14 | */ 15 | @interface MASCompositeConstraint : MASConstraint 16 | 17 | /** 18 | * Creates a composite with a predefined array of children 19 | * 20 | * @param children child MASConstraints 21 | * 22 | * @return a composite constraint 23 | */ 24 | - (id)initWithChildren:(NSArray *)children; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /PageController/Masonry/MASCompositeConstraint.m: -------------------------------------------------------------------------------- 1 | // 2 | // MASCompositeConstraint.m 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 21/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASCompositeConstraint.h" 10 | #import "MASConstraint+Private.h" 11 | 12 | @interface MASCompositeConstraint () 13 | 14 | @property (nonatomic, strong) id mas_key; 15 | @property (nonatomic, strong) NSMutableArray *childConstraints; 16 | 17 | @end 18 | 19 | @implementation MASCompositeConstraint 20 | 21 | - (id)initWithChildren:(NSArray *)children { 22 | self = [super init]; 23 | if (!self) return nil; 24 | 25 | _childConstraints = [children mutableCopy]; 26 | for (MASConstraint *constraint in _childConstraints) { 27 | constraint.delegate = self; 28 | } 29 | 30 | return self; 31 | } 32 | 33 | #pragma mark - MASConstraintDelegate 34 | 35 | - (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint { 36 | NSUInteger index = [self.childConstraints indexOfObject:constraint]; 37 | NSAssert(index != NSNotFound, @"Could not find constraint %@", constraint); 38 | [self.childConstraints replaceObjectAtIndex:index withObject:replacementConstraint]; 39 | } 40 | 41 | - (MASConstraint *)constraint:(MASConstraint __unused *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute { 42 | id strongDelegate = self.delegate; 43 | MASConstraint *newConstraint = [strongDelegate constraint:self addConstraintWithLayoutAttribute:layoutAttribute]; 44 | newConstraint.delegate = self; 45 | [self.childConstraints addObject:newConstraint]; 46 | return newConstraint; 47 | } 48 | 49 | #pragma mark - NSLayoutConstraint multiplier proxies 50 | 51 | - (MASConstraint * (^)(CGFloat))multipliedBy { 52 | return ^id(CGFloat multiplier) { 53 | for (MASConstraint *constraint in self.childConstraints) { 54 | constraint.multipliedBy(multiplier); 55 | } 56 | return self; 57 | }; 58 | } 59 | 60 | - (MASConstraint * (^)(CGFloat))dividedBy { 61 | return ^id(CGFloat divider) { 62 | for (MASConstraint *constraint in self.childConstraints) { 63 | constraint.dividedBy(divider); 64 | } 65 | return self; 66 | }; 67 | } 68 | 69 | #pragma mark - MASLayoutPriority proxy 70 | 71 | - (MASConstraint * (^)(MASLayoutPriority))priority { 72 | return ^id(MASLayoutPriority priority) { 73 | for (MASConstraint *constraint in self.childConstraints) { 74 | constraint.priority(priority); 75 | } 76 | return self; 77 | }; 78 | } 79 | 80 | #pragma mark - NSLayoutRelation proxy 81 | 82 | - (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation { 83 | return ^id(id attr, NSLayoutRelation relation) { 84 | for (MASConstraint *constraint in self.childConstraints.copy) { 85 | constraint.equalToWithRelation(attr, relation); 86 | } 87 | return self; 88 | }; 89 | } 90 | 91 | #pragma mark - attribute chaining 92 | 93 | - (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute { 94 | [self constraint:self addConstraintWithLayoutAttribute:layoutAttribute]; 95 | return self; 96 | } 97 | 98 | #pragma mark - Animator proxy 99 | 100 | #if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV) 101 | 102 | - (MASConstraint *)animator { 103 | for (MASConstraint *constraint in self.childConstraints) { 104 | [constraint animator]; 105 | } 106 | return self; 107 | } 108 | 109 | #endif 110 | 111 | #pragma mark - debug helpers 112 | 113 | - (MASConstraint * (^)(id))key { 114 | return ^id(id key) { 115 | self.mas_key = key; 116 | int i = 0; 117 | for (MASConstraint *constraint in self.childConstraints) { 118 | constraint.key([NSString stringWithFormat:@"%@[%d]", key, i++]); 119 | } 120 | return self; 121 | }; 122 | } 123 | 124 | #pragma mark - NSLayoutConstraint constant setters 125 | 126 | - (void)setInsets:(MASEdgeInsets)insets { 127 | for (MASConstraint *constraint in self.childConstraints) { 128 | constraint.insets = insets; 129 | } 130 | } 131 | 132 | - (void)setOffset:(CGFloat)offset { 133 | for (MASConstraint *constraint in self.childConstraints) { 134 | constraint.offset = offset; 135 | } 136 | } 137 | 138 | - (void)setSizeOffset:(CGSize)sizeOffset { 139 | for (MASConstraint *constraint in self.childConstraints) { 140 | constraint.sizeOffset = sizeOffset; 141 | } 142 | } 143 | 144 | - (void)setCenterOffset:(CGPoint)centerOffset { 145 | for (MASConstraint *constraint in self.childConstraints) { 146 | constraint.centerOffset = centerOffset; 147 | } 148 | } 149 | 150 | #pragma mark - MASConstraint 151 | 152 | - (void)activate { 153 | for (MASConstraint *constraint in self.childConstraints) { 154 | [constraint activate]; 155 | } 156 | } 157 | 158 | - (void)deactivate { 159 | for (MASConstraint *constraint in self.childConstraints) { 160 | [constraint deactivate]; 161 | } 162 | } 163 | 164 | - (void)install { 165 | for (MASConstraint *constraint in self.childConstraints) { 166 | constraint.updateExisting = self.updateExisting; 167 | [constraint install]; 168 | } 169 | } 170 | 171 | - (void)uninstall { 172 | for (MASConstraint *constraint in self.childConstraints) { 173 | [constraint uninstall]; 174 | } 175 | } 176 | 177 | @end 178 | -------------------------------------------------------------------------------- /PageController/Masonry/MASConstraint+Private.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASConstraint+Private.h 3 | // Masonry 4 | // 5 | // Created by Nick Tymchenko on 29/04/14. 6 | // Copyright (c) 2014 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASConstraint.h" 10 | 11 | @protocol MASConstraintDelegate; 12 | 13 | 14 | @interface MASConstraint () 15 | 16 | /** 17 | * Whether or not to check for an existing constraint instead of adding constraint 18 | */ 19 | @property (nonatomic, assign) BOOL updateExisting; 20 | 21 | /** 22 | * Usually MASConstraintMaker but could be a parent MASConstraint 23 | */ 24 | @property (nonatomic, weak) id delegate; 25 | 26 | /** 27 | * Based on a provided value type, is equal to calling: 28 | * NSNumber - setOffset: 29 | * NSValue with CGPoint - setPointOffset: 30 | * NSValue with CGSize - setSizeOffset: 31 | * NSValue with MASEdgeInsets - setInsets: 32 | */ 33 | - (void)setLayoutConstantWithValue:(NSValue *)value; 34 | 35 | @end 36 | 37 | 38 | @interface MASConstraint (Abstract) 39 | 40 | /** 41 | * Sets the constraint relation to given NSLayoutRelation 42 | * returns a block which accepts one of the following: 43 | * MASViewAttribute, UIView, NSValue, NSArray 44 | * see readme for more details. 45 | */ 46 | - (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation; 47 | 48 | /** 49 | * Override to set a custom chaining behaviour 50 | */ 51 | - (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute; 52 | 53 | @end 54 | 55 | 56 | @protocol MASConstraintDelegate 57 | 58 | /** 59 | * Notifies the delegate when the constraint needs to be replaced with another constraint. For example 60 | * A MASViewConstraint may turn into a MASCompositeConstraint when an array is passed to one of the equality blocks 61 | */ 62 | - (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint; 63 | 64 | - (MASConstraint *)constraint:(MASConstraint *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute; 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /PageController/Masonry/MASLayoutConstraint.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASLayoutConstraint.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 3/08/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "MASUtilities.h" 10 | 11 | /** 12 | * When you are debugging or printing the constraints attached to a view this subclass 13 | * makes it easier to identify which constraints have been created via Masonry 14 | */ 15 | @interface MASLayoutConstraint : NSLayoutConstraint 16 | 17 | /** 18 | * a key to associate with this constraint 19 | */ 20 | @property (nonatomic, strong) id mas_key; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /PageController/Masonry/MASLayoutConstraint.m: -------------------------------------------------------------------------------- 1 | // 2 | // MASLayoutConstraint.m 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 3/08/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "MASLayoutConstraint.h" 10 | 11 | @implementation MASLayoutConstraint 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PageController/Masonry/MASViewAttribute.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASAttribute.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 21/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASUtilities.h" 10 | 11 | /** 12 | * An immutable tuple which stores the view and the related NSLayoutAttribute. 13 | * Describes part of either the left or right hand side of a constraint equation 14 | */ 15 | @interface MASViewAttribute : NSObject 16 | 17 | /** 18 | * The view which the reciever relates to. Can be nil if item is not a view. 19 | */ 20 | @property (nonatomic, weak, readonly) MAS_VIEW *view; 21 | 22 | /** 23 | * The item which the reciever relates to. 24 | */ 25 | @property (nonatomic, weak, readonly) id item; 26 | 27 | /** 28 | * The attribute which the reciever relates to 29 | */ 30 | @property (nonatomic, assign, readonly) NSLayoutAttribute layoutAttribute; 31 | 32 | /** 33 | * Convenience initializer. 34 | */ 35 | - (id)initWithView:(MAS_VIEW *)view layoutAttribute:(NSLayoutAttribute)layoutAttribute; 36 | 37 | /** 38 | * The designated initializer. 39 | */ 40 | - (id)initWithView:(MAS_VIEW *)view item:(id)item layoutAttribute:(NSLayoutAttribute)layoutAttribute; 41 | 42 | /** 43 | * Determine whether the layoutAttribute is a size attribute 44 | * 45 | * @return YES if layoutAttribute is equal to NSLayoutAttributeWidth or NSLayoutAttributeHeight 46 | */ 47 | - (BOOL)isSizeAttribute; 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /PageController/Masonry/MASViewAttribute.m: -------------------------------------------------------------------------------- 1 | // 2 | // MASAttribute.m 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 21/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASViewAttribute.h" 10 | 11 | @implementation MASViewAttribute 12 | 13 | - (id)initWithView:(MAS_VIEW *)view layoutAttribute:(NSLayoutAttribute)layoutAttribute { 14 | self = [self initWithView:view item:view layoutAttribute:layoutAttribute]; 15 | return self; 16 | } 17 | 18 | - (id)initWithView:(MAS_VIEW *)view item:(id)item layoutAttribute:(NSLayoutAttribute)layoutAttribute { 19 | self = [super init]; 20 | if (!self) return nil; 21 | 22 | _view = view; 23 | _item = item; 24 | _layoutAttribute = layoutAttribute; 25 | 26 | return self; 27 | } 28 | 29 | - (BOOL)isSizeAttribute { 30 | return self.layoutAttribute == NSLayoutAttributeWidth 31 | || self.layoutAttribute == NSLayoutAttributeHeight; 32 | } 33 | 34 | - (BOOL)isEqual:(MASViewAttribute *)viewAttribute { 35 | if ([viewAttribute isKindOfClass:self.class]) { 36 | return self.view == viewAttribute.view 37 | && self.layoutAttribute == viewAttribute.layoutAttribute; 38 | } 39 | return [super isEqual:viewAttribute]; 40 | } 41 | 42 | - (NSUInteger)hash { 43 | return MAS_NSUINTROTATE([self.view hash], MAS_NSUINT_BIT / 2) ^ self.layoutAttribute; 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /PageController/Masonry/MASViewConstraint.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASConstraint.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 20/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASViewAttribute.h" 10 | #import "MASConstraint.h" 11 | #import "MASLayoutConstraint.h" 12 | #import "MASUtilities.h" 13 | 14 | /** 15 | * A single constraint. 16 | * Contains the attributes neccessary for creating a NSLayoutConstraint and adding it to the appropriate view 17 | */ 18 | @interface MASViewConstraint : MASConstraint 19 | 20 | /** 21 | * First item/view and first attribute of the NSLayoutConstraint 22 | */ 23 | @property (nonatomic, strong, readonly) MASViewAttribute *firstViewAttribute; 24 | 25 | /** 26 | * Second item/view and second attribute of the NSLayoutConstraint 27 | */ 28 | @property (nonatomic, strong, readonly) MASViewAttribute *secondViewAttribute; 29 | 30 | /** 31 | * initialises the MASViewConstraint with the first part of the equation 32 | * 33 | * @param firstViewAttribute view.mas_left, view.mas_width etc. 34 | * 35 | * @return a new view constraint 36 | */ 37 | - (id)initWithFirstViewAttribute:(MASViewAttribute *)firstViewAttribute; 38 | 39 | /** 40 | * Returns all MASViewConstraints installed with this view as a first item. 41 | * 42 | * @param view A view to retrieve constraints for. 43 | * 44 | * @return An array of MASViewConstraints. 45 | */ 46 | + (NSArray *)installedConstraintsForView:(MAS_VIEW *)view; 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /PageController/Masonry/Masonry.h: -------------------------------------------------------------------------------- 1 | // 2 | // Masonry.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 20/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for Masonry. 12 | FOUNDATION_EXPORT double MasonryVersionNumber; 13 | 14 | //! Project version string for Masonry. 15 | FOUNDATION_EXPORT const unsigned char MasonryVersionString[]; 16 | 17 | #import "MASUtilities.h" 18 | #import "View+MASAdditions.h" 19 | #import "View+MASShorthandAdditions.h" 20 | #import "ViewController+MASAdditions.h" 21 | #import "NSArray+MASAdditions.h" 22 | #import "NSArray+MASShorthandAdditions.h" 23 | #import "MASConstraint.h" 24 | #import "MASCompositeConstraint.h" 25 | #import "MASViewAttribute.h" 26 | #import "MASViewConstraint.h" 27 | #import "MASConstraintMaker.h" 28 | #import "MASLayoutConstraint.h" 29 | #import "NSLayoutConstraint+MASDebugAdditions.h" 30 | -------------------------------------------------------------------------------- /PageController/Masonry/NSArray+MASAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+MASAdditions.h 3 | // 4 | // 5 | // Created by Daniel Hammond on 11/26/13. 6 | // 7 | // 8 | 9 | #import "MASUtilities.h" 10 | #import "MASConstraintMaker.h" 11 | #import "MASViewAttribute.h" 12 | 13 | typedef NS_ENUM(NSUInteger, MASAxisType) { 14 | MASAxisTypeHorizontal, 15 | MASAxisTypeVertical 16 | }; 17 | 18 | @interface NSArray (MASAdditions) 19 | 20 | /** 21 | * Creates a MASConstraintMaker with each view in the callee. 22 | * Any constraints defined are added to the view or the appropriate superview once the block has finished executing on each view 23 | * 24 | * @param block scope within which you can build up the constraints which you wish to apply to each view. 25 | * 26 | * @return Array of created MASConstraints 27 | */ 28 | - (NSArray *)mas_makeConstraints:(void (^)(MASConstraintMaker *make))block; 29 | 30 | /** 31 | * Creates a MASConstraintMaker with each view in the callee. 32 | * Any constraints defined are added to each view or the appropriate superview once the block has finished executing on each view. 33 | * If an existing constraint exists then it will be updated instead. 34 | * 35 | * @param block scope within which you can build up the constraints which you wish to apply to each view. 36 | * 37 | * @return Array of created/updated MASConstraints 38 | */ 39 | - (NSArray *)mas_updateConstraints:(void (^)(MASConstraintMaker *make))block; 40 | 41 | /** 42 | * Creates a MASConstraintMaker with each view in the callee. 43 | * Any constraints defined are added to each view or the appropriate superview once the block has finished executing on each view. 44 | * All constraints previously installed for the views will be removed. 45 | * 46 | * @param block scope within which you can build up the constraints which you wish to apply to each view. 47 | * 48 | * @return Array of created/updated MASConstraints 49 | */ 50 | - (NSArray *)mas_remakeConstraints:(void (^)(MASConstraintMaker *make))block; 51 | 52 | /** 53 | * distribute with fixed spacing 54 | * 55 | * @param axisType which axis to distribute items along 56 | * @param fixedSpacing the spacing between each item 57 | * @param leadSpacing the spacing before the first item and the container 58 | * @param tailSpacing the spacing after the last item and the container 59 | */ 60 | - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)fixedSpacing leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing; 61 | 62 | /** 63 | * distribute with fixed item size 64 | * 65 | * @param axisType which axis to distribute items along 66 | * @param fixedItemLength the fixed length of each item 67 | * @param leadSpacing the spacing before the first item and the container 68 | * @param tailSpacing the spacing after the last item and the container 69 | */ 70 | - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)fixedItemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing; 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /PageController/Masonry/NSArray+MASShorthandAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+MASShorthandAdditions.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 22/07/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "NSArray+MASAdditions.h" 10 | 11 | #ifdef MAS_SHORTHAND 12 | 13 | /** 14 | * Shorthand array additions without the 'mas_' prefixes, 15 | * only enabled if MAS_SHORTHAND is defined 16 | */ 17 | @interface NSArray (MASShorthandAdditions) 18 | 19 | - (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *make))block; 20 | - (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *make))block; 21 | - (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *make))block; 22 | 23 | @end 24 | 25 | @implementation NSArray (MASShorthandAdditions) 26 | 27 | - (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *))block { 28 | return [self mas_makeConstraints:block]; 29 | } 30 | 31 | - (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *))block { 32 | return [self mas_updateConstraints:block]; 33 | } 34 | 35 | - (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *))block { 36 | return [self mas_remakeConstraints:block]; 37 | } 38 | 39 | @end 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /PageController/Masonry/NSLayoutConstraint+MASDebugAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSLayoutConstraint+MASDebugAdditions.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 3/08/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "MASUtilities.h" 10 | 11 | /** 12 | * makes debug and log output of NSLayoutConstraints more readable 13 | */ 14 | @interface NSLayoutConstraint (MASDebugAdditions) 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /PageController/Masonry/View+MASAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+MASAdditions.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 20/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASUtilities.h" 10 | #import "MASConstraintMaker.h" 11 | #import "MASViewAttribute.h" 12 | 13 | /** 14 | * Provides constraint maker block 15 | * and convience methods for creating MASViewAttribute which are view + NSLayoutAttribute pairs 16 | */ 17 | @interface MAS_VIEW (MASAdditions) 18 | 19 | /** 20 | * following properties return a new MASViewAttribute with current view and appropriate NSLayoutAttribute 21 | */ 22 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_left; 23 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_top; 24 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_right; 25 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottom; 26 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_leading; 27 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_trailing; 28 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_width; 29 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_height; 30 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerX; 31 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerY; 32 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_baseline; 33 | @property (nonatomic, strong, readonly) MASViewAttribute *(^mas_attribute)(NSLayoutAttribute attr); 34 | 35 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) 36 | 37 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_firstBaseline; 38 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_lastBaseline; 39 | 40 | #endif 41 | 42 | #if TARGET_OS_IPHONE || TARGET_OS_TV 43 | 44 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_leftMargin; 45 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_rightMargin; 46 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_topMargin; 47 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomMargin; 48 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_leadingMargin; 49 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_trailingMargin; 50 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerXWithinMargins; 51 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerYWithinMargins; 52 | 53 | #endif 54 | 55 | /** 56 | * a key to associate with this view 57 | */ 58 | @property (nonatomic, strong) id mas_key; 59 | 60 | /** 61 | * Finds the closest common superview between this view and another view 62 | * 63 | * @param view other view 64 | * 65 | * @return returns nil if common superview could not be found 66 | */ 67 | - (instancetype)mas_closestCommonSuperview:(MAS_VIEW *)view; 68 | 69 | /** 70 | * Creates a MASConstraintMaker with the callee view. 71 | * Any constraints defined are added to the view or the appropriate superview once the block has finished executing 72 | * 73 | * @param block scope within which you can build up the constraints which you wish to apply to the view. 74 | * 75 | * @return Array of created MASConstraints 76 | */ 77 | - (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block; 78 | 79 | /** 80 | * Creates a MASConstraintMaker with the callee view. 81 | * Any constraints defined are added to the view or the appropriate superview once the block has finished executing. 82 | * If an existing constraint exists then it will be updated instead. 83 | * 84 | * @param block scope within which you can build up the constraints which you wish to apply to the view. 85 | * 86 | * @return Array of created/updated MASConstraints 87 | */ 88 | - (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block; 89 | 90 | /** 91 | * Creates a MASConstraintMaker with the callee view. 92 | * Any constraints defined are added to the view or the appropriate superview once the block has finished executing. 93 | * All constraints previously installed for the view will be removed. 94 | * 95 | * @param block scope within which you can build up the constraints which you wish to apply to the view. 96 | * 97 | * @return Array of created/updated MASConstraints 98 | */ 99 | - (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block; 100 | 101 | @end 102 | -------------------------------------------------------------------------------- /PageController/Masonry/View+MASShorthandAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+MASShorthandAdditions.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 22/07/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "View+MASAdditions.h" 10 | 11 | #ifdef MAS_SHORTHAND 12 | 13 | /** 14 | * Shorthand view additions without the 'mas_' prefixes, 15 | * only enabled if MAS_SHORTHAND is defined 16 | */ 17 | @interface MAS_VIEW (MASShorthandAdditions) 18 | 19 | @property (nonatomic, strong, readonly) MASViewAttribute *left; 20 | @property (nonatomic, strong, readonly) MASViewAttribute *top; 21 | @property (nonatomic, strong, readonly) MASViewAttribute *right; 22 | @property (nonatomic, strong, readonly) MASViewAttribute *bottom; 23 | @property (nonatomic, strong, readonly) MASViewAttribute *leading; 24 | @property (nonatomic, strong, readonly) MASViewAttribute *trailing; 25 | @property (nonatomic, strong, readonly) MASViewAttribute *width; 26 | @property (nonatomic, strong, readonly) MASViewAttribute *height; 27 | @property (nonatomic, strong, readonly) MASViewAttribute *centerX; 28 | @property (nonatomic, strong, readonly) MASViewAttribute *centerY; 29 | @property (nonatomic, strong, readonly) MASViewAttribute *baseline; 30 | @property (nonatomic, strong, readonly) MASViewAttribute *(^attribute)(NSLayoutAttribute attr); 31 | 32 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) 33 | 34 | @property (nonatomic, strong, readonly) MASViewAttribute *firstBaseline; 35 | @property (nonatomic, strong, readonly) MASViewAttribute *lastBaseline; 36 | 37 | #endif 38 | 39 | #if TARGET_OS_IPHONE || TARGET_OS_TV 40 | 41 | @property (nonatomic, strong, readonly) MASViewAttribute *leftMargin; 42 | @property (nonatomic, strong, readonly) MASViewAttribute *rightMargin; 43 | @property (nonatomic, strong, readonly) MASViewAttribute *topMargin; 44 | @property (nonatomic, strong, readonly) MASViewAttribute *bottomMargin; 45 | @property (nonatomic, strong, readonly) MASViewAttribute *leadingMargin; 46 | @property (nonatomic, strong, readonly) MASViewAttribute *trailingMargin; 47 | @property (nonatomic, strong, readonly) MASViewAttribute *centerXWithinMargins; 48 | @property (nonatomic, strong, readonly) MASViewAttribute *centerYWithinMargins; 49 | 50 | #endif 51 | 52 | - (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *make))block; 53 | - (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *make))block; 54 | - (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *make))block; 55 | 56 | @end 57 | 58 | #define MAS_ATTR_FORWARD(attr) \ 59 | - (MASViewAttribute *)attr { \ 60 | return [self mas_##attr]; \ 61 | } 62 | 63 | @implementation MAS_VIEW (MASShorthandAdditions) 64 | 65 | MAS_ATTR_FORWARD(top); 66 | MAS_ATTR_FORWARD(left); 67 | MAS_ATTR_FORWARD(bottom); 68 | MAS_ATTR_FORWARD(right); 69 | MAS_ATTR_FORWARD(leading); 70 | MAS_ATTR_FORWARD(trailing); 71 | MAS_ATTR_FORWARD(width); 72 | MAS_ATTR_FORWARD(height); 73 | MAS_ATTR_FORWARD(centerX); 74 | MAS_ATTR_FORWARD(centerY); 75 | MAS_ATTR_FORWARD(baseline); 76 | 77 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) 78 | 79 | MAS_ATTR_FORWARD(firstBaseline); 80 | MAS_ATTR_FORWARD(lastBaseline); 81 | 82 | #endif 83 | 84 | #if TARGET_OS_IPHONE || TARGET_OS_TV 85 | 86 | MAS_ATTR_FORWARD(leftMargin); 87 | MAS_ATTR_FORWARD(rightMargin); 88 | MAS_ATTR_FORWARD(topMargin); 89 | MAS_ATTR_FORWARD(bottomMargin); 90 | MAS_ATTR_FORWARD(leadingMargin); 91 | MAS_ATTR_FORWARD(trailingMargin); 92 | MAS_ATTR_FORWARD(centerXWithinMargins); 93 | MAS_ATTR_FORWARD(centerYWithinMargins); 94 | 95 | #endif 96 | 97 | - (MASViewAttribute *(^)(NSLayoutAttribute))attribute { 98 | return [self mas_attribute]; 99 | } 100 | 101 | - (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *))block { 102 | return [self mas_makeConstraints:block]; 103 | } 104 | 105 | - (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *))block { 106 | return [self mas_updateConstraints:block]; 107 | } 108 | 109 | - (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *))block { 110 | return [self mas_remakeConstraints:block]; 111 | } 112 | 113 | @end 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /PageController/Masonry/ViewController+MASAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+MASAdditions.h 3 | // Masonry 4 | // 5 | // Created by Craig Siemens on 2015-06-23. 6 | // 7 | // 8 | 9 | #import "MASUtilities.h" 10 | #import "MASConstraintMaker.h" 11 | #import "MASViewAttribute.h" 12 | 13 | #ifdef MAS_VIEW_CONTROLLER 14 | 15 | @interface MAS_VIEW_CONTROLLER (MASAdditions) 16 | 17 | /** 18 | * following properties return a new MASViewAttribute with appropriate UILayoutGuide and NSLayoutAttribute 19 | */ 20 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuide; 21 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuide; 22 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuideTop; 23 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuideBottom; 24 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuideTop; 25 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuideBottom; 26 | 27 | 28 | @end 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /PageController/Masonry/ViewController+MASAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+MASAdditions.m 3 | // Masonry 4 | // 5 | // Created by Craig Siemens on 2015-06-23. 6 | // 7 | // 8 | 9 | #import "ViewController+MASAdditions.h" 10 | 11 | #ifdef MAS_VIEW_CONTROLLER 12 | 13 | @implementation MAS_VIEW_CONTROLLER (MASAdditions) 14 | 15 | - (MASViewAttribute *)mas_topLayoutGuide { 16 | return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeBottom]; 17 | } 18 | - (MASViewAttribute *)mas_topLayoutGuideTop { 19 | return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeTop]; 20 | } 21 | - (MASViewAttribute *)mas_topLayoutGuideBottom { 22 | return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeBottom]; 23 | } 24 | 25 | - (MASViewAttribute *)mas_bottomLayoutGuide { 26 | return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeTop]; 27 | } 28 | - (MASViewAttribute *)mas_bottomLayoutGuideTop { 29 | return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeTop]; 30 | } 31 | - (MASViewAttribute *)mas_bottomLayoutGuideBottom { 32 | return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeBottom]; 33 | } 34 | 35 | 36 | 37 | @end 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /PageController/PrefixHeader.pch: -------------------------------------------------------------------------------- 1 | // 2 | // PrefixHeader.pch 3 | // PageController 4 | // 5 | // Created by L_晨曦 on 2017/10/17. 6 | // Copyright © 2017年 L_晨曦. All rights reserved. 7 | // 8 | 9 | #ifndef PrefixHeader_pch 10 | #define PrefixHeader_pch 11 | #import "UIColor+Hex.h" 12 | #import "UIImage+Common.h" 13 | #import "Masonry.h" 14 | #import "UIViewController+ChildViewController.h" 15 | #import "XSBaseTableViewCell.h" 16 | #endif /* PrefixHeader_pch */ 17 | -------------------------------------------------------------------------------- /PageController/SDCycleScrollView/NSString+Common.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Common.h 3 | // 4 | // Created by Alexi on 12-11-5. 5 | // Copyright (c) 2012年 . All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | char pinyinFirstLetter(unsigned short hanzi); 11 | 12 | @interface NSString (Common) 13 | 14 | // 将str加密成本地保存的文件名 15 | + (NSString *)md5String:(NSString *)str; 16 | - (NSString *)md5; 17 | 18 | -(NSString*)firstPinYin; 19 | 20 | //是否为空 21 | + (BOOL)isEmpty:(NSString *)string; 22 | 23 | /** 24 | compare two version 25 | @param sourVersion *.*.*.* 26 | @param desVersion *.*.*.* 27 | @returns No,sourVersion is less than desVersion; YES, the statue is opposed 28 | */ 29 | +(BOOL)compareVerison:(NSString *)sourVersion withDes:(NSString *)desVersion; 30 | 31 | //当前字符串是否只包含空白字符和换行符 32 | - (BOOL)isWhitespaceAndNewlines; 33 | 34 | //去除字符串前后的空白,不包含换行符 35 | - (NSString *)trim; 36 | 37 | //去除字符串中所有空白 38 | - (NSString *)removeWhiteSpace; 39 | - (NSString *)removeNewLine; 40 | 41 | //将字符串以URL格式编码 42 | - (NSString *)stringByUrlEncoding; 43 | 44 | /*! 45 | @brief 大写第一个字符 46 | @return 格式化后的字符串 47 | */ 48 | - (NSString *)capitalize; 49 | 50 | //以给定字符串开始,忽略大小写 51 | - (BOOL)startsWith:(NSString *)str; 52 | //以指定条件判断字符串是否以给定字符串开始 53 | - (BOOL)startsWith:(NSString *)str Options:(NSStringCompareOptions)compareOptions; 54 | 55 | 56 | //以给定字符串结束,忽略大小写 57 | - (BOOL)endsWith:(NSString *)str; 58 | //以指定条件判断字符串是否以给定字符串结尾 59 | - (BOOL)endsWith:(NSString *)str Options:(NSStringCompareOptions)compareOptions; 60 | 61 | //包含给定的字符串, 忽略大小写 62 | - (BOOL)containsString:(NSString *)str; 63 | //以指定条件判断是否包含给定的字符串 64 | - (BOOL)containsString:(NSString *)str Options:(NSStringCompareOptions)compareOptions; 65 | 66 | //判断字符串是否相同,忽略大小写 67 | - (BOOL)equalsString:(NSString *)str; 68 | 69 | 70 | - (NSString *)emjoiText; 71 | 72 | 73 | #pragma mark Hashing 74 | #if kSupportGTM64 75 | - (NSString *)base64Encoding; 76 | #endif 77 | 78 | - (NSString *)valueOfLabel:(NSString *)label; 79 | 80 | - (NSString *)substringAtRange:(NSRange)rang; 81 | 82 | 83 | // 是否带有表情府 84 | 85 | - (NSUInteger)utf8Length; 86 | 87 | - (BOOL)isContainsEmoji; 88 | 89 | //递归计算符合规定的文本长度 90 | - (NSString *)cutBeyondTextInLength:(NSInteger)maxLenth; 91 | 92 | - (CGSize)textSizeIn:(CGSize)size font:(UIFont *)font; 93 | - (CGSize)textSizeIn:(CGSize)size font:(UIFont *)font breakMode:(NSLineBreakMode)breakMode; 94 | - (CGSize)textSizeIn:(CGSize)size font:(UIFont *)font breakMode:(NSLineBreakMode)breakMode align:(NSTextAlignment)alignment; 95 | 96 | 97 | @end 98 | -------------------------------------------------------------------------------- /PageController/SDCycleScrollView/PageControl/TAAbstractDotView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TAAbstractDotView.h 3 | // TAPageControl 4 | // 5 | // Created by Tanguy Aladenise on 2015-01-22. 6 | // Copyright (c) 2015 Tanguy Aladenise. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface TAAbstractDotView : UIView 13 | 14 | 15 | /** 16 | * A method call let view know which state appearance it should take. Active meaning it's current page. Inactive not the current page. 17 | * 18 | * @param active BOOL to tell if view is active or not 19 | */ 20 | - (void)changeActivityState:(BOOL)active; 21 | 22 | 23 | @end 24 | 25 | -------------------------------------------------------------------------------- /PageController/SDCycleScrollView/PageControl/TAAbstractDotView.m: -------------------------------------------------------------------------------- 1 | // 2 | // TAAbstractDotView.m 3 | // TAPageControl 4 | // 5 | // Created by Tanguy Aladenise on 2015-01-22. 6 | // Copyright (c) 2015 Tanguy Aladenise. All rights reserved. 7 | // 8 | 9 | #import "TAAbstractDotView.h" 10 | 11 | 12 | @implementation TAAbstractDotView 13 | 14 | 15 | - (id)init 16 | { 17 | @throw [NSException exceptionWithName:NSInternalInconsistencyException 18 | reason:[NSString stringWithFormat:@"You must override %@ in %@", NSStringFromSelector(_cmd), self.class] 19 | userInfo:nil]; 20 | } 21 | 22 | 23 | - (void)changeActivityState:(BOOL)active 24 | { 25 | @throw [NSException exceptionWithName:NSInternalInconsistencyException 26 | reason:[NSString stringWithFormat:@"You must override %@ in %@", NSStringFromSelector(_cmd), self.class] 27 | userInfo:nil]; 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /PageController/SDCycleScrollView/PageControl/TAAnimatedDotView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TAAnimatedDotView.h 3 | // TAPageControl 4 | // 5 | // Created by Tanguy Aladenise on 2015-01-22. 6 | // Copyright (c) 2015 Tanguy Aladenise. All rights reserved. 7 | // 8 | 9 | #import "TAAbstractDotView.h" 10 | 11 | @interface TAAnimatedDotView : TAAbstractDotView 12 | 13 | @property (nonatomic, strong) UIColor *dotColor; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /PageController/SDCycleScrollView/PageControl/TAAnimatedDotView.m: -------------------------------------------------------------------------------- 1 | // 2 | // TAAnimatedDotView.m 3 | // TAPageControl 4 | // 5 | // Created by Tanguy Aladenise on 2015-01-22. 6 | // Copyright (c) 2015 Tanguy Aladenise. All rights reserved. 7 | // 8 | 9 | #import "TAAnimatedDotView.h" 10 | 11 | static CGFloat const kAnimateDuration = 1; 12 | 13 | @implementation TAAnimatedDotView 14 | 15 | - (instancetype)init 16 | { 17 | self = [super init]; 18 | if (self) { 19 | [self initialization]; 20 | } 21 | 22 | return self; 23 | } 24 | 25 | 26 | - (id)initWithFrame:(CGRect)frame 27 | { 28 | self = [super initWithFrame:frame]; 29 | if (self) { 30 | [self initialization]; 31 | } 32 | return self; 33 | } 34 | 35 | 36 | - (id)initWithCoder:(NSCoder *)aDecoder 37 | { 38 | self = [super initWithCoder:aDecoder]; 39 | if (self) { 40 | [self initialization]; 41 | } 42 | 43 | return self; 44 | } 45 | 46 | - (void)setDotColor:(UIColor *)dotColor 47 | { 48 | _dotColor = dotColor; 49 | self.layer.borderColor = dotColor.CGColor; 50 | } 51 | 52 | - (void)initialization 53 | { 54 | _dotColor = [UIColor whiteColor]; 55 | self.backgroundColor = [UIColor clearColor]; 56 | self.layer.cornerRadius = CGRectGetWidth(self.frame) / 2; 57 | self.layer.borderColor = [UIColor whiteColor].CGColor; 58 | self.layer.borderWidth = 2; 59 | } 60 | 61 | 62 | - (void)changeActivityState:(BOOL)active 63 | { 64 | if (active) { 65 | [self animateToActiveState]; 66 | } else { 67 | [self animateToDeactiveState]; 68 | } 69 | } 70 | 71 | 72 | - (void)animateToActiveState 73 | { 74 | [UIView animateWithDuration:kAnimateDuration delay:0 usingSpringWithDamping:.5 initialSpringVelocity:-20 options:UIViewAnimationOptionCurveLinear animations:^{ 75 | self.backgroundColor = _dotColor; 76 | self.transform = CGAffineTransformMakeScale(1.4, 1.4); 77 | } completion:nil]; 78 | } 79 | 80 | - (void)animateToDeactiveState 81 | { 82 | [UIView animateWithDuration:kAnimateDuration delay:0 usingSpringWithDamping:.5 initialSpringVelocity:0 options:UIViewAnimationOptionCurveLinear animations:^{ 83 | self.backgroundColor = [UIColor clearColor]; 84 | self.transform = CGAffineTransformIdentity; 85 | } completion:nil]; 86 | } 87 | 88 | @end 89 | -------------------------------------------------------------------------------- /PageController/SDCycleScrollView/PageControl/TADotView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TADotView.h 3 | // TAPageControl 4 | // 5 | // Created by Tanguy Aladenise on 2015-01-22. 6 | // Copyright (c) 2015 Tanguy Aladenise. All rights reserved. 7 | // 8 | 9 | #import "TAAbstractDotView.h" 10 | 11 | @interface TADotView : TAAbstractDotView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PageController/SDCycleScrollView/PageControl/TADotView.m: -------------------------------------------------------------------------------- 1 | // 2 | // TADotView.m 3 | // TAPageControl 4 | // 5 | // Created by Tanguy Aladenise on 2015-01-22. 6 | // Copyright (c) 2015 Tanguy Aladenise. All rights reserved. 7 | // 8 | 9 | #import "TADotView.h" 10 | 11 | @implementation TADotView 12 | 13 | 14 | - (instancetype)init 15 | { 16 | self = [super init]; 17 | if (self) { 18 | [self initialization]; 19 | } 20 | 21 | return self; 22 | } 23 | 24 | 25 | - (id)initWithFrame:(CGRect)frame 26 | { 27 | self = [super initWithFrame:frame]; 28 | if (self) { 29 | [self initialization]; 30 | } 31 | return self; 32 | } 33 | 34 | 35 | - (id)initWithCoder:(NSCoder *)aDecoder 36 | { 37 | self = [super initWithCoder:aDecoder]; 38 | if (self) { 39 | [self initialization]; 40 | } 41 | 42 | return self; 43 | } 44 | 45 | - (void)initialization 46 | { 47 | self.backgroundColor = [UIColor clearColor]; 48 | self.layer.cornerRadius = CGRectGetWidth(self.frame) / 2; 49 | self.layer.borderColor = [UIColor whiteColor].CGColor; 50 | self.layer.borderWidth = 2; 51 | } 52 | 53 | 54 | - (void)changeActivityState:(BOOL)active 55 | { 56 | if (active) { 57 | self.backgroundColor = [UIColor whiteColor]; 58 | } else { 59 | self.backgroundColor = [UIColor clearColor]; 60 | } 61 | } 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /PageController/SDCycleScrollView/PageControl/TAPageControl.h: -------------------------------------------------------------------------------- 1 | // 2 | // TAPageControl.h 3 | // TAPageControl 4 | // 5 | // Created by Tanguy Aladenise on 2015-01-21. 6 | // Copyright (c) 2015 Tanguy Aladenise. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol TAPageControlDelegate; 12 | 13 | 14 | @interface TAPageControl : UIControl 15 | 16 | 17 | /** 18 | * Dot view customization properties 19 | */ 20 | 21 | /** 22 | * The Class of your custom UIView, make sure to respect the TAAbstractDotView class. 23 | */ 24 | @property (nonatomic) Class dotViewClass; 25 | 26 | 27 | /** 28 | * UIImage to represent a dot. 29 | */ 30 | @property (nonatomic) UIImage *dotImage; 31 | 32 | 33 | /** 34 | * UIImage to represent current page dot. 35 | */ 36 | @property (nonatomic) UIImage *currentDotImage; 37 | 38 | 39 | /** 40 | * Dot size for dot views. Default is 8 by 8. 41 | */ 42 | @property (nonatomic) CGSize dotSize; 43 | 44 | 45 | @property (nonatomic, strong) UIColor *dotColor; 46 | 47 | /** 48 | * Spacing between two dot views. Default is 8. 49 | */ 50 | @property (nonatomic) NSInteger spacingBetweenDots; 51 | 52 | 53 | /** 54 | * Page control setup properties 55 | */ 56 | 57 | 58 | /** 59 | * Delegate for TAPageControl 60 | */ 61 | @property(nonatomic,assign) id delegate; 62 | 63 | 64 | /** 65 | * Number of pages for control. Default is 0. 66 | */ 67 | @property (nonatomic) NSInteger numberOfPages; 68 | 69 | 70 | /** 71 | * Current page on which control is active. Default is 0. 72 | */ 73 | @property (nonatomic) NSInteger currentPage; 74 | 75 | 76 | /** 77 | * Hide the control if there is only one page. Default is NO. 78 | */ 79 | @property (nonatomic) BOOL hidesForSinglePage; 80 | 81 | 82 | /** 83 | * Let the control know if should grow bigger by keeping center, or just get longer (right side expanding). By default YES. 84 | */ 85 | @property (nonatomic) BOOL shouldResizeFromCenter; 86 | 87 | 88 | /** 89 | * Return the minimum size required to display control properly for the given page count. 90 | * 91 | * @param pageCount Number of dots that will require display 92 | * 93 | * @return The CGSize being the minimum size required. 94 | */ 95 | - (CGSize)sizeForNumberOfPages:(NSInteger)pageCount; 96 | 97 | 98 | @end 99 | 100 | 101 | @protocol TAPageControlDelegate 102 | 103 | @optional 104 | - (void)TAPageControl:(TAPageControl *)pageControl didSelectPageAtIndex:(NSInteger)index; 105 | 106 | @end 107 | -------------------------------------------------------------------------------- /PageController/SDCycleScrollView/SDCollectionViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // SDCollectionViewCell.h 3 | // SDCycleScrollView 4 | // 5 | // Created by aier on 15-3-22. 6 | // Copyright (c) 2015年 GSD. All rights reserved. 7 | // 8 | 9 | /* 10 | 11 | ********************************************************************************* 12 | * 13 | * 🌟🌟🌟 新建SDCycleScrollView交流QQ群:185534916 🌟🌟🌟 14 | * 15 | * 在您使用此自动轮播库的过程中如果出现bug请及时以以下任意一种方式联系我们,我们会及时修复bug并 16 | * 帮您解决问题。 17 | * 新浪微博:GSD_iOS 18 | * Email : gsdios@126.com 19 | * GitHub: https://github.com/gsdios 20 | * 21 | * 另(我的自动布局库SDAutoLayout): 22 | * 一行代码搞定自动布局!支持Cell和Tableview高度自适应,Label和ScrollView内容自适应,致力于 23 | * 做最简单易用的AutoLayout库。 24 | * 视频教程:http://www.letv.com/ptv/vplay/24038772.html 25 | * 用法示例:https://github.com/gsdios/SDAutoLayout/blob/master/README.md 26 | * GitHub:https://github.com/gsdios/SDAutoLayout 27 | ********************************************************************************* 28 | 29 | */ 30 | 31 | 32 | 33 | #import 34 | 35 | @interface SDCollectionViewCell : UICollectionViewCell 36 | 37 | @property (weak, nonatomic) UIImageView *imageView; 38 | @property (copy, nonatomic) NSString *title; 39 | 40 | @property (nonatomic, strong) UIColor *titleLabelTextColor; 41 | @property (nonatomic, strong) UIFont *titleLabelTextFont; 42 | @property (nonatomic, strong) UIColor *titleLabelBackgroundColor; 43 | @property (nonatomic, assign) CGFloat titleLabelHeight; 44 | @property (nonatomic, assign) NSTextAlignment titleLabelTextAlignment; 45 | 46 | @property (nonatomic, assign) BOOL hasConfigured; 47 | 48 | /** 只展示文字轮播 */ 49 | @property (nonatomic, assign) BOOL onlyDisplayText; 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /PageController/SDCycleScrollView/SDCollectionViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // SDCollectionViewCell.m 3 | // SDCycleScrollView 4 | // 5 | // Created by aier on 15-3-22. 6 | // Copyright (c) 2015年 GSD. All rights reserved. 7 | // 8 | 9 | 10 | /* 11 | 12 | ********************************************************************************* 13 | * 14 | * 🌟🌟🌟 新建SDCycleScrollView交流QQ群:185534916 🌟🌟🌟 15 | * 16 | * 在您使用此自动轮播库的过程中如果出现bug请及时以以下任意一种方式联系我们,我们会及时修复bug并 17 | * 帮您解决问题。 18 | * 新浪微博:GSD_iOS 19 | * Email : gsdios@126.com 20 | * GitHub: https://github.com/gsdios 21 | * 22 | * 另(我的自动布局库SDAutoLayout): 23 | * 一行代码搞定自动布局!支持Cell和Tableview高度自适应,Label和ScrollView内容自适应,致力于 24 | * 做最简单易用的AutoLayout库。 25 | * 视频教程:http://www.letv.com/ptv/vplay/24038772.html 26 | * 用法示例:https://github.com/gsdios/SDAutoLayout/blob/master/README.md 27 | * GitHub:https://github.com/gsdios/SDAutoLayout 28 | ********************************************************************************* 29 | 30 | */ 31 | 32 | 33 | #import "SDCollectionViewCell.h" 34 | #import "UIView+SDExtension.h" 35 | 36 | @implementation SDCollectionViewCell 37 | { 38 | __weak UILabel *_titleLabel; 39 | } 40 | 41 | 42 | - (instancetype)initWithFrame:(CGRect)frame 43 | { 44 | if (self = [super initWithFrame:frame]) { 45 | [self setupImageView]; 46 | [self setupTitleLabel]; 47 | } 48 | 49 | return self; 50 | } 51 | 52 | - (void)setTitleLabelBackgroundColor:(UIColor *)titleLabelBackgroundColor 53 | { 54 | _titleLabelBackgroundColor = titleLabelBackgroundColor; 55 | _titleLabel.backgroundColor = titleLabelBackgroundColor; 56 | } 57 | 58 | - (void)setTitleLabelTextColor:(UIColor *)titleLabelTextColor 59 | { 60 | _titleLabelTextColor = titleLabelTextColor; 61 | _titleLabel.textColor = titleLabelTextColor; 62 | } 63 | 64 | - (void)setTitleLabelTextFont:(UIFont *)titleLabelTextFont 65 | { 66 | _titleLabelTextFont = titleLabelTextFont; 67 | _titleLabel.font = titleLabelTextFont; 68 | } 69 | 70 | - (void)setupImageView 71 | { 72 | UIImageView *imageView = [[UIImageView alloc] init]; 73 | _imageView = imageView; 74 | [self.contentView addSubview:imageView]; 75 | } 76 | 77 | - (void)setupTitleLabel 78 | { 79 | UILabel *titleLabel = [[UILabel alloc] init]; 80 | _titleLabel = titleLabel; 81 | _titleLabel.hidden = YES; 82 | [self.contentView addSubview:titleLabel]; 83 | } 84 | 85 | - (void)setTitle:(NSString *)title 86 | { 87 | _title = [title copy]; 88 | _titleLabel.text = [NSString stringWithFormat:@" %@", title]; 89 | if (_titleLabel.hidden) { 90 | _titleLabel.hidden = NO; 91 | } 92 | } 93 | 94 | -(void)setTitleLabelTextAlignment:(NSTextAlignment)titleLabelTextAlignment 95 | { 96 | _titleLabelTextAlignment = titleLabelTextAlignment; 97 | _titleLabel.textAlignment = titleLabelTextAlignment; 98 | } 99 | 100 | - (void)layoutSubviews 101 | { 102 | [super layoutSubviews]; 103 | 104 | if (self.onlyDisplayText) { 105 | _titleLabel.frame = self.bounds; 106 | } else { 107 | _imageView.frame = self.bounds; 108 | CGFloat titleLabelW = self.sd_width; 109 | CGFloat titleLabelH = _titleLabelHeight; 110 | CGFloat titleLabelX = 0; 111 | CGFloat titleLabelY = self.sd_height - titleLabelH; 112 | _titleLabel.frame = CGRectMake(titleLabelX, titleLabelY, titleLabelW, titleLabelH); 113 | } 114 | } 115 | 116 | @end 117 | -------------------------------------------------------------------------------- /PageController/SDCycleScrollView/UIColor+Hex.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+UIColor_extra_h.h 3 | // PAChat 4 | // 5 | // Created by xiao on 8/12/14. 6 | // Copyright (c) 2014 FreeDo. All rights reserved. 7 | // 8 | 9 | #import 10 | @interface UIColor (Hex) 11 | 12 | #define kColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 \ 13 | green:((float)((rgbValue & 0xFF00) >> 8))/255.0 \ 14 | blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0] 15 | 16 | + (UIColor *)colorWithHex:(long)hexColor; 17 | + (UIColor *)colorWithHex:(long)hexColor alpha:(float)opacity; 18 | 19 | @end -------------------------------------------------------------------------------- /PageController/SDCycleScrollView/UIColor+Hex.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+UIColor_extra_h.m 3 | // PAChat 4 | // 5 | // Created by xiao on 8/12/14. 6 | // Copyright (c) 2014 FreeDo. All rights reserved. 7 | // 8 | 9 | 10 | #import 11 | @implementation UIColor (UIColor_extra_h) 12 | 13 | @end 14 | 15 | @implementation UIColor (Hex) 16 | 17 | + (UIColor*) colorWithHex:(long)hexColor; 18 | { 19 | return [UIColor colorWithHex:hexColor alpha:1.]; 20 | } 21 | 22 | + (UIColor *)colorWithHex:(long)hexColor alpha:(float)opacity 23 | { 24 | float red = ((float)((hexColor & 0xFF0000) >> 16))/255.0; 25 | float green = ((float)((hexColor & 0xFF00) >> 8))/255.0; 26 | float blue = ((float)(hexColor & 0xFF))/255.0; 27 | return [UIColor colorWithRed:red green:green blue:blue alpha:opacity]; 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /PageController/SDCycleScrollView/UIImage+Alpha.h: -------------------------------------------------------------------------------- 1 | // UIImage+Alpha.h 2 | // Created by Trevor Harmon on 9/20/09. 3 | // Free for personal or commercial use, with or without modification. 4 | // No warranty is expressed or implied. 5 | 6 | #import 7 | @interface UIImage (Alpha) 8 | 9 | - (BOOL)hasAlpha; 10 | 11 | - (UIImage *)imageWithAlpha; 12 | 13 | - (UIImage *)transparentBorderImage:(NSUInteger)borderSize; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /PageController/SDCycleScrollView/UIImage+Alpha.m: -------------------------------------------------------------------------------- 1 | // UIImage+Alpha.m 2 | // Created by Trevor Harmon on 9/20/09. 3 | // Free for personal or commercial use, with or without modification. 4 | // No warranty is expressed or implied. 5 | 6 | #import "UIImage+Alpha.h" 7 | 8 | 9 | @implementation UIImage (Alpha) 10 | 11 | // Returns true if the image has an alpha layer 12 | - (BOOL)hasAlpha 13 | { 14 | CGImageAlphaInfo alpha = CGImageGetAlphaInfo(self.CGImage); 15 | return (alpha == kCGImageAlphaFirst || alpha == kCGImageAlphaLast || alpha == kCGImageAlphaPremultipliedFirst || alpha == kCGImageAlphaPremultipliedLast); 16 | } 17 | 18 | // Returns a copy of the given image, adding an alpha channel if it doesn't already have one 19 | - (UIImage *)imageWithAlpha 20 | { 21 | if ([self hasAlpha]) 22 | { 23 | return self; 24 | } 25 | 26 | CGImageRef imageRef = self.CGImage; 27 | size_t width = CGImageGetWidth(imageRef); 28 | size_t height = CGImageGetHeight(imageRef); 29 | 30 | // The bitsPerComponent and bitmapInfo values are hard-coded to prevent an "unsupported parameter combination" error 31 | CGContextRef offscreenContext = CGBitmapContextCreate(NULL, width, height, 8, 0, CGImageGetColorSpace(imageRef), kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst); 32 | 33 | // Draw the image into the context and retrieve the new image, which will now have an alpha layer 34 | CGContextDrawImage(offscreenContext, CGRectMake(0, 0, width, height), imageRef); 35 | CGImageRef imageRefWithAlpha = CGBitmapContextCreateImage(offscreenContext); 36 | UIImage *imageWithAlpha = [UIImage imageWithCGImage:imageRefWithAlpha]; 37 | 38 | // Clean up 39 | CGContextRelease(offscreenContext); 40 | CGImageRelease(imageRefWithAlpha); 41 | 42 | return imageWithAlpha; 43 | } 44 | 45 | // Returns a copy of the image with a transparent border of the given size added around its edges. 46 | // If the image has no alpha layer, one will be added to it. 47 | - (UIImage *)transparentBorderImage:(NSUInteger)borderSize 48 | { 49 | // If the image does not have an alpha layer, add one 50 | UIImage *image = [self imageWithAlpha]; 51 | 52 | CGRect newRect = CGRectMake(0, 0, image.size.width + borderSize * 2, image.size.height + borderSize * 2); 53 | 54 | // Build a context that's the same dimensions as the new size 55 | CGContextRef bitmap = CGBitmapContextCreate(NULL, newRect.size.width, newRect.size.height, CGImageGetBitsPerComponent(self.CGImage), 0, CGImageGetColorSpace(self.CGImage), CGImageGetBitmapInfo(self.CGImage)); 56 | 57 | // Draw the image in the center of the context, leaving a gap around the edges 58 | CGRect imageLocation = CGRectMake(borderSize, borderSize, image.size.width, image.size.height); 59 | CGContextDrawImage(bitmap, imageLocation, self.CGImage); 60 | CGImageRef borderImageRef = CGBitmapContextCreateImage(bitmap); 61 | 62 | // Create a mask to make the border transparent, and combine it with the image 63 | CGImageRef maskImageRef = [self newBorderMask:borderSize size:newRect.size]; 64 | CGImageRef transparentBorderImageRef = CGImageCreateWithMask(borderImageRef, maskImageRef); 65 | UIImage *transparentBorderImage = [UIImage imageWithCGImage:transparentBorderImageRef]; 66 | 67 | // Clean up 68 | CGContextRelease(bitmap); 69 | CGImageRelease(borderImageRef); 70 | CGImageRelease(maskImageRef); 71 | CGImageRelease(transparentBorderImageRef); 72 | 73 | return transparentBorderImage; 74 | } 75 | 76 | #pragma mark - 77 | #pragma mark Private helper methods 78 | 79 | // Creates a mask that makes the outer edges transparent and everything else opaque 80 | // The size must include the entire mask (opaque part + transparent border) 81 | // The caller is responsible for releasing the returned reference by calling CGImageRelease 82 | - (CGImageRef)newBorderMask:(NSUInteger)borderSize size:(CGSize)size 83 | { 84 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); 85 | 86 | // Build a context that's the same dimensions as the new size 87 | CGContextRef maskContext = CGBitmapContextCreate(NULL, size.width, size.height, 8, 0, colorSpace, kCGBitmapByteOrderDefault | kCGImageAlphaNone); 88 | 89 | // Start with a mask that's entirely transparent 90 | CGContextSetFillColorWithColor(maskContext, [UIColor blackColor].CGColor); 91 | CGContextFillRect(maskContext, CGRectMake(0, 0, size.width, size.height)); 92 | 93 | // Make the inner part (within the border) opaque 94 | CGContextSetFillColorWithColor(maskContext, [UIColor whiteColor].CGColor); 95 | CGContextFillRect(maskContext, CGRectMake(borderSize, borderSize, size.width - borderSize * 2, size.height - borderSize * 2)); 96 | 97 | // Get an image of the context 98 | CGImageRef maskImageRef = CGBitmapContextCreateImage(maskContext); 99 | 100 | // Clean up 101 | CGContextRelease(maskContext); 102 | CGColorSpaceRelease(colorSpace); 103 | 104 | return maskImageRef; 105 | } 106 | 107 | @end 108 | -------------------------------------------------------------------------------- /PageController/SDCycleScrollView/UIImage+Common.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Common.h 3 | // CommonLibrary 4 | // 5 | // Created by Alexi on 13-11-6. 6 | // Copyright (c) 2013年 ywchen. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIImage (Common) 12 | 13 | - (UIImage *)fixOrientation; 14 | 15 | - (UIImage *)thumbnailWithSize:(CGSize)asize; 16 | 17 | - (UIImage *)rescaleImageToSize:(CGSize)size; 18 | 19 | - (UIImage *)cropImageToRect:(CGRect)cropRect; 20 | 21 | - (CGSize)calculateNewSizeForCroppingBox:(CGSize)croppingBox; 22 | 23 | - (UIImage *)cropCenterAndScaleImageToSize:(CGSize)cropSize; 24 | 25 | - (UIImage *)cropToSquareImage; 26 | 27 | // path为图片的键值 28 | - (void)saveToCacheWithKey:(NSString *)key; 29 | 30 | + (UIImage *)loadFromCacheWithKey:(NSString *)key; 31 | 32 | + (UIImage *)imageWithColor:(UIColor *)color; 33 | 34 | + (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size; 35 | 36 | + (UIImage *)randomColorImageWith:(CGSize)size; 37 | 38 | - (UIImage *)croppedImage:(CGRect)bounds; 39 | 40 | @end 41 | 42 | 43 | 44 | #if kSupportUIImageNonCommon 45 | 46 | //======================================== 47 | 48 | @interface UIImage (Cut) 49 | 50 | - (UIImage *)clipImageWithScaleWithsize:(CGSize)asize; 51 | - (UIImage *)clipImageWithScaleWithsize:(CGSize)asize roundedCornerImage:(NSInteger)roundedCornerImage borderSize:(NSInteger)borderSize; 52 | @end 53 | 54 | //======================================== 55 | 56 | @interface UIImage (Resize) 57 | 58 | 59 | 60 | - (UIImage *)thumbnailImage:(NSInteger)thumbnailSize transparentBorder:(NSUInteger)borderSize cornerRadius:(NSUInteger)cornerRadius interpolationQuality:(CGInterpolationQuality)quality; 61 | 62 | - (UIImage *)resizedImage:(CGSize)newSize interpolationQuality:(CGInterpolationQuality)quality; 63 | 64 | - (UIImage *)resizedImageWithContentMode:(UIViewContentMode)contentMode bounds:(CGSize)bounds interpolationQuality:(CGInterpolationQuality)quality; 65 | 66 | - (UIImage *)resizedImage:(CGSize)newSize transform:(CGAffineTransform)transform drawTransposed:(BOOL)transpose interpolationQuality:(CGInterpolationQuality)quality; 67 | 68 | - (UIImage *)resizedImageInRect:(CGRect)rect transform:(CGAffineTransform)transform drawTransposed:(BOOL)transpose interpolationQuality:(CGInterpolationQuality)quality; 69 | 70 | - (CGAffineTransform)transformForOrientation:(CGSize)newSize; 71 | 72 | @end 73 | 74 | //======================================== 75 | 76 | @interface UIImage (RoundedCorner) 77 | 78 | - (UIImage *)roundedCornerImage:(NSInteger)cornerSize borderSize:(NSInteger)borderSize; 79 | - (void)addRoundedRectToPath:(CGRect)rect context:(CGContextRef)context ovalWidth:(CGFloat)ovalWidth ovalHeight:(CGFloat)ovalHeight; 80 | 81 | @end 82 | 83 | //======================================== 84 | @interface UIImage (SplitImageIntoTwoParts) 85 | + (NSArray*)splitImageIntoTwoParts:(UIImage*)image; 86 | @end 87 | 88 | #endif 89 | 90 | -------------------------------------------------------------------------------- /PageController/SDCycleScrollView/UIView+SDExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+SDExtension.h 3 | // SDRefreshView 4 | // 5 | // Created by aier on 15-2-23. 6 | // Copyright (c) 2015年 GSD. All rights reserved. 7 | // 8 | 9 | /* 10 | 11 | ********************************************************************************* 12 | * 13 | * 🌟🌟🌟 新建SDCycleScrollView交流QQ群:185534916 🌟🌟🌟 14 | * 15 | * 在您使用此自动轮播库的过程中如果出现bug请及时以以下任意一种方式联系我们,我们会及时修复bug并 16 | * 帮您解决问题。 17 | * 新浪微博:GSD_iOS 18 | * Email : gsdios@126.com 19 | * GitHub: https://github.com/gsdios 20 | * 21 | * 另(我的自动布局库SDAutoLayout): 22 | * 一行代码搞定自动布局!支持Cell和Tableview高度自适应,Label和ScrollView内容自适应,致力于 23 | * 做最简单易用的AutoLayout库。 24 | * 视频教程:http://www.letv.com/ptv/vplay/24038772.html 25 | * 用法示例:https://github.com/gsdios/SDAutoLayout/blob/master/README.md 26 | * GitHub:https://github.com/gsdios/SDAutoLayout 27 | ********************************************************************************* 28 | 29 | */ 30 | 31 | #import 32 | 33 | #define SDColorCreater(r, g, b, a) [UIColor colorWithRed:(r / 255.0) green:(g / 255.0) blue:(b / 255.0) alpha:a] 34 | 35 | 36 | @interface UIView (SDExtension) 37 | 38 | @property (nonatomic, assign) CGFloat sd_height; 39 | @property (nonatomic, assign) CGFloat sd_width; 40 | 41 | @property (nonatomic, assign) CGFloat sd_y; 42 | @property (nonatomic, assign) CGFloat sd_x; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /PageController/SDCycleScrollView/UIView+SDExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+SDExtension.m 3 | // SDRefreshView 4 | // 5 | // Created by aier on 15-2-23. 6 | // Copyright (c) 2015年 GSD. All rights reserved. 7 | // 8 | 9 | /* 10 | 11 | ********************************************************************************* 12 | * 13 | * 🌟🌟🌟 新建SDCycleScrollView交流QQ群:185534916 🌟🌟🌟 14 | * 15 | * 在您使用此自动轮播库的过程中如果出现bug请及时以以下任意一种方式联系我们,我们会及时修复bug并 16 | * 帮您解决问题。 17 | * 新浪微博:GSD_iOS 18 | * Email : gsdios@126.com 19 | * GitHub: https://github.com/gsdios 20 | * 21 | * 另(我的自动布局库SDAutoLayout): 22 | * 一行代码搞定自动布局!支持Cell和Tableview高度自适应,Label和ScrollView内容自适应,致力于 23 | * 做最简单易用的AutoLayout库。 24 | * 视频教程:http://www.letv.com/ptv/vplay/24038772.html 25 | * 用法示例:https://github.com/gsdios/SDAutoLayout/blob/master/README.md 26 | * GitHub:https://github.com/gsdios/SDAutoLayout 27 | ********************************************************************************* 28 | 29 | */ 30 | 31 | /* 32 | 33 | ********************************************************************************* 34 | * 35 | * 在您使用此自动轮播库的过程中如果出现bug请及时以以下任意一种方式联系我们,我们会及时修复bug并 36 | * 帮您解决问题。 37 | * 新浪微博:GSD_iOS 38 | * Email : gsdios@126.com 39 | * GitHub: https://github.com/gsdios 40 | * 41 | * 另(我的自动布局库SDAutoLayout): 42 | * 一行代码搞定自动布局!支持Cell和Tableview高度自适应,Label和ScrollView内容自适应,致力于 43 | * 做最简单易用的AutoLayout库。 44 | * 视频教程:http://www.letv.com/ptv/vplay/24038772.html 45 | * 用法示例:https://github.com/gsdios/SDAutoLayout/blob/master/README.md 46 | * GitHub:https://github.com/gsdios/SDAutoLayout 47 | ********************************************************************************* 48 | 49 | */ 50 | 51 | 52 | #import "UIView+SDExtension.h" 53 | 54 | @implementation UIView (SDExtension) 55 | 56 | - (CGFloat)sd_height 57 | { 58 | return self.frame.size.height; 59 | } 60 | 61 | - (void)setSd_height:(CGFloat)sd_height 62 | { 63 | CGRect temp = self.frame; 64 | temp.size.height = sd_height; 65 | self.frame = temp; 66 | } 67 | 68 | - (CGFloat)sd_width 69 | { 70 | return self.frame.size.width; 71 | } 72 | 73 | - (void)setSd_width:(CGFloat)sd_width 74 | { 75 | CGRect temp = self.frame; 76 | temp.size.width = sd_width; 77 | self.frame = temp; 78 | } 79 | 80 | 81 | - (CGFloat)sd_y 82 | { 83 | return self.frame.origin.y; 84 | } 85 | 86 | - (void)setSd_y:(CGFloat)sd_y 87 | { 88 | CGRect temp = self.frame; 89 | temp.origin.y = sd_y; 90 | self.frame = temp; 91 | } 92 | 93 | - (CGFloat)sd_x 94 | { 95 | return self.frame.origin.x; 96 | } 97 | 98 | - (void)setSd_x:(CGFloat)sd_x 99 | { 100 | CGRect temp = self.frame; 101 | temp.origin.x = sd_x; 102 | self.frame = temp; 103 | } 104 | 105 | 106 | 107 | @end 108 | -------------------------------------------------------------------------------- /PageController/SDCycleScrollView/UIViewController+ChildViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+ChildViewController.h 3 | // CommonLibrary 4 | // 5 | // Created by Alexi on 14-2-24. 6 | // Copyright (c) 2014年 CommonLibrary. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | // 还需要调试这一块的代码 12 | 13 | 14 | @interface UIViewController (ChildViewController) 15 | 16 | 17 | - (void)addChild:(UIViewController *)vc; 18 | 19 | - (void)addChild:(UIViewController *)vc animation:(void (^)(void))inAnimation; 20 | 21 | - (void)addChild:(UIViewController *)vc inRect:(CGRect)rect; 22 | 23 | - (void)addChild:(UIViewController *)vc inRect:(CGRect)rect animation:(void (^)(void))inAnimation; 24 | 25 | - (void)addChild:(UIViewController *)vc container:(UIView *)view; 26 | 27 | - (void)addChild:(UIViewController *)vc container:(UIView *)view inRect:(CGRect)rect; 28 | 29 | - (void)addChild:(UIViewController *)vc container:(UIView *)view inRect:(CGRect)rect animation:(void (^)(void))inAnimation; 30 | 31 | - (void)removeChild:(UIViewController *)vc; 32 | 33 | - (void)removeChild:(UIViewController *)vc animation:(void (^)(void))outAnimation; 34 | 35 | - (void)removeChild:(UIViewController *)vc inContainer:(UIView *)view; 36 | 37 | - (void)removeChild:(UIViewController *)vc inContainer:(UIView *)view animation:(void (^)(void))outAnimation; 38 | 39 | // 默认是在self.view中操作 40 | - (void)replace:(UIViewController *)oldVC withNew:(UIViewController *)newVC animations:(void (^)(void))animations; 41 | 42 | // 在container中进行操作 43 | - (void)replace:(UIViewController *)oldVC withNew:(UIViewController *)newVC container:(UIView *)container animations:(void (^)(void))animations; 44 | 45 | @end -------------------------------------------------------------------------------- /PageController/SDCycleScrollView/UIViewController+ChildViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+ChildViewController.m 3 | // CommonLibrary 4 | // 5 | // Created by Alexi on 14-2-24. 6 | // Copyright (c) 2014年 CommonLibrary. All rights reserved. 7 | // 8 | 9 | #import "UIViewController+ChildViewController.h" 10 | 11 | @implementation UIViewController (ChildViewController) 12 | 13 | - (void)addChild:(UIViewController *)vc 14 | { 15 | [self addChild:vc inRect:CGRectZero]; 16 | } 17 | 18 | - (void)addChild:(UIViewController *)vc animation:(void (^)(void))inAnimation 19 | { 20 | [self addChild:vc inRect:CGRectZero animation:inAnimation]; 21 | } 22 | 23 | - (void)addChild:(UIViewController *)vc inRect:(CGRect)rect 24 | { 25 | [self.view addSubview:vc.view]; 26 | vc.view.frame = rect; 27 | [self addChildViewController:vc]; 28 | } 29 | 30 | - (void)addChild:(UIViewController *)vc inRect:(CGRect)rect animation:(void (^)(void))inAnimation 31 | { 32 | [self addChild:vc inRect:rect]; 33 | if (inAnimation) { 34 | [UIView animateWithDuration:0.3 animations:^{ 35 | inAnimation(); 36 | }]; 37 | } 38 | } 39 | 40 | - (void)addChild:(UIViewController *)vc container:(UIView *)view 41 | { 42 | [view addSubview:vc.view]; 43 | [self addChildViewController:vc]; 44 | } 45 | 46 | - (void)addChild:(UIViewController *)vc container:(UIView *)view inRect:(CGRect)rect 47 | { 48 | [view addSubview:vc.view]; 49 | vc.view.frame = rect; 50 | [self addChildViewController:vc]; 51 | } 52 | 53 | - (void)addChild:(UIViewController *)child container:(UIView *)view inRect:(CGRect)rect animation:(void (^)(void))inAnimation 54 | { 55 | [self addChild:child container:view inRect:rect]; 56 | if (inAnimation) { 57 | [UIView animateWithDuration:0.3 animations:^{ 58 | inAnimation(); 59 | }]; 60 | } 61 | } 62 | 63 | - (void)removeChild:(UIViewController *)vc 64 | { 65 | [vc.view removeFromSuperview]; 66 | [vc willMoveToParentViewController:nil]; 67 | [vc removeFromParentViewController]; 68 | } 69 | 70 | - (void)removeChild:(UIViewController *)vc animation:(void (^)(void))outAnimation 71 | { 72 | if (outAnimation) 73 | { 74 | [UIView animateWithDuration:0.3 animations:^{ 75 | outAnimation(); 76 | } completion:^(BOOL finished) { 77 | [self removeChild:vc]; 78 | }]; 79 | } 80 | else 81 | { 82 | [self removeChild:vc]; 83 | } 84 | 85 | } 86 | 87 | - (void)removeChild:(UIViewController *)child inContainer:(UIView *)view 88 | { 89 | [child.view removeFromSuperview]; 90 | [child willMoveToParentViewController:nil]; 91 | [child removeFromParentViewController]; 92 | } 93 | 94 | - (void)removeChild:(UIViewController *)child inContainer:(UIView *)view animation:(void (^)(void))outAnimation 95 | { 96 | if (outAnimation) 97 | { 98 | [UIView animateWithDuration:0.3 animations:^{ 99 | outAnimation(); 100 | } completion:^(BOOL finished) { 101 | [self removeChild:child inContainer:view]; 102 | }]; 103 | } 104 | else 105 | { 106 | [self removeChild:child inContainer:view]; 107 | } 108 | } 109 | 110 | // 默认是在self.view中操作 111 | - (void)replace:(UIViewController *)oldVC withNew:(UIViewController *)newVC animations:(void (^)(void))animations; 112 | { 113 | [self replace:oldVC withNew:newVC container:self.view animations:animations]; 114 | } 115 | 116 | - (void)replace:(UIViewController *)old withNew:(UIViewController *)newvc container:(UIView *)container animations:(void (^)(void))animations 117 | { 118 | if (newvc) 119 | { 120 | [self addChild:newvc container:container inRect:old.view.frame]; 121 | 122 | if (old) 123 | { 124 | [self transitionFromViewController:old toViewController:newvc duration:0.0 options:0 animations:animations completion:^(BOOL finished) 125 | { 126 | 127 | [newvc didMoveToParentViewController:self]; 128 | 129 | [[old view] removeFromSuperview]; 130 | [old willMoveToParentViewController:nil]; 131 | [old removeFromParentViewController]; 132 | }]; 133 | } 134 | else 135 | { 136 | [container addSubview:[newvc view]]; 137 | [newvc didMoveToParentViewController:self]; 138 | } 139 | } 140 | else 141 | { 142 | [[old view] removeFromSuperview]; 143 | [old willMoveToParentViewController:nil]; 144 | [old removeFromParentViewController]; 145 | } 146 | } 147 | 148 | @end 149 | -------------------------------------------------------------------------------- /PageController/SDWebImage/FLAnimatedImage/FLAnimatedImage.h: -------------------------------------------------------------------------------- 1 | // 2 | // FLAnimatedImage.h 3 | // Flipboard 4 | // 5 | // Created by Raphael Schaad on 7/8/13. 6 | // Copyright (c) 2013-2015 Flipboard. All rights reserved. 7 | // 8 | 9 | 10 | #import 11 | 12 | // Allow user classes conveniently just importing one header. 13 | #import "FLAnimatedImageView.h" 14 | 15 | 16 | #ifndef NS_DESIGNATED_INITIALIZER 17 | #if __has_attribute(objc_designated_initializer) 18 | #define NS_DESIGNATED_INITIALIZER __attribute((objc_designated_initializer)) 19 | #else 20 | #define NS_DESIGNATED_INITIALIZER 21 | #endif 22 | #endif 23 | 24 | extern const NSTimeInterval kFLAnimatedImageDelayTimeIntervalMinimum; 25 | 26 | // 27 | // An `FLAnimatedImage`'s job is to deliver frames in a highly performant way and works in conjunction with `FLAnimatedImageView`. 28 | // It subclasses `NSObject` and not `UIImage` because it's only an "image" in the sense that a sea lion is a lion. 29 | // It tries to intelligently choose the frame cache size depending on the image and memory situation with the goal to lower CPU usage for smaller ones, lower memory usage for larger ones and always deliver frames for high performant play-back. 30 | // Note: `posterImage`, `size`, `loopCount`, `delayTimes` and `frameCount` don't change after successful initialization. 31 | // 32 | @interface FLAnimatedImage : NSObject 33 | 34 | @property (nonatomic, strong, readonly) UIImage *posterImage; // Guaranteed to be loaded; usually equivalent to `-imageLazilyCachedAtIndex:0` 35 | @property (nonatomic, assign, readonly) CGSize size; // The `.posterImage`'s `.size` 36 | 37 | @property (nonatomic, assign, readonly) NSUInteger loopCount; // 0 means repeating the animation indefinitely 38 | @property (nonatomic, strong, readonly) NSDictionary *delayTimesForIndexes; // Of type `NSTimeInterval` boxed in `NSNumber`s 39 | @property (nonatomic, assign, readonly) NSUInteger frameCount; // Number of valid frames; equal to `[.delayTimes count]` 40 | 41 | @property (nonatomic, assign, readonly) NSUInteger frameCacheSizeCurrent; // Current size of intelligently chosen buffer window; can range in the interval [1..frameCount] 42 | @property (nonatomic, assign) NSUInteger frameCacheSizeMax; // Allow to cap the cache size; 0 means no specific limit (default) 43 | 44 | // Intended to be called from main thread synchronously; will return immediately. 45 | // If the result isn't cached, will return `nil`; the caller should then pause playback, not increment frame counter and keep polling. 46 | // After an initial loading time, depending on `frameCacheSize`, frames should be available immediately from the cache. 47 | - (UIImage *)imageLazilyCachedAtIndex:(NSUInteger)index; 48 | 49 | // Pass either a `UIImage` or an `FLAnimatedImage` and get back its size 50 | + (CGSize)sizeForImage:(id)image; 51 | 52 | // On success, the initializers return an `FLAnimatedImage` with all fields initialized, on failure they return `nil` and an error will be logged. 53 | - (instancetype)initWithAnimatedGIFData:(NSData *)data; 54 | // Pass 0 for optimalFrameCacheSize to get the default, predrawing is enabled by default. 55 | - (instancetype)initWithAnimatedGIFData:(NSData *)data optimalFrameCacheSize:(NSUInteger)optimalFrameCacheSize predrawingEnabled:(BOOL)isPredrawingEnabled NS_DESIGNATED_INITIALIZER; 56 | + (instancetype)animatedImageWithGIFData:(NSData *)data; 57 | 58 | @property (nonatomic, strong, readonly) NSData *data; // The data the receiver was initialized with; read-only 59 | 60 | @end 61 | 62 | typedef NS_ENUM(NSUInteger, FLLogLevel) { 63 | FLLogLevelNone = 0, 64 | FLLogLevelError, 65 | FLLogLevelWarn, 66 | FLLogLevelInfo, 67 | FLLogLevelDebug, 68 | FLLogLevelVerbose 69 | }; 70 | 71 | @interface FLAnimatedImage (Logging) 72 | 73 | + (void)setLogBlock:(void (^)(NSString *logString, FLLogLevel logLevel))logBlock logLevel:(FLLogLevel)logLevel; 74 | + (void)logStringFromBlock:(NSString *(^)(void))stringBlock withLevel:(FLLogLevel)level; 75 | 76 | @end 77 | 78 | #define FLLog(logLevel, format, ...) [FLAnimatedImage logStringFromBlock:^NSString *{ return [NSString stringWithFormat:(format), ## __VA_ARGS__]; } withLevel:(logLevel)] 79 | 80 | @interface FLWeakProxy : NSProxy 81 | 82 | + (instancetype)weakProxyForObject:(id)targetObject; 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /PageController/SDWebImage/FLAnimatedImage/FLAnimatedImageView+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 "FLAnimatedImageView+WebCache.h" 10 | 11 | #if SD_UIKIT 12 | #import "objc/runtime.h" 13 | #import "UIView+WebCacheOperation.h" 14 | #import "UIView+WebCache.h" 15 | #import "NSData+ImageContentType.h" 16 | #import "FLAnimatedImage.h" 17 | #import "UIImageView+WebCache.h" 18 | 19 | @implementation FLAnimatedImageView (WebCache) 20 | 21 | - (void)sd_setImageWithURL:(nullable NSURL *)url { 22 | [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil]; 23 | } 24 | 25 | - (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder { 26 | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil]; 27 | } 28 | 29 | - (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options { 30 | [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil]; 31 | } 32 | 33 | - (void)sd_setImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock { 34 | [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock]; 35 | } 36 | 37 | - (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock { 38 | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock]; 39 | } 40 | 41 | - (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock { 42 | [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock]; 43 | } 44 | 45 | - (void)sd_setImageWithURL:(nullable NSURL *)url 46 | placeholderImage:(nullable UIImage *)placeholder 47 | options:(SDWebImageOptions)options 48 | progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock 49 | completed:(nullable SDExternalCompletionBlock)completedBlock { 50 | __weak typeof(self)weakSelf = self; 51 | [self sd_internalSetImageWithURL:url 52 | placeholderImage:placeholder 53 | options:options 54 | operationKey:nil 55 | setImageBlock:^(UIImage *image, NSData *imageData) { 56 | SDImageFormat imageFormat = [NSData sd_imageFormatForImageData:imageData]; 57 | if (imageFormat == SDImageFormatGIF) { 58 | weakSelf.animatedImage = [FLAnimatedImage animatedImageWithGIFData:imageData]; 59 | weakSelf.image = nil; 60 | } else { 61 | weakSelf.image = image; 62 | weakSelf.animatedImage = nil; 63 | } 64 | } 65 | progress:progressBlock 66 | completed:completedBlock]; 67 | } 68 | 69 | @end 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /PageController/SDWebImage/FLAnimatedImage/FLAnimatedImageView.h: -------------------------------------------------------------------------------- 1 | // 2 | // FLAnimatedImageView.h 3 | // Flipboard 4 | // 5 | // Created by Raphael Schaad on 7/8/13. 6 | // Copyright (c) 2013-2015 Flipboard. All rights reserved. 7 | // 8 | 9 | 10 | #import 11 | 12 | @class FLAnimatedImage; 13 | @protocol FLAnimatedImageViewDebugDelegate; 14 | 15 | 16 | // 17 | // An `FLAnimatedImageView` can take an `FLAnimatedImage` and plays it automatically when in view hierarchy and stops when removed. 18 | // The animation can also be controlled with the `UIImageView` methods `-start/stop/isAnimating`. 19 | // It is a fully compatible `UIImageView` subclass and can be used as a drop-in component to work with existing code paths expecting to display a `UIImage`. 20 | // Under the hood it uses a `CADisplayLink` for playback, which can be inspected with `currentFrame` & `currentFrameIndex`. 21 | // 22 | @interface FLAnimatedImageView : UIImageView 23 | 24 | // Setting `[UIImageView.image]` to a non-`nil` value clears out existing `animatedImage`. 25 | // And vice versa, setting `animatedImage` will initially populate the `[UIImageView.image]` to its `posterImage` and then start animating and hold `currentFrame`. 26 | @property (nonatomic, strong) FLAnimatedImage *animatedImage; 27 | @property (nonatomic, copy) void(^loopCompletionBlock)(NSUInteger loopCountRemaining); 28 | 29 | @property (nonatomic, strong, readonly) UIImage *currentFrame; 30 | @property (nonatomic, assign, readonly) NSUInteger currentFrameIndex; 31 | 32 | // The animation runloop mode. Enables playback during scrolling by allowing timer events (i.e. animation) with NSRunLoopCommonModes. 33 | // To keep scrolling smooth on single-core devices such as iPhone 3GS/4 and iPod Touch 4th gen, the default run loop mode is NSDefaultRunLoopMode. Otherwise, the default is NSDefaultRunLoopMode. 34 | @property (nonatomic, copy) NSString *runLoopMode; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /PageController/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 | -------------------------------------------------------------------------------- /PageController/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 | -------------------------------------------------------------------------------- /PageController/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 | @end 34 | -------------------------------------------------------------------------------- /PageController/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 | 12 | 13 | @implementation NSData (ImageContentType) 14 | 15 | + (SDImageFormat)sd_imageFormatForImageData:(nullable NSData *)data { 16 | if (!data) { 17 | return SDImageFormatUndefined; 18 | } 19 | 20 | uint8_t c; 21 | [data getBytes:&c length:1]; 22 | switch (c) { 23 | case 0xFF: 24 | return SDImageFormatJPEG; 25 | case 0x89: 26 | return SDImageFormatPNG; 27 | case 0x47: 28 | return SDImageFormatGIF; 29 | case 0x49: 30 | case 0x4D: 31 | return SDImageFormatTIFF; 32 | case 0x52: 33 | // R as RIFF for WEBP 34 | if (data.length < 12) { 35 | return SDImageFormatUndefined; 36 | } 37 | 38 | NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding]; 39 | if ([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) { 40 | return SDImageFormatWebP; 41 | } 42 | } 43 | return SDImageFormatUndefined; 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /PageController/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 | -------------------------------------------------------------------------------- /PageController/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 | -------------------------------------------------------------------------------- /PageController/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 maximum length of time to keep an image in the cache, in seconds 32 | */ 33 | @property (assign, nonatomic) NSInteger maxCacheAge; 34 | 35 | /** 36 | * The maximum size of the cache, in bytes. 37 | */ 38 | @property (assign, nonatomic) NSUInteger maxCacheSize; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /PageController/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 | _maxCacheAge = kDefaultCacheMaxCacheAge; 21 | _maxCacheSize = 0; 22 | } 23 | return self; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /PageController/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 | -------------------------------------------------------------------------------- /PageController/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 | 11 | #import "objc/runtime.h" 12 | 13 | #if !__has_feature(objc_arc) 14 | #error SDWebImage is ARC only. Either turn on ARC for the project or use -fobjc-arc flag 15 | #endif 16 | 17 | inline UIImage *SDScaledImageForKey(NSString * _Nullable key, UIImage * _Nullable image) { 18 | if (!image) { 19 | return nil; 20 | } 21 | 22 | #if SD_MAC 23 | return image; 24 | #elif SD_UIKIT || SD_WATCH 25 | if ((image.images).count > 0) { 26 | NSMutableArray *scaledImages = [NSMutableArray array]; 27 | 28 | for (UIImage *tempImage in image.images) { 29 | [scaledImages addObject:SDScaledImageForKey(key, tempImage)]; 30 | } 31 | 32 | UIImage *animatedImage = [UIImage animatedImageWithImages:scaledImages duration:image.duration]; 33 | #ifdef SD_WEBP 34 | if (animatedImage) { 35 | SEL sd_webpLoopCount = NSSelectorFromString(@"sd_webpLoopCount"); 36 | NSNumber *value = objc_getAssociatedObject(image, sd_webpLoopCount); 37 | NSInteger loopCount = value.integerValue; 38 | if (loopCount) { 39 | objc_setAssociatedObject(animatedImage, sd_webpLoopCount, @(loopCount), OBJC_ASSOCIATION_RETAIN_NONATOMIC); 40 | } 41 | } 42 | #endif 43 | return animatedImage; 44 | } else { 45 | #if SD_WATCH 46 | if ([[WKInterfaceDevice currentDevice] respondsToSelector:@selector(screenScale)]) { 47 | #elif SD_UIKIT 48 | if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) { 49 | #endif 50 | CGFloat scale = 1; 51 | if (key.length >= 8) { 52 | NSRange range = [key rangeOfString:@"@2x."]; 53 | if (range.location != NSNotFound) { 54 | scale = 2.0; 55 | } 56 | 57 | range = [key rangeOfString:@"@3x."]; 58 | if (range.location != NSNotFound) { 59 | scale = 3.0; 60 | } 61 | } 62 | 63 | UIImage *scaledImage = [[UIImage alloc] initWithCGImage:image.CGImage scale:scale orientation:image.imageOrientation]; 64 | image = scaledImage; 65 | } 66 | return image; 67 | } 68 | #endif 69 | } 70 | 71 | NSString *const SDWebImageErrorDomain = @"SDWebImageErrorDomain"; 72 | -------------------------------------------------------------------------------- /PageController/SDWebImage/SDWebImageDecoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * (c) james 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 | @interface UIImage (ForceDecode) 14 | 15 | + (nullable UIImage *)decodedImageWithImage:(nullable UIImage *)image; 16 | 17 | + (nullable UIImage *)decodedAndScaledDownImageWithImage:(nullable UIImage *)image; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /PageController/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 | -------------------------------------------------------------------------------- /PageController/SDWebImage/SDWebImageHeaders.h: -------------------------------------------------------------------------------- 1 | // 2 | // SDWebImageHeaders.h 3 | // HKConnect 4 | // 5 | // Created by Simon Li on 14-8-7. 6 | // Copyright (c) 2014年 Harman. All rights reserved. 7 | // 8 | 9 | #ifndef HKConnect_SDWebImageHeaders_h 10 | #define HKConnect_SDWebImageHeaders_h 11 | 12 | #import "MKAnnotationView+WebCache.h" 13 | #import "NSData+ImageContentType.h" 14 | #import "SDImageCache.h" 15 | #import "SDWebImageCompat.h" 16 | #import "SDWebImageDecoder.h" 17 | #import "SDWebImageDownloader.h" 18 | #import "SDWebImageDownloaderOperation.h" 19 | #import "SDWebImageManager.h" 20 | #import "SDWebImageOperation.h" 21 | #import "SDWebImagePrefetcher.h" 22 | #import "UIButton+WebCache.h" 23 | #import "UIImage+GIF.h" 24 | #import "UIImage+MultiFormat.h" 25 | #import "UIImage+WebP.h" 26 | #import "UIImageView+HighlightedWebCache.h" 27 | #import "UIImageView+WebCache.h" 28 | #import "UIView+WebCacheOperation.h" 29 | 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /PageController/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 | -------------------------------------------------------------------------------- /PageController/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 | -------------------------------------------------------------------------------- /PageController/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 | * Compatibility method - creates an animated UIImage from an NSData, it will only contain the 1st frame image 16 | */ 17 | + (UIImage *)sd_animatedGIFWithData:(NSData *)data; 18 | 19 | /** 20 | * Checks if an UIImage instance is a GIF. Will use the `images` array 21 | */ 22 | - (BOOL)isGIF; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /PageController/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 12 | #import "objc/runtime.h" 13 | #import "NSImage+WebCache.h" 14 | 15 | @implementation UIImage (GIF) 16 | 17 | + (UIImage *)sd_animatedGIFWithData:(NSData *)data { 18 | if (!data) { 19 | return nil; 20 | } 21 | 22 | #if SD_MAC 23 | return [[UIImage alloc] initWithData:data]; 24 | #else 25 | 26 | CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL); 27 | 28 | size_t count = CGImageSourceGetCount(source); 29 | 30 | UIImage *staticImage; 31 | 32 | if (count <= 1) { 33 | staticImage = [[UIImage alloc] initWithData:data]; 34 | } else { 35 | // we will only retrieve the 1st frame. the full GIF support is available via the FLAnimatedImageView category. 36 | // this here is only code to allow drawing animated images as static ones 37 | #if SD_WATCH 38 | CGFloat scale = 1; 39 | scale = [WKInterfaceDevice currentDevice].screenScale; 40 | #elif SD_UIKIT 41 | CGFloat scale = 1; 42 | scale = [UIScreen mainScreen].scale; 43 | #endif 44 | 45 | CGImageRef CGImage = CGImageSourceCreateImageAtIndex(source, 0, NULL); 46 | #if SD_UIKIT || SD_WATCH 47 | UIImage *frameImage = [UIImage imageWithCGImage:CGImage scale:scale orientation:UIImageOrientationUp]; 48 | staticImage = [UIImage animatedImageWithImages:@[frameImage] duration:0.0f]; 49 | #endif 50 | CGImageRelease(CGImage); 51 | } 52 | 53 | CFRelease(source); 54 | 55 | return staticImage; 56 | #endif 57 | } 58 | 59 | - (BOOL)isGIF { 60 | return (self.images != nil); 61 | } 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /PageController/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 | + (nullable UIImage *)sd_imageWithData:(nullable NSData *)data; 15 | - (nullable NSData *)sd_imageData; 16 | - (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /PageController/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 | */ 23 | - (NSInteger)sd_webpLoopCount; 24 | 25 | + (nullable UIImage *)sd_imageWithWebPData:(nullable NSData *)data; 26 | 27 | @end 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /PageController/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 | -------------------------------------------------------------------------------- /PageController/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 | -------------------------------------------------------------------------------- /PageController/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 | -------------------------------------------------------------------------------- /PageController/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 | -------------------------------------------------------------------------------- /PageController/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 | -------------------------------------------------------------------------------- /PageController/TabbarIcon/Me_shareFriends@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/TabbarIcon/Me_shareFriends@2x.png -------------------------------------------------------------------------------- /PageController/TabbarIcon/Me_shareFriends@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/TabbarIcon/Me_shareFriends@3x.png -------------------------------------------------------------------------------- /PageController/TabbarIcon/back_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/TabbarIcon/back_icon@2x.png -------------------------------------------------------------------------------- /PageController/TabbarIcon/back_icon_active@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/TabbarIcon/back_icon_active@2x.png -------------------------------------------------------------------------------- /PageController/TabbarIcon/home@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/TabbarIcon/home@2x.png -------------------------------------------------------------------------------- /PageController/TabbarIcon/shareArrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/TabbarIcon/shareArrow@2x.png -------------------------------------------------------------------------------- /PageController/TabbarIcon/shareArrow@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/TabbarIcon/shareArrow@3x.png -------------------------------------------------------------------------------- /PageController/TabbarIcon/tabbar_BBS@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/TabbarIcon/tabbar_BBS@2x.png -------------------------------------------------------------------------------- /PageController/TabbarIcon/tabbar_BBS@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/TabbarIcon/tabbar_BBS@3x.png -------------------------------------------------------------------------------- /PageController/TabbarIcon/tabbar_BBS_highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/TabbarIcon/tabbar_BBS_highlighted@2x.png -------------------------------------------------------------------------------- /PageController/TabbarIcon/tabbar_BBS_highlighted@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/TabbarIcon/tabbar_BBS_highlighted@3x.png -------------------------------------------------------------------------------- /PageController/TabbarIcon/tabbar_homePage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/TabbarIcon/tabbar_homePage@2x.png -------------------------------------------------------------------------------- /PageController/TabbarIcon/tabbar_homePage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/TabbarIcon/tabbar_homePage@3x.png -------------------------------------------------------------------------------- /PageController/TabbarIcon/tabbar_homePage_highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/TabbarIcon/tabbar_homePage_highlighted@2x.png -------------------------------------------------------------------------------- /PageController/TabbarIcon/tabbar_homePage_highlighted@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/TabbarIcon/tabbar_homePage_highlighted@3x.png -------------------------------------------------------------------------------- /PageController/TabbarIcon/tabbar_me@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/TabbarIcon/tabbar_me@2x.png -------------------------------------------------------------------------------- /PageController/TabbarIcon/tabbar_me@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/TabbarIcon/tabbar_me@3x.png -------------------------------------------------------------------------------- /PageController/TabbarIcon/tabbar_me_highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/TabbarIcon/tabbar_me_highlighted@2x.png -------------------------------------------------------------------------------- /PageController/TabbarIcon/tabbar_me_highlighted@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/TabbarIcon/tabbar_me_highlighted@3x.png -------------------------------------------------------------------------------- /PageController/TabbarIcon/tabbar_myCourse@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/TabbarIcon/tabbar_myCourse@2x.png -------------------------------------------------------------------------------- /PageController/TabbarIcon/tabbar_myCourse@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/TabbarIcon/tabbar_myCourse@3x.png -------------------------------------------------------------------------------- /PageController/TabbarIcon/tabbar_myCourse_highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/TabbarIcon/tabbar_myCourse_highlighted@2x.png -------------------------------------------------------------------------------- /PageController/TabbarIcon/tabbar_myCourse_highlighted@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/PageController/TabbarIcon/tabbar_myCourse_highlighted@3x.png -------------------------------------------------------------------------------- /PageController/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // PageController 4 | // 5 | // Created by L_晨曦 on 2017/10/17. 6 | // Copyright © 2017年 L_晨曦. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /PageController/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // PageController 4 | // 5 | // Created by L_晨曦 on 2017/10/17. 6 | // Copyright © 2017年 L_晨曦. All rights reserved. 7 | // 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 | -------------------------------------------------------------------------------- /PageController/XLChannelControl/XLChannelControl.h: -------------------------------------------------------------------------------- 1 | // 2 | // XLChannelControl.h 3 | // XLChannelControlDemo 4 | // 5 | // Created by MengXianLiang on 2017/3/3. 6 | // Copyright © 2017年 MengXianLiang. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef void(^ChannelBlock)(NSArray *inUseTitles,NSArray *unUseTitles,NSString *title, BOOL isChange); 12 | 13 | @interface XLChannelControl : NSObject 14 | 15 | +(XLChannelControl*)shareControl; 16 | 17 | -(void)showChannelViewWithInUseTitles:(NSArray*)inUseTitles unUseTitles:(NSArray*)unUseTitles finish:(ChannelBlock)block; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /PageController/XLChannelControl/XLChannelControl.m: -------------------------------------------------------------------------------- 1 | // 2 | // XLChannelControl.m 3 | // XLChannelControlDemo 4 | // 5 | // Created by MengXianLiang on 2017/3/3. 6 | // Copyright © 2017年 MengXianLiang. All rights reserved. 7 | // 8 | 9 | #import "XLChannelControl.h" 10 | #import "XLChannelView.h" 11 | 12 | @interface XLChannelControl () 13 | { 14 | UINavigationController *_nav; 15 | 16 | XLChannelView *_channelView; 17 | 18 | UIButton *_leftBtn; 19 | 20 | ChannelBlock _block; 21 | } 22 | @end 23 | 24 | @implementation XLChannelControl 25 | 26 | +(XLChannelControl*)shareControl{ 27 | static XLChannelControl *control = nil; 28 | static dispatch_once_t onceToken; 29 | dispatch_once(&onceToken, ^{ 30 | control = [[XLChannelControl alloc] init]; 31 | }); 32 | return control; 33 | } 34 | 35 | -(instancetype)init 36 | { 37 | if (self = [super init]) { 38 | [self buildChannelView]; 39 | } 40 | return self; 41 | } 42 | 43 | -(void)buildChannelView{ 44 | 45 | _channelView = [[XLChannelView alloc] initWithFrame:[UIScreen mainScreen].bounds]; 46 | 47 | __weak typeof(self) weakSelf = self; 48 | _channelView.didClickCategoryItem = ^(NSString *title,BOOL isChange) { 49 | [weakSelf backMethodWhenDidClick:title]; 50 | }; 51 | 52 | _nav = [[UINavigationController alloc] initWithRootViewController:[UIViewController new]]; 53 | _nav.navigationBar.tintColor = [UIColor blackColor]; 54 | _nav.topViewController.title = @"频道管理"; 55 | _nav.topViewController.view = _channelView; 56 | _nav.topViewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop target:self action:@selector(backMethod)]; 57 | 58 | _leftBtn = [UIButton buttonWithType:UIButtonTypeCustom]; 59 | //66,141,244 60 | UIColor *color = [UIColor colorWithRed:66/255.0 green:141/255.0 blue:244/255.0 alpha:1]; 61 | 62 | [_leftBtn setTitleColor:color forState:UIControlStateNormal]; 63 | [_leftBtn setTitleColor:color forState:UIControlStateSelected]; 64 | 65 | [_leftBtn setTitle:@"编辑" forState:UIControlStateNormal]; 66 | [_leftBtn setTitle:@"完成" forState:UIControlStateSelected]; 67 | [_leftBtn sizeToFit]; 68 | [_leftBtn addTarget:self action:@selector(editAction:) forControlEvents:UIControlEventTouchDown]; 69 | _nav.topViewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:_leftBtn]; 70 | } 71 | 72 | 73 | - (void)editAction:(UIButton*)sender { 74 | 75 | sender.selected = !sender.selected; 76 | // 编辑状态 是否; 77 | _channelView.editStatus = sender.isSelected; 78 | 79 | 80 | 81 | 82 | } 83 | 84 | 85 | - (void)backMethodWhenDidClick:(NSString *)title { 86 | [UIView animateWithDuration:0.3 animations:^{ 87 | CGRect frame = _nav.view.frame; 88 | frame.origin.y = - _nav.view.bounds.size.height; 89 | _nav.view.frame = frame; 90 | }completion:^(BOOL finished) { 91 | [_nav.view removeFromSuperview]; 92 | }]; 93 | _block(_channelView.inUseTitles,_channelView.unUseTitles,title, _channelView.isChange); 94 | [self changeStatus]; 95 | } 96 | 97 | - (void)backMethod { 98 | /* 99 | [UIView animateWithDuration:0.3 animations:^{ 100 | CGRect frame = _nav.view.frame; 101 | frame.origin.y = - _nav.view.bounds.size.height; 102 | _nav.view.frame = frame; 103 | }completion:^(BOOL finished) { 104 | [_nav.view removeFromSuperview]; 105 | }]; 106 | _block(_channelView.inUseTitles,_channelView.unUseTitles,nil, _channelView.isChange); 107 | [self changeStatus]; 108 | */ 109 | [self backMethodWhenDidClick:nil]; 110 | } 111 | 112 | 113 | - (void)changeStatus { 114 | _channelView.isChange = NO; 115 | _leftBtn.selected = NO; 116 | _channelView.editStatus = NO; 117 | [_channelView reloadData]; 118 | } 119 | 120 | -(void)showChannelViewWithInUseTitles:(NSArray*)inUseTitles unUseTitles:(NSArray*)unUseTitles finish:(ChannelBlock)block{ 121 | _block = block; 122 | _channelView.inUseTitles = [NSMutableArray arrayWithArray:inUseTitles]; 123 | _channelView.unUseTitles = [NSMutableArray arrayWithArray:unUseTitles]; 124 | [_channelView reloadData]; 125 | 126 | CGRect frame = _nav.view.frame; 127 | frame.origin.y = - _nav.view.bounds.size.height; 128 | _nav.view.frame = frame; 129 | _nav.view.alpha = 0; 130 | [[UIApplication sharedApplication].keyWindow addSubview:_nav.view]; 131 | [UIView animateWithDuration:0.3 animations:^{ 132 | _nav.view.alpha = 1; 133 | _nav.view.frame = [UIScreen mainScreen].bounds; 134 | }]; 135 | } 136 | 137 | @end 138 | -------------------------------------------------------------------------------- /PageController/XLChannelControl/XLChannelHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // XLChannelHeaderView.h 3 | // XLChannelControlDemo 4 | // 5 | // Created by MengXianLiang on 2017/3/3. 6 | // Copyright © 2017年 MengXianLiang. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface XLChannelHeader : UICollectionReusableView 12 | 13 | @property (copy,nonatomic) NSString *title; 14 | 15 | @property (copy,nonatomic) NSString *subTitle; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /PageController/XLChannelControl/XLChannelHeader.m: -------------------------------------------------------------------------------- 1 | // 2 | // XLChannelHeaderView.m 3 | // XLChannelControlDemo 4 | // 5 | // Created by MengXianLiang on 2017/3/3. 6 | // Copyright © 2017年 MengXianLiang. All rights reserved. 7 | // 8 | 9 | #import "XLChannelHeader.h" 10 | 11 | @interface XLChannelHeader () 12 | { 13 | UILabel *_titleLabel; 14 | 15 | UILabel *_subtitleLabel; 16 | } 17 | @end 18 | 19 | @implementation XLChannelHeader 20 | 21 | -(instancetype)initWithFrame:(CGRect)frame 22 | { 23 | if (self = [super initWithFrame:frame]) { 24 | [self buildUI]; 25 | } 26 | return self; 27 | } 28 | 29 | -(void)buildUI 30 | { 31 | CGFloat marginX = 15.0f; 32 | 33 | //CGFloat labelWidth = (self.bounds.size.width - 2*marginX)/2.0f; 34 | 35 | _titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(marginX, 0, 16 *4 +15, self.bounds.size.height)]; 36 | _titleLabel.textColor = [UIColor blackColor]; 37 | _titleLabel.font = [UIFont systemFontOfSize:16.0f]; 38 | _titleLabel.text = @"我的科目"; 39 | [self addSubview:_titleLabel]; 40 | 41 | _subtitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(_titleLabel.frame), 0,self.bounds.size.width - CGRectGetMaxX(_titleLabel.frame)-2*marginX, self.bounds.size.height)]; 42 | _subtitleLabel.textColor = [UIColor lightGrayColor]; 43 | _subtitleLabel.textAlignment = NSTextAlignmentLeft; 44 | _subtitleLabel.font = [UIFont systemFontOfSize:15.0f]; 45 | [self addSubview:_subtitleLabel]; 46 | 47 | 48 | } 49 | 50 | -(void)setTitle:(NSString *)title 51 | { 52 | _title = title; 53 | _titleLabel.text = title; 54 | } 55 | 56 | -(void)setSubTitle:(NSString *)subTitle 57 | { 58 | _subTitle = subTitle; 59 | _subtitleLabel.text = subTitle; 60 | } 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /PageController/XLChannelControl/XLChannelItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // XLChannelItem.h 3 | // XLChannelControlDemo 4 | // 5 | // Created by MengXianLiang on 2017/3/3. 6 | // Copyright © 2017年 MengXianLiang. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface XLChannelItem : UICollectionViewCell 12 | //标题 13 | @property (nonatomic, copy) NSString *title; 14 | 15 | //是否正在移动状态 16 | @property (nonatomic, assign) BOOL isMoving; 17 | 18 | //是否被固定 19 | @property (nonatomic, assign) BOOL isFixed; 20 | 21 | /* 编辑按钮 */ 22 | @property (nonatomic, strong) UIButton *editButton; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /PageController/XLChannelControl/XLChannelItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // XLChannelItem.m 3 | // XLChannelControlDemo 4 | // 5 | // Created by MengXianLiang on 2017/3/3. 6 | // Copyright © 2017年 MengXianLiang. All rights reserved. 7 | // 8 | 9 | #import "XLChannelItem.h" 10 | #import "Masonry.h" 11 | @interface XLChannelItem (){ 12 | 13 | CAShapeLayer *_borderLayer; 14 | } 15 | 16 | @property (nonatomic, strong) UILabel *titleLabel; 17 | @property (nonatomic, strong) UIImageView *iconView; 18 | @end 19 | 20 | @implementation XLChannelItem 21 | 22 | -(instancetype)initWithFrame:(CGRect)frame 23 | { 24 | self = [super initWithFrame:frame]; 25 | if (self) { 26 | [self initUI]; 27 | } 28 | return self; 29 | } 30 | 31 | -(void)initUI 32 | { 33 | self.userInteractionEnabled = true; 34 | self.layer.cornerRadius = 5.0f; 35 | //self.backgroundColor = [self backgroundColor]; 36 | self.backgroundColor = [UIColor whiteColor]; 37 | _titleLabel = [UILabel new]; 38 | _titleLabel.textAlignment = NSTextAlignmentCenter; 39 | _titleLabel.textColor = [self textColor]; 40 | // _titleLabel.adjustsFontSizeToFitWidth = true; 41 | // _titleLabel.userInteractionEnabled = true; 42 | _titleLabel.text = @"工业设计"; 43 | _titleLabel.font = [UIFont systemFontOfSize:11]; 44 | [self.contentView addSubview:_titleLabel]; 45 | 46 | _iconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"category_edit_recommend"]]; 47 | [self.contentView addSubview:_iconView]; 48 | 49 | _editButton = [UIButton buttonWithType:UIButtonTypeCustom]; 50 | _editButton.userInteractionEnabled = NO; 51 | [_editButton setImage:[UIImage imageNamed:@"category_edit_add"] forState:UIControlStateNormal]; 52 | [_editButton setImage:[UIImage imageNamed:@"category_edit_delect"] forState:UIControlStateSelected]; 53 | [self.contentView addSubview:_editButton]; 54 | 55 | [self addSubViewConstraint] ; 56 | [self addBorderLayer]; 57 | } 58 | 59 | -(void)addBorderLayer{ 60 | _borderLayer = [CAShapeLayer layer]; 61 | _borderLayer.bounds = self.bounds; 62 | _borderLayer.position = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds)); 63 | _borderLayer.path = [UIBezierPath bezierPathWithRoundedRect:_borderLayer.bounds cornerRadius:self.layer.cornerRadius].CGPath; 64 | _borderLayer.lineWidth = 1; 65 | _borderLayer.lineDashPattern = @[@5, @3]; 66 | _borderLayer.fillColor = [UIColor clearColor].CGColor; 67 | _borderLayer.strokeColor = [self backgroundColor].CGColor; 68 | [self.layer addSublayer:_borderLayer]; 69 | _borderLayer.hidden = true; 70 | } 71 | 72 | - (void)addSubViewConstraint { 73 | 74 | [_iconView mas_makeConstraints:^(MASConstraintMaker *make) { 75 | make.top.equalTo(self.contentView).offset(10); 76 | make.centerX.equalTo(self.contentView); 77 | make.height.width.mas_equalTo(54/2); 78 | }]; 79 | 80 | [_titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { 81 | make.left.right.equalTo(self.contentView); 82 | make.top.equalTo(_iconView.mas_bottom).offset(20); 83 | }]; 84 | 85 | [_editButton mas_makeConstraints:^(MASConstraintMaker *make) { 86 | make.right.equalTo(_iconView).offset(34/4); 87 | make.bottom.equalTo(_iconView).offset(34/4); 88 | make.width.height.mas_equalTo(34/2); 89 | }]; 90 | } 91 | 92 | -(void)layoutSubviews 93 | { 94 | [super layoutSubviews]; 95 | //_titleLabel.frame = self.bounds; 96 | } 97 | 98 | #pragma mark - 99 | #pragma mark 配置方法 100 | 101 | -(UIColor*)backgroundColor{ 102 | return [UIColor colorWithRed:241/255.0f green:241/255.0f blue:241/255.0f alpha:1]; 103 | } 104 | 105 | -(UIColor*)textColor{ 106 | return [UIColor colorWithRed:40/255.0f green:40/255.0f blue:40/255.0f alpha:1]; 107 | } 108 | 109 | -(UIColor*)lightTextColor{ 110 | return [UIColor colorWithRed:200/255.0f green:200/255.0f blue:200/255.0f alpha:1]; 111 | } 112 | 113 | #pragma mark - 114 | #pragma mark Setter 115 | 116 | -(void)setTitle:(NSString *)title 117 | { 118 | _title = title; 119 | _titleLabel.text = title; 120 | } 121 | 122 | -(void)setIsMoving:(BOOL)isMoving 123 | { 124 | _isMoving = isMoving; 125 | if (_isMoving) { 126 | self.backgroundColor = [UIColor whiteColor]; 127 | _borderLayer.hidden = false; 128 | }else{ 129 | //self.backgroundColor = [self backgroundColor]; 130 | self.backgroundColor = [UIColor whiteColor]; 131 | 132 | _borderLayer.hidden = true; 133 | } 134 | } 135 | 136 | -(void)setIsFixed:(BOOL)isFixed{ 137 | _isFixed = isFixed; 138 | if (isFixed) { 139 | _titleLabel.textColor = [self lightTextColor]; 140 | }else{ 141 | _titleLabel.textColor = [self textColor]; 142 | } 143 | } 144 | 145 | @end 146 | -------------------------------------------------------------------------------- /PageController/XLChannelControl/XLChannelView.h: -------------------------------------------------------------------------------- 1 | // 2 | // XLChannelView.h 3 | // XLChannelControlDemo 4 | // 5 | // Created by MengXianLiang on 2017/3/3. 6 | // Copyright © 2017年 MengXianLiang. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface XLChannelView : UIView 12 | 13 | @property (nonatomic, strong) NSMutableArray *inUseTitles; 14 | 15 | @property (nonatomic,strong) NSMutableArray *unUseTitles; 16 | 17 | /*编辑状态*/ 18 | @property (nonatomic, assign) BOOL editStatus; 19 | 20 | /* 是否编辑过 */ 21 | @property (nonatomic, assign) BOOL isChange; 22 | 23 | /*点击跳出到查看界面*/ 24 | @property (nonatomic, copy) void (^didClickCategoryItem)(NSString *title, BOOL isChagne); 25 | 26 | -(void)reloadData; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /PageController/XSBaseTableViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // XSBaseTableViewCell.h 3 | // XSTeachEDU 4 | // 5 | // Created by xsteach on 14/12/19. 6 | // Copyright (c) 2014年 xsteach.com. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface XSBaseTableViewCell : UITableViewCell 12 | 13 | + (instancetype)cellWithTableView:(UITableView *)tableView; 14 | 15 | - (void)addOwnViews; 16 | - (void)addConstraints; 17 | 18 | - (void)setupInit; 19 | 20 | + (NSString *)identifer; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /PageController/XSBaseTableViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // XSBaseTableViewCell.m 3 | // XSTeachEDU 4 | // 5 | // Created by xsteach on 14/12/19. 6 | // Copyright (c) 2014年 xsteach.com. All rights reserved. 7 | // 8 | 9 | #import "XSBaseTableViewCell.h" 10 | 11 | @implementation XSBaseTableViewCell 12 | 13 | + (instancetype)cellWithTableView:(UITableView *)tableView { 14 | XSBaseTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([self class])]; 15 | if (!cell) { 16 | cell = [[[self class] alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:NSStringFromClass([self class])]; 17 | 18 | } 19 | return cell; 20 | } 21 | 22 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 23 | if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { 24 | [self setupInit]; 25 | [self addOwnViews]; 26 | [self addConstraints]; 27 | } 28 | return self; 29 | } 30 | 31 | - (void)setupInit { 32 | self.backgroundColor = [UIColor whiteColor]; 33 | UIView * selectedView = [[UIView alloc]initWithFrame:CGRectZero]; 34 | selectedView.backgroundColor = [UIColor colorWithHex:0xF7F7F9]; 35 | self.selectedBackgroundView = selectedView; 36 | } 37 | 38 | - (void)addOwnViews {} 39 | - (void)addConstraints{} 40 | 41 | + (NSString *)identifer { 42 | return NSStringFromClass([self class]); 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /PageController/XSCourseCategoryVC.h: -------------------------------------------------------------------------------- 1 | // 2 | // XSHomeNavCouseVC.h 3 | // XSTeachEDU 4 | // 5 | // Created by L_晨曦 on 2017/9/21. 6 | // Copyright © 2017年 xsteach.com. All rights reserved. 7 | // 8 | 9 | #import 10 | @interface XSCourseCategoryVC :UIViewController 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /PageController/XSCourseCollectionViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // XSCourseCollectionViewCell.h 3 | // XSTeachEDU 4 | // 5 | // Created by L_晨曦 on 2017/9/22. 6 | // Copyright © 2017年 xsteach.com. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface XSCourseCollectionViewCell : UICollectionViewCell 12 | 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /PageController/XSHomeHeadView.h: -------------------------------------------------------------------------------- 1 | // 2 | // XSHomeHeadView.h 3 | // XSTeachEDU 4 | // 5 | // Created by L_晨曦 on 2017/9/20. 6 | // Copyright © 2017年 xsteach.com. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SDCycleScrollView.h" 11 | 12 | @interface XSHomeHeadView : UIView 13 | @property (nonatomic, strong) SDCycleScrollView *cycleScrollView; 14 | @property (nonatomic, strong) UIButton *voiceBtnBackView; 15 | @property (nonatomic, strong) UITableView *tableView; 16 | 17 | /*课程分类点击*/ 18 | @property (nonatomic, copy) void (^courCategoryBlock)(NSInteger index); 19 | 20 | @property (nonatomic, copy) void (^voiceActionBlock)(); 21 | 22 | 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /PageController/XSHomePageVC.h: -------------------------------------------------------------------------------- 1 | // 2 | // XSHomePageVC.h 3 | // XSTeachEDU 4 | // 5 | // Created by L_晨曦 on 2017/9/22. 6 | // Copyright © 2017年 xsteach.com. All rights reserved. 7 | // 8 | 9 | 10 | #import 11 | @interface XSHomePageVC : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PageController/XSMyTabar.h: -------------------------------------------------------------------------------- 1 | // 2 | // XSMyTabar.h 3 | // XSTeachEDU 4 | // 5 | // Created by x on 2017/2/21. 6 | // Copyright © 2017年 xsteach.com. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface XSMyTabar : UITabBar 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PageController/XSMyTabar.m: -------------------------------------------------------------------------------- 1 | // 2 | // XSMyTabar.m 3 | // XSTeachEDU 4 | // 5 | // Created by x on 2017/2/21. 6 | // Copyright © 2017年 xsteach.com. All rights reserved. 7 | // 8 | 9 | #import "XSMyTabar.h" 10 | 11 | @implementation XSMyTabar { 12 | UIView *_shadowView; 13 | } 14 | 15 | - (instancetype)initWithFrame:(CGRect)frame { 16 | if (self = [super initWithFrame:frame]) { 17 | } 18 | return self; 19 | } 20 | 21 | - (void)layoutSubviews{ 22 | [super layoutSubviews]; 23 | for (UIControl *tabBarButton in self.subviews) { 24 | if ([tabBarButton isKindOfClass:NSClassFromString(@"UITabBarButton")]) { 25 | 26 | [tabBarButton addTarget:self action:@selector(tabBarButtonClick:) forControlEvents:UIControlEventTouchUpInside]; 27 | } 28 | } 29 | } 30 | 31 | - (void)tabBarButtonClick:(UIControl *)tabBarButton { 32 | for (UIView *imageView in tabBarButton.subviews) { 33 | if ([imageView isKindOfClass:NSClassFromString(@"UITabBarSwappableImageView")]) { 34 | CAKeyframeAnimation *animation = [CAKeyframeAnimation animation]; 35 | animation.keyPath = @"transform.scale"; 36 | //animation.values = @[@1.0,@1.3,@0.9,@1.15,@0.95,@1.02,@1.0]; 37 | animation.values = @[@1.0,@1.1,@1.25,@1.1,@1.0]; 38 | animation.duration = 0.5; 39 | animation.calculationMode = kCAAnimationCubic; 40 | [imageView.layer addAnimation:animation forKey:nil]; 41 | } 42 | } 43 | } 44 | @end 45 | -------------------------------------------------------------------------------- /PageController/XSNavCourseReusableView.h: -------------------------------------------------------------------------------- 1 | // 2 | // XSNavCourseReusableView.h 3 | // XSTeachEDU 4 | // 5 | // Created by L_晨曦 on 2017/9/22. 6 | // Copyright © 2017年 xsteach.com. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface XSNavCourseReusableView : UIView 12 | 13 | @property (nonatomic, strong) NSArray *titleAry; 14 | @property (nonatomic, strong) UIView *categoryView; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /PageController/XSNavCourseReusableView.m: -------------------------------------------------------------------------------- 1 | // 2 | // XSNavCourseReusableView.m 3 | // XSTeachEDU 4 | // 5 | // Created by L_晨曦 on 2017/9/22. 6 | // Copyright © 2017年 xsteach.com. All rights reserved. 7 | // 8 | 9 | #import "XSNavCourseReusableView.h" 10 | #import "UIColor+Hex.h" 11 | #import "UIImage+Common.h" 12 | #import "Masonry.h" 13 | @interface XSNavCourseReusableView () 14 | @property (nonatomic, strong) UIButton *selectBtn; 15 | 16 | @end 17 | 18 | @implementation XSNavCourseReusableView 19 | 20 | - (instancetype)initWithFrame:(CGRect)frame{ 21 | 22 | if (self = [super initWithFrame:frame]) { 23 | self.backgroundColor = [UIColor redColor]; 24 | [self addSubViews]; 25 | UILabel *lable = [[UILabel alloc] initWithFrame:self.frame]; 26 | [self addSubview:lable]; 27 | lable.text = @"djdjdddddddddd"; 28 | lable.backgroundColor = [UIColor orangeColor]; 29 | 30 | } 31 | return self; 32 | } 33 | 34 | #pragma mark - func 35 | 36 | - (void)addSubViews { 37 | 38 | [self didAddSubview:self.categoryView]; 39 | } 40 | 41 | #pragma mark - cation 42 | 43 | - (void)categoryBtnClick:(UIButton *)sender { 44 | NSLog(@"分类头部点击"); 45 | _selectBtn.selected = NO; 46 | _selectBtn.layer.borderColor = [UIColor colorWithHex:0xececf3].CGColor; 47 | 48 | sender.selected = YES; 49 | sender.layer.borderColor = [UIColor colorWithHex:0xececf3].CGColor; 50 | _selectBtn = sender; 51 | 52 | } 53 | 54 | 55 | #pragma mark - set 56 | 57 | - (void)setTitleAry:(NSArray *)titleAry { 58 | 59 | 60 | [_categoryView.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 61 | [obj removeFromSuperview]; 62 | }]; 63 | 64 | for (int index = 0; index < titleAry.count; ++index) { 65 | 66 | UIView *backView = [[UIView alloc] initWithFrame:CGRectMake(self.frame.size.width/4 *index, 0, self.frame.size.width/4, 60)]; 67 | [_categoryView addSubview:backView]; 68 | 69 | UIButton *categoryBtn = [UIButton buttonWithType:UIButtonTypeCustom]; 70 | [categoryBtn setTitle:titleAry[index] forState:UIControlStateNormal]; 71 | categoryBtn.layer.cornerRadius = 15; 72 | categoryBtn.layer.masksToBounds = YES; 73 | categoryBtn.titleLabel.font = [UIFont systemFontOfSize:13.0f]; 74 | categoryBtn.layer.borderColor = [UIColor colorWithHex:0xececf3].CGColor;// colorWithHex: 75 | categoryBtn.layer.borderWidth = 1.0f; 76 | 77 | [categoryBtn setTitleColor:[UIColor colorWithHex:0x666b81] forState:UIControlStateNormal]; 78 | [categoryBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected]; 79 | 80 | UIImage *image = [UIImage imageWithColor:[UIColor colorWithHex:0x428df4]]; 81 | UIImage *images = [UIImage imageWithColor:[UIColor whiteColor]]; 82 | [categoryBtn setBackgroundImage:images forState:UIControlStateNormal]; 83 | [categoryBtn setBackgroundImage:image forState:UIControlStateSelected]; 84 | 85 | [categoryBtn addTarget:self action:@selector(categoryBtnClick:) forControlEvents:UIControlEventTouchUpInside]; 86 | [categoryBtn sizeToFit]; 87 | [backView addSubview:categoryBtn]; 88 | 89 | NSString *tempStr = titleAry[index]; 90 | CGFloat ButtonW = tempStr.length *13.0f + 15 ; 91 | categoryBtn.frame = CGRectMake(0,0, ButtonW, 30); 92 | categoryBtn.center = backView.center; 93 | 94 | [categoryBtn mas_makeConstraints:^(MASConstraintMaker *make) { 95 | make.width.mas_equalTo(ButtonW); 96 | make.center.equalTo(backView); 97 | make.height.equalTo(@30); 98 | }]; 99 | 100 | if (index == 0) { 101 | categoryBtn.selected = YES; 102 | categoryBtn.layer.borderColor = [UIColor clearColor].CGColor; 103 | _selectBtn = categoryBtn; 104 | } 105 | } 106 | } 107 | 108 | 109 | 110 | #pragma mark - lazy 111 | - (UIView *)categoryView { 112 | if (_categoryView == nil) { 113 | 114 | _categoryView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 60)]; 115 | _categoryView.backgroundColor = [UIColor blueColor]; 116 | } 117 | return _categoryView; 118 | } 119 | 120 | @end 121 | -------------------------------------------------------------------------------- /PageController/XSNavCouseChoseView.h: -------------------------------------------------------------------------------- 1 | // 2 | // XSNavCouseChoseView.h 3 | // XSTeachEDU 4 | // 5 | // Created by L_晨曦 on 2017/9/21. 6 | // Copyright © 2017年 xsteach.com. All rights reserved. 7 | // 8 | 9 | #import 10 | @protocol XSNavChooseScrollViewDelegate; 11 | @interface XSNavCouseChoseView : UIView 12 | 13 | @property(strong ,nonatomic) NSMutableArray * modelAry; 14 | @property(strong ,nonatomic) id delegate; 15 | @property(strong ,nonatomic) UIScrollView * scrollView; 16 | 17 | /* 跳转到选择的按钮 */ 18 | @property (nonatomic, assign) NSInteger currentBtnIndex; 19 | 20 | -(void)selectedItem:(UIButton *)sender; 21 | 22 | @end 23 | 24 | 25 | @protocol XSNavChooseScrollViewDelegate 26 | 27 | -(void)XSNavChooseView:(XSNavCouseChoseView *)chooseView clickItem:( id)itemModel withIndex:(NSInteger )index; 28 | 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /PageController/XSRecommendCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // XSRecommendCell.h 3 | // XSTeachEDU 4 | // 5 | // Created by L_晨曦 on 2017/9/22. 6 | // Copyright © 2017年 xsteach.com. All rights reserved. 7 | // 8 | 9 | #import 10 | @interface XSRecommendCell : XSBaseTableViewCell 11 | 12 | @property (nonatomic, assign) NSInteger count; 13 | 14 | @property (nonatomic, copy) void (^courseItemDiclickBlock)(); 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /PageController/XSRecommendCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // XSRecommendCell.m 3 | // XSTeachEDU 4 | // 5 | // Created by L_晨曦 on 2017/9/22. 6 | // Copyright © 2017年 xsteach.com. All rights reserved. 7 | // 8 | 9 | #import "XSRecommendCell.h" 10 | #import "XSCourseCollectionViewCell.h" 11 | 12 | static CGFloat const courseItemHs = 278/2 ; 13 | static NSString *const reuseIdentifier = @"reuseIdentifier"; 14 | 15 | @interface XSRecommendCell () 16 | 17 | @property (nonatomic, strong) UICollectionView *collectionView; 18 | @property (nonatomic, strong) UICollectionViewFlowLayout *flowLayout; 19 | @end 20 | 21 | @implementation XSRecommendCell 22 | 23 | 24 | - (void)addOwnViews{ 25 | 26 | [self.contentView addSubview:self.collectionView]; 27 | 28 | } 29 | 30 | - (void)addConstraints{ 31 | [self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) { 32 | make.edges.equalTo(self.contentView); 33 | }]; 34 | 35 | } 36 | 37 | - (void)setCount:(NSInteger)count { 38 | _count = count; 39 | [_collectionView reloadData]; 40 | 41 | } 42 | 43 | #pragma mark - collectionView datasource 44 | 45 | - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{ 46 | return 1; 47 | } 48 | 49 | 50 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ 51 | 52 | return _count; 53 | } 54 | 55 | 56 | -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ 57 | XSCourseCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath]; 58 | 59 | return cell; 60 | } 61 | 62 | 63 | #pragma mark - collectionView delegate 64 | 65 | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{ 66 | 67 | !self.courseItemDiclickBlock ? : self.courseItemDiclickBlock(); 68 | } 69 | 70 | - (void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath { 71 | UICollectionViewCell* cell = [collectionView cellForItemAtIndexPath:indexPath]; // 背景色 72 | cell.contentView.backgroundColor = [UIColor colorWithHex:0xf8f8fa]; 73 | 74 | } 75 | 76 | - (void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath { 77 | UICollectionViewCell* cell = [collectionView cellForItemAtIndexPath:indexPath]; 78 | cell.contentView.backgroundColor = nil; 79 | } 80 | 81 | 82 | 83 | #pragma mark - lazy 84 | // 设置collectionView 85 | - (UICollectionView *)collectionView { 86 | if (_collectionView == nil) { 87 | _collectionView = [[UICollectionView alloc]initWithFrame:self.bounds collectionViewLayout:self.flowLayout]; 88 | [_collectionView registerClass:[XSCourseCollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier]; 89 | 90 | _collectionView.delegate = self; 91 | _collectionView.dataSource = self; 92 | _collectionView.backgroundColor = [UIColor whiteColor]; 93 | _collectionView.scrollEnabled = NO; 94 | 95 | } 96 | return _collectionView; 97 | } 98 | 99 | - (UICollectionViewFlowLayout *)flowLayout { 100 | if (_flowLayout == nil) { 101 | _flowLayout = [[UICollectionViewFlowLayout alloc] init]; 102 | CGFloat cellW = ([UIScreen mainScreen].bounds.size.width - 45 )/2 ; 103 | _flowLayout.itemSize = CGSizeMake(cellW , courseItemHs); 104 | _flowLayout.sectionInset = UIEdgeInsetsMake(15, 15, 15, 15); 105 | _flowLayout.minimumLineSpacing = 15; 106 | _flowLayout.minimumInteritemSpacing = 0; 107 | } 108 | return _flowLayout; 109 | } 110 | 111 | @end 112 | -------------------------------------------------------------------------------- /PageController/XSRecommendVC.h: -------------------------------------------------------------------------------- 1 | // 2 | // XSRecommendVC.h 3 | // XSTeachEDU 4 | // 5 | // Created by L_晨曦 on 2017/9/22. 6 | // Copyright © 2017年 xsteach.com. All rights reserved. 7 | // 8 | 9 | #import 10 | @interface XSRecommendVC : UIViewController 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /PageController/XSTabbarMainVC.h: -------------------------------------------------------------------------------- 1 | // 2 | // XSTabbarMainVC.h 3 | // XSTeachEDU 4 | // 5 | // Created by xs003 on 14/12/3. 6 | // Copyright (c) 2014年 xsteach.com. All rights reserved. 7 | // 8 | 9 | #import 10 | @interface XSTabbarMainVC : UITabBarController 11 | 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PageController/XSTabbarMainVC.m: -------------------------------------------------------------------------------- 1 | // 2 | // XSTabbarMainVC.m 3 | // XSTeachEDU 4 | // 5 | // Copyright (c) 2017年 xsteach.com. All rights reserved. 6 | // 7 | 8 | #import "XSTabbarMainVC.h" 9 | #import "XSHomePageVC.h" 10 | #import "XSMyTabar.h" 11 | 12 | 13 | @interface XSTabbarMainVC () 14 | { 15 | XSHomePageVC *_homePageVC; 16 | NSInteger currentIndex; 17 | } 18 | @property (nonatomic, strong) UITabBarItem *tempBtn; 19 | @property (nonatomic, assign) NSInteger index; 20 | @end 21 | 22 | @implementation XSTabbarMainVC 23 | 24 | 25 | 26 | - (void)viewDidLoad { 27 | [super viewDidLoad]; 28 | XSMyTabar *myTabBar = [[XSMyTabar alloc] init]; 29 | [self setValue:myTabBar forKey:@"tabBar"]; 30 | 31 | self.tabBar.backgroundColor = [UIColor whiteColor]; 32 | self.tabBar.backgroundImage = [UIImage new]; 33 | self.tabBar.shadowImage = [UIImage new]; 34 | self.tabBar.translucent = NO; 35 | 36 | _homePageVC = [[XSHomePageVC alloc] init]; 37 | _homePageVC.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"首页" 38 | image:[UIImage imageNamed:@"tabbar_homePage"] 39 | selectedImage:[[UIImage imageNamed:@"tabbar_homePage_highlighted"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]]; 40 | _homePageVC.tabBarItem.titlePositionAdjustment = UIOffsetMake(0, -2); 41 | 42 | UINavigationController *courseNav = [[UINavigationController alloc] initWithRootViewController:_homePageVC]; 43 | 44 | 45 | UIViewController *myCourseVC = [[UIViewController alloc] init]; 46 | 47 | myCourseVC.tabBarItem = [[UITabBarItem alloc]initWithTitle:@"课程" 48 | image:[UIImage imageNamed:@"tabbar_myCourse"] 49 | selectedImage:[[UIImage imageNamed:@"tabbar_myCourse_highlighted"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]]; 50 | 51 | UINavigationController *chatNav = [[UINavigationController alloc] initWithRootViewController:myCourseVC ]; 52 | 53 | 54 | 55 | UIViewController *bbsMainVC = [[UIViewController alloc] init]; 56 | bbsMainVC.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"版块" 57 | image:[UIImage imageNamed:@"tabbar_BBS"] 58 | selectedImage:[[UIImage imageNamed:@"tabbar_BBS_highlighted"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]]; 59 | bbsMainVC.tabBarItem.titlePositionAdjustment = UIOffsetMake(0, -2); 60 | 61 | UINavigationController *bbsNav = [[UINavigationController alloc] initWithRootViewController:bbsMainVC ]; 62 | bbsNav.delegate = self; 63 | 64 | 65 | UIViewController *meMainVC = [[UIViewController alloc] init]; 66 | meMainVC.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"我的" 67 | image:[UIImage imageNamed:@"tabbar_me"] 68 | selectedImage:[[UIImage imageNamed:@"tabbar_me_highlighted"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]]; 69 | meMainVC.tabBarItem.titlePositionAdjustment = UIOffsetMake(0, -2); 70 | 71 | UINavigationController *meNav = [[UINavigationController alloc] initWithRootViewController:meMainVC ]; 72 | meNav.delegate = self; 73 | NSArray *items = @[courseNav, chatNav, bbsNav, meNav]; 74 | [self setViewControllers:items]; 75 | 76 | 77 | } 78 | 79 | 80 | - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController{ 81 | 82 | return YES; 83 | } 84 | 85 | 86 | 87 | 88 | #pragma mark - 私有方法 89 | 90 | - (void)dropShadowWithOffset:(CGSize)offset 91 | radius:(CGFloat)radius 92 | color:(UIColor *)color 93 | opacity:(CGFloat)opacity { 94 | 95 | CGMutablePathRef path = CGPathCreateMutable(); 96 | CGPathAddRect(path, NULL, self.tabBar.bounds); 97 | self.tabBar.layer.shadowPath = path; 98 | CGPathCloseSubpath(path); 99 | CGPathRelease(path); 100 | 101 | self.tabBar.layer.shadowColor = color.CGColor; 102 | self.tabBar.layer.shadowOffset = offset; 103 | self.tabBar.layer.shadowRadius = radius; 104 | self.tabBar.layer.shadowOpacity = opacity; 105 | self.tabBar.clipsToBounds = NO; 106 | } 107 | 108 | 109 | 110 | - (UITabBarItem *)tempBtn{ 111 | 112 | if (_tempBtn == nil) { 113 | _tempBtn = [[UITabBarItem alloc]init]; 114 | } 115 | 116 | return _tempBtn; 117 | } 118 | 119 | 120 | @end 121 | -------------------------------------------------------------------------------- /PageController/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // PageController 4 | // 5 | // Created by L_晨曦 on 2017/10/17. 6 | // Copyright © 2017年 L_晨曦. 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 | -------------------------------------------------------------------------------- /PageControllerTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /PageControllerTests/PageControllerTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // PageControllerTests.m 3 | // PageControllerTests 4 | // 5 | // Created by L_晨曦 on 2017/10/17. 6 | // Copyright © 2017年 L_晨曦. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PageControllerTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation PageControllerTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /PageControllerUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /PageControllerUITests/PageControllerUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // PageControllerUITests.m 3 | // PageControllerUITests 4 | // 5 | // Created by L_晨曦 on 2017/10/17. 6 | // Copyright © 2017年 L_晨曦. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PageControllerUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation PageControllerUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pageController 2 | 一个类似腾讯新闻的分页控制器,支持标题的增删,标题联动等。首页是嵌套collectionview,分类选择控制器是http://blog.csdn.net/u013282507/article/details/54374952 在这位大哥的基础上修改的,支持拖动排序。 3 | 简书地址:http://www.jianshu.com/p/b982c38047e1 4 | 5 | ![image](https://github.com/396987177/pageController/raw/master/image/demo4.gif) 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /image/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/image/.DS_Store -------------------------------------------------------------------------------- /image/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/image/demo.gif -------------------------------------------------------------------------------- /image/demo2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/image/demo2.jpg -------------------------------------------------------------------------------- /image/demo3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/image/demo3.gif -------------------------------------------------------------------------------- /image/demo4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/396987177/pageController/66ffd95f5c8d5882a4857ca110f177ae066d25bc/image/demo4.gif --------------------------------------------------------------------------------