├── CDDTitleRolling ├── CDDTitleRolling │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── topTitle.imageset │ │ │ ├── topTitle@2x.png │ │ │ └── Contents.json │ │ ├── commune_ask.imageset │ │ │ ├── commune_ask@2x.png │ │ │ ├── commune_ask@3x.png │ │ │ └── Contents.json │ │ ├── shouye_img_toutiao.imageset │ │ │ ├── shouye_img_toutiao.png │ │ │ ├── shouye_img_toutiao@2x.png │ │ │ └── Contents.json │ │ ├── jshop_sign_layer_not.imageset │ │ │ ├── jshop_sign_layer_not@2x.png │ │ │ ├── jshop_sign_layer_not@3x.png │ │ │ └── Contents.json │ │ ├── jshop_sign_layer_ok.imageset │ │ │ ├── jshop_sign_layer_ok@2x.png │ │ │ ├── jshop_sign_layer_ok@3x.png │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── ViewController.h │ ├── CDDTitleRolling.xcdatamodeld │ │ ├── .xccurrentversion │ │ └── CDDTitleRolling.xcdatamodel │ │ │ └── contents │ ├── AppDelegate.h │ ├── main.m │ ├── CDDTitleRolling │ │ ├── UIView+DCRolling.h │ │ ├── DCTitleRolling.h │ │ ├── UIView+DCRolling.m │ │ └── DCTitleRolling.m │ ├── Info.plist │ ├── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard │ ├── AppDelegate.m │ └── ViewController.m └── CDDTitleRolling.xcodeproj │ ├── project.xcworkspace │ └── contents.xcworkspacedata │ └── project.pbxproj ├── README.md ├── .gitignore └── LICENSE /CDDTitleRolling/CDDTitleRolling/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CDDTitleRolling 2 | 电商轮播标题广告(仿京东、淘宝) 3 | 4 | 5 | 如果这个Demo让你有所收获,请Star and Fork。 6 | 7 | 注:如果遇到问题还请Issues,我会尽快回复。 8 | 9 | 10 | [简书传送门](http://www.jianshu.com/p/b5ab7b374fa0)
11 | -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/Assets.xcassets/topTitle.imageset/topTitle@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RocketsChen/CDDTitleRolling/HEAD/CDDTitleRolling/CDDTitleRolling/Assets.xcassets/topTitle.imageset/topTitle@2x.png -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/Assets.xcassets/commune_ask.imageset/commune_ask@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RocketsChen/CDDTitleRolling/HEAD/CDDTitleRolling/CDDTitleRolling/Assets.xcassets/commune_ask.imageset/commune_ask@2x.png -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/Assets.xcassets/commune_ask.imageset/commune_ask@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RocketsChen/CDDTitleRolling/HEAD/CDDTitleRolling/CDDTitleRolling/Assets.xcassets/commune_ask.imageset/commune_ask@3x.png -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/Assets.xcassets/shouye_img_toutiao.imageset/shouye_img_toutiao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RocketsChen/CDDTitleRolling/HEAD/CDDTitleRolling/CDDTitleRolling/Assets.xcassets/shouye_img_toutiao.imageset/shouye_img_toutiao.png -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/Assets.xcassets/shouye_img_toutiao.imageset/shouye_img_toutiao@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RocketsChen/CDDTitleRolling/HEAD/CDDTitleRolling/CDDTitleRolling/Assets.xcassets/shouye_img_toutiao.imageset/shouye_img_toutiao@2x.png -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/Assets.xcassets/jshop_sign_layer_not.imageset/jshop_sign_layer_not@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RocketsChen/CDDTitleRolling/HEAD/CDDTitleRolling/CDDTitleRolling/Assets.xcassets/jshop_sign_layer_not.imageset/jshop_sign_layer_not@2x.png -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/Assets.xcassets/jshop_sign_layer_not.imageset/jshop_sign_layer_not@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RocketsChen/CDDTitleRolling/HEAD/CDDTitleRolling/CDDTitleRolling/Assets.xcassets/jshop_sign_layer_not.imageset/jshop_sign_layer_not@3x.png -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/Assets.xcassets/jshop_sign_layer_ok.imageset/jshop_sign_layer_ok@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RocketsChen/CDDTitleRolling/HEAD/CDDTitleRolling/CDDTitleRolling/Assets.xcassets/jshop_sign_layer_ok.imageset/jshop_sign_layer_ok@2x.png -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/Assets.xcassets/jshop_sign_layer_ok.imageset/jshop_sign_layer_ok@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RocketsChen/CDDTitleRolling/HEAD/CDDTitleRolling/CDDTitleRolling/Assets.xcassets/jshop_sign_layer_ok.imageset/jshop_sign_layer_ok@3x.png -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // CDDTitleRolling 4 | // 5 | // Created by dashen on 2017/11/17. 6 | // Copyright © 2017年 RocketsChen. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/CDDTitleRolling.xcdatamodeld/.xccurrentversion: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | _XCCurrentVersionName 6 | CDDTitleRolling.xcdatamodel 7 | 8 | 9 | -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/CDDTitleRolling.xcdatamodeld/CDDTitleRolling.xcdatamodel/contents: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // CDDTitleRolling 4 | // 5 | // Created by dashen on 2017/11/17. 6 | // Copyright © 2017年 RocketsChen. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface AppDelegate : UIResponder 13 | 14 | @property (strong, nonatomic) UIWindow *window; 15 | 16 | 17 | @end 18 | 19 | -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // CDDTitleRolling 4 | // 5 | // Created by dashen on 2017/11/17. 6 | // Copyright © 2017年 RocketsChen. 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 | -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/Assets.xcassets/topTitle.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "topTitle@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/Assets.xcassets/commune_ask.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "commune_ask@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "commune_ask@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/Assets.xcassets/shouye_img_toutiao.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "shouye_img_toutiao.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "shouye_img_toutiao@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/Assets.xcassets/jshop_sign_layer_not.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "jshop_sign_layer_not@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "jshop_sign_layer_not@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/Assets.xcassets/jshop_sign_layer_ok.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "jshop_sign_layer_ok@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "jshop_sign_layer_ok@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/CDDTitleRolling/UIView+DCRolling.h: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | 4 | @interface UIView (DCRolling) 5 | 6 | 7 | @property (nonatomic , assign) CGFloat dc_width; 8 | @property (nonatomic , assign) CGFloat dc_height; 9 | @property (nonatomic , assign) CGSize dc_size; 10 | @property (nonatomic , assign) CGFloat dc_x; 11 | @property (nonatomic , assign) CGFloat dc_y; 12 | @property (nonatomic , assign) CGPoint dc_origin; 13 | @property (nonatomic , assign) CGFloat dc_centerX; 14 | @property (nonatomic , assign) CGFloat dc_centerY; 15 | @property (nonatomic , assign) CGFloat dc_right; 16 | @property (nonatomic , assign) CGFloat dc_bottom; 17 | 18 | - (BOOL)intersectWithView:(UIView *)view; 19 | 20 | + (instancetype)dc_viewFromXib; 21 | - (BOOL)isShowingOnKeyWindow; 22 | 23 | - (CGSize)labelAutoCalculateRectWith:(NSString *)text FontSize:(CGFloat)fontSize MaxSize:(CGSize)maxSize; 24 | 25 | 26 | - (id)dc_chageControlCircularWith:(id)anyControl AndSetCornerRadius:(NSInteger)radius SetBorderWidth:(NSInteger)width SetBorderColor:(UIColor *)borderColor canMasksToBounds:(BOOL)can; 27 | @end 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | # CocoaPods 32 | # 33 | # We recommend against adding the Pods directory to your .gitignore. However 34 | # you should judge for yourself, the pros and cons are mentioned at: 35 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 36 | # 37 | # Pods/ 38 | 39 | # Carthage 40 | # 41 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 42 | # Carthage/Checkouts 43 | 44 | Carthage/Build 45 | 46 | # fastlane 47 | # 48 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 49 | # screenshots whenever they are needed. 50 | # For more information about the recommended setup visit: 51 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 52 | 53 | fastlane/report.xml 54 | fastlane/Preview.html 55 | fastlane/screenshots 56 | fastlane/test_output 57 | 58 | # Code Injection 59 | # 60 | # After new code Injection tools there's a generated folder /iOSInjectionProject 61 | # https://github.com/johnno1962/injectionforxcode 62 | 63 | iOSInjectionProject/ 64 | -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/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 | -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/CDDTitleRolling/DCTitleRolling.h: -------------------------------------------------------------------------------- 1 | // 2 | // DCTitleRolling.h 3 | // CDDTitleRolling 4 | // 5 | // Created by dashen on 2017/11/17. 6 | //Copyright © 2017年 com.RocketsChen. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | // 每条几组数据 12 | typedef enum : NSUInteger { 13 | CDDRollingOneGroup , // 默认一种(类似京东、国美) 14 | CDDRollingTwoGroup, // 两种(类似淘宝) 15 | } CDDRollingGroupStyle; 16 | 17 | 18 | @protocol CDDRollingDelegate 19 | 20 | - (void)dc_RollingViewSelectWithActionAtIndex:(NSInteger)index; 21 | 22 | @end 23 | 24 | 25 | @interface DCTitleRolling : UIView 26 | 27 | 28 | /** 点击代理 */ 29 | @property (nonatomic , assign) iddelegate; 30 | /** 更多点击回调 */ 31 | @property (nonatomic, copy) dispatch_block_t moreClickBlock; 32 | 33 | /* 图片 */ 34 | @property (strong , nonatomic)UIImageView *leftImageView; 35 | /* 按钮 */ 36 | @property (strong , nonatomic)UIButton *rightButton; 37 | 38 | /** 39 | 数据 40 | 41 | *leftImage 左边图片 42 | *rolTitles 标题数组 43 | *rolTags tag数组 44 | *rightImages 右边图片数组 45 | *rightbuttonTitle 右边按钮(支持点击回调) 46 | *interval 定时器滚动间隔 47 | *rollingTime 滚动一次时间的长短 48 | *titleFont 标题尺寸 49 | *titleColor 标题颜色 50 | *isShowTagBorder 是否展示tag标题边框(默认不) 51 | @param frame 滚动标题的frame 52 | @param titleDataBlock 设置滚动内部的数据 53 | @return 数据展示 54 | */ 55 | - (instancetype)initWithFrame:(CGRect)frame WithTitleData:(void(^)(CDDRollingGroupStyle *rollingGroupStyle, NSString **leftImage,NSArray **rolTitles,NSArray **rolTags,NSArray **rightImages,NSString **rightbuttonTitle,NSInteger *interval,float *rollingTime,NSInteger *titleFont,UIColor **titleColor,BOOL *isShowTagBorder))titleDataBlock; 56 | 57 | /** 58 | 开始滚动 59 | */ 60 | - (void)dc_beginRolling; 61 | 62 | /** 63 | 结束滚动 64 | */ 65 | - (void)dc_endRolling; 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // CDDTitleRolling 4 | // 5 | // Created by dashen on 2017/11/17. 6 | // Copyright © 2017年 RocketsChen. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | // Saves changes in the application's managed object context before the application terminates. 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/CDDTitleRolling/UIView+DCRolling.m: -------------------------------------------------------------------------------- 1 | 2 | #import "UIView+DCRolling.h" 3 | 4 | @implementation UIView (DCRolling) 5 | 6 | - (CGFloat)dc_x 7 | { 8 | return self.frame.origin.x; 9 | } 10 | - (void)setDc_x:(CGFloat)dc_x 11 | { 12 | CGRect dcFrame = self.frame; 13 | dcFrame.origin.x = dc_x; 14 | self.frame = dcFrame; 15 | } 16 | 17 | -(CGFloat)dc_y 18 | { 19 | return self.frame.origin.y; 20 | } 21 | -(void)setDc_y:(CGFloat)dc_y 22 | { 23 | CGRect dcFrame = self.frame; 24 | dcFrame.origin.y = dc_y; 25 | self.frame = dcFrame; 26 | } 27 | 28 | -(CGPoint)dc_origin 29 | { 30 | return self.frame.origin; 31 | } 32 | -(void)setDc_origin:(CGPoint)dc_origin 33 | { 34 | CGRect dcFrame = self.frame; 35 | dcFrame.origin = dc_origin; 36 | self.frame = dcFrame; 37 | } 38 | 39 | -(CGFloat)dc_width 40 | { 41 | return self.frame.size.width; 42 | } 43 | -(void)setDc_width:(CGFloat)dc_width 44 | { 45 | CGRect dcFrame = self.frame; 46 | dcFrame.size.width = dc_width; 47 | self.frame = dcFrame; 48 | } 49 | 50 | -(CGFloat)dc_height 51 | { 52 | return self.frame.size.height; 53 | } 54 | -(void)setDc_height:(CGFloat)dc_height 55 | { 56 | CGRect dcFrame = self.frame; 57 | dcFrame.size.height = dc_height; 58 | self.frame = dcFrame; 59 | } 60 | 61 | -(CGSize)dc_size 62 | { 63 | return self.frame.size; 64 | } 65 | - (void)setDc_size:(CGSize)dc_size 66 | { 67 | CGRect dcFrame = self.frame; 68 | dcFrame.size = dc_size; 69 | self.frame = dcFrame; 70 | } 71 | 72 | -(CGFloat)dc_centerX{ 73 | 74 | return self.center.x; 75 | } 76 | 77 | -(void)setDc_centerX:(CGFloat)dc_centerX{ 78 | 79 | CGPoint dcFrmae = self.center; 80 | dcFrmae.x = dc_centerX; 81 | self.center = dcFrmae; 82 | } 83 | 84 | -(CGFloat)dc_centerY{ 85 | 86 | return self.center.y; 87 | } 88 | 89 | -(void)setDc_centerY:(CGFloat)dc_centerY{ 90 | 91 | CGPoint dcFrame = self.center; 92 | dcFrame.y = dc_centerY; 93 | self.center = dcFrame; 94 | } 95 | 96 | - (CGFloat)dc_right{ 97 | 98 | return CGRectGetMaxX(self.frame); 99 | } 100 | 101 | - (CGFloat)dc_bottom{ 102 | 103 | return CGRectGetMaxY(self.frame); 104 | } 105 | 106 | - (void)setDc_right:(CGFloat)dc_right{ 107 | 108 | self.dc_x = dc_right - self.dc_width; 109 | } 110 | 111 | - (void)setDc_bottom:(CGFloat)dc_bottom{ 112 | 113 | self.dc_y = dc_bottom - self.dc_height; 114 | } 115 | 116 | - (BOOL)intersectWithView:(UIView *)view{ 117 | 118 | UIWindow *window = [UIApplication sharedApplication].keyWindow; 119 | CGRect selfRect = [self convertRect:self.bounds toView:window]; 120 | CGRect viewRect = [view convertRect:view.bounds toView:window]; 121 | return CGRectIntersectsRect(selfRect, viewRect); 122 | } 123 | 124 | - (BOOL)isShowingOnKeyWindow { 125 | // 主窗口 126 | UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow; 127 | 128 | // 以主窗口左上角为坐标原点, 计算self的矩形框 129 | CGRect newFrame = [keyWindow convertRect:self.frame fromView:self.superview]; 130 | CGRect winBounds = keyWindow.bounds; 131 | 132 | // 主窗口的bounds 和 self的矩形框 是否有重叠 133 | BOOL intersects = CGRectIntersectsRect(newFrame, winBounds); 134 | 135 | return !self.isHidden && self.alpha > 0.01 && self.window == keyWindow && intersects; 136 | } 137 | 138 | +(instancetype)dc_viewFromXib 139 | { 140 | return [[NSBundle mainBundle]loadNibNamed:NSStringFromClass(self) owner:nil options:nil].firstObject; 141 | } 142 | 143 | - (CGSize)labelAutoCalculateRectWith:(NSString *)text FontSize:(CGFloat)fontSize MaxSize:(CGSize)maxSize 144 | { 145 | NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc]init]; 146 | paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; 147 | NSDictionary * attributes = @{NSFontAttributeName:[UIFont systemFontOfSize:fontSize], NSParagraphStyleAttributeName:paragraphStyle.copy}; 148 | 149 | CGSize labelSize = [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin |NSStringDrawingUsesFontLeading | NSStringDrawingTruncatesLastVisibleLine attributes:attributes context:nil].size; 150 | 151 | labelSize.height = ceil(labelSize.height); 152 | labelSize.width = ceil(labelSize.width); 153 | return labelSize; 154 | } 155 | 156 | -(id)dc_chageControlCircularWith:(id)anyControl AndSetCornerRadius:(NSInteger)radius SetBorderWidth:(NSInteger)width SetBorderColor:(UIColor *)borderColor canMasksToBounds:(BOOL)can 157 | { 158 | CALayer *icon_layer=[anyControl layer]; 159 | [icon_layer setCornerRadius:radius]; 160 | [icon_layer setBorderWidth:width]; 161 | [icon_layer setBorderColor:[borderColor CGColor]]; 162 | [icon_layer setMasksToBounds:can]; 163 | 164 | return anyControl; 165 | } 166 | 167 | @end 168 | -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // CDDTitleRolling 4 | // 5 | // Created by dashen on 2017/11/17. 6 | // Copyright © 2017年 RocketsChen. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | #import "DCTitleRolling.h" 12 | 13 | @interface ViewController () 14 | 15 | /* 京东头条 */ 16 | @property (strong , nonatomic)DCTitleRolling *jdRollingView; 17 | 18 | /* 国美在线 */ 19 | @property (strong , nonatomic)DCTitleRolling *gmRollingView; 20 | 21 | /* 淘宝 */ 22 | @property (strong , nonatomic)DCTitleRolling *tbRollingView; 23 | 24 | @end 25 | 26 | @implementation ViewController 27 | 28 | 29 | - (void)viewDidLoad { 30 | [super viewDidLoad]; 31 | 32 | self.view.backgroundColor = [UIColor colorWithRed:245/255.0 green:245/255.0 blue:245/255.0 alpha:1.0]; 33 | 34 | [self setUpJDRolling]; 35 | 36 | [self setUpGMRolling]; 37 | 38 | [self setUpTBRolling]; 39 | } 40 | 41 | #pragma mark - JD 42 | - (void)setUpJDRolling { 43 | 44 | _jdRollingView = [[DCTitleRolling alloc] initWithFrame:CGRectMake(15, 100, self.view.frame.size.width - 30, 44) WithTitleData:^(CDDRollingGroupStyle *rollingGroupStyle, NSString *__autoreleasing *leftImage, NSArray *__autoreleasing *rolTitles, NSArray *__autoreleasing *rolTags, NSArray *__autoreleasing *rightImages, NSString *__autoreleasing *rightbuttonTitle, NSInteger *interval, float *rollingTime, NSInteger *titleFont, UIColor *__autoreleasing *titleColor, BOOL *isShowTagBorder) { 45 | 46 | *rollingTime = 0.2; 47 | *rolTags = @[@"HOT",@"HOT",@"",@"HOT"]; 48 | *rolTitles = @[@"小丑女的拍照秘籍竟然是?",@"2000热门手机推荐",@"好奇么?点进去哈",@"这套家具比房子还贵"]; 49 | *leftImage = @"shouye_img_toutiao"; 50 | *rightbuttonTitle = @"更多"; 51 | *interval = 3.0; 52 | *titleFont = 14; 53 | *titleColor = [UIColor darkGrayColor]; 54 | }]; 55 | 56 | _jdRollingView.moreClickBlock = ^{ 57 | NSLog(@"jd----more"); 58 | }; 59 | 60 | [_jdRollingView dc_beginRolling]; 61 | _jdRollingView.layer.cornerRadius = 15; 62 | [_jdRollingView.layer masksToBounds]; 63 | _jdRollingView.backgroundColor = [UIColor whiteColor]; 64 | [self.view addSubview:_jdRollingView]; 65 | } 66 | 67 | #pragma mark - GM 68 | - (void)setUpGMRolling 69 | { 70 | _gmRollingView = [[DCTitleRolling alloc] initWithFrame:CGRectMake(0, 200, self.view.frame.size.width, 44) WithTitleData:^(CDDRollingGroupStyle *rollingGroupStyle, NSString *__autoreleasing *leftImage, NSArray *__autoreleasing *rolTitles, NSArray *__autoreleasing *rolTags, NSArray *__autoreleasing *rightImages, NSString *__autoreleasing *rightbuttonTitle, NSInteger *interval, float *rollingTime, NSInteger *titleFont, UIColor *__autoreleasing *titleColor, BOOL *isShowTagBorder) { 71 | 72 | *rolTags = @[@"object",@"github",@"java/php"]; 73 | *rolTitles = @[@"DCTitleRolling 欢迎留言",@"喜欢的话可以给我点个Star✨✨",@"一门面向对象编程语言"]; 74 | *leftImage = @"shouye_img_toutiao"; 75 | *interval = 3.0; 76 | *titleFont = 14; 77 | *titleColor = [UIColor orangeColor]; 78 | *isShowTagBorder = YES; 79 | }]; 80 | _gmRollingView.delegate = self; 81 | [_gmRollingView dc_beginRolling]; 82 | _gmRollingView.backgroundColor = [UIColor whiteColor]; 83 | [self.view addSubview:_gmRollingView]; 84 | 85 | 86 | } 87 | 88 | #pragma mark - TB 89 | - (void)setUpTBRolling 90 | { 91 | _tbRollingView = [[DCTitleRolling alloc] initWithFrame:CGRectMake(0, 300, self.view.frame.size.width, 60) WithTitleData:^(CDDRollingGroupStyle *rollingGroupStyle, NSString *__autoreleasing *leftImage, NSArray *__autoreleasing *rolTitles, NSArray *__autoreleasing *rolTags, NSArray *__autoreleasing *rightImages, NSString *__autoreleasing *rightbuttonTitle, NSInteger *interval, float *rollingTime, NSInteger *titleFont, UIColor *__autoreleasing *titleColor, BOOL *isShowTagBorder) { 92 | 93 | *rollingTime = 0.2; 94 | *rightImages = @[@"jshop_sign_layer_not",@"jshop_sign_layer_ok",@"jshop_sign_layer_not"]; 95 | *rollingGroupStyle = CDDRollingTwoGroup; 96 | *rolTags = @[@[@"热热",@"爆爆",@"红红"],@[@"冷知识",@"小常识",@"最新"]]; 97 | *rolTitles = @[@[@"喜欢的给个Star",@"苹果X爆冷,黄牛都哭了",@"还在等什么,赶紧抢购"],@[@"有问题欢迎留言~~",@"IOS 11 升级bug出现",@"科技风云惊奇出现等等的等"]]; 98 | *leftImage = @"topTitle"; 99 | *interval = 4.0; 100 | *titleFont = 14; 101 | *titleColor = [UIColor blueColor]; 102 | *isShowTagBorder = YES; //是否展示tag边框 103 | 104 | }]; 105 | _tbRollingView.delegate = self; 106 | [_tbRollingView dc_beginRolling]; 107 | _tbRollingView.backgroundColor = [UIColor whiteColor]; 108 | [self.view addSubview:_tbRollingView]; 109 | } 110 | 111 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 112 | { 113 | [_jdRollingView dc_endRolling]; 114 | 115 | // [_gmRollingView dc_endRolling]; 116 | 117 | // [_tbRollingView dc_endRolling]; 118 | } 119 | 120 | 121 | 122 | #pragma mark - 123 | - (void)dc_RollingViewSelectWithActionAtIndex:(NSInteger)index 124 | { 125 | NSLog(@"点击了第%zd头条滚动条",index); 126 | } 127 | 128 | @end 129 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 923FB3FF1FC2AD970096DBC3 /* UIView+DCRolling.m in Sources */ = {isa = PBXBuildFile; fileRef = 923FB3FD1FC2AD960096DBC3 /* UIView+DCRolling.m */; }; 11 | 92FAD5661FBE811C0031306A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 92FAD5651FBE811C0031306A /* AppDelegate.m */; }; 12 | 92FAD5691FBE811D0031306A /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 92FAD5681FBE811D0031306A /* ViewController.m */; }; 13 | 92FAD56C1FBE811D0031306A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 92FAD56A1FBE811D0031306A /* Main.storyboard */; }; 14 | 92FAD56F1FBE811D0031306A /* CDDTitleRolling.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 92FAD56D1FBE811D0031306A /* CDDTitleRolling.xcdatamodeld */; }; 15 | 92FAD5711FBE811D0031306A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 92FAD5701FBE811D0031306A /* Assets.xcassets */; }; 16 | 92FAD5741FBE811D0031306A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 92FAD5721FBE811D0031306A /* LaunchScreen.storyboard */; }; 17 | 92FAD5771FBE811D0031306A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 92FAD5761FBE811D0031306A /* main.m */; }; 18 | 92FAD57F1FBE817A0031306A /* DCTitleRolling.m in Sources */ = {isa = PBXBuildFile; fileRef = 92FAD57E1FBE817A0031306A /* DCTitleRolling.m */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXFileReference section */ 22 | 923FB3FD1FC2AD960096DBC3 /* UIView+DCRolling.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+DCRolling.m"; sourceTree = ""; }; 23 | 923FB3FE1FC2AD970096DBC3 /* UIView+DCRolling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+DCRolling.h"; sourceTree = ""; }; 24 | 92FAD5611FBE811C0031306A /* CDDTitleRolling.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CDDTitleRolling.app; sourceTree = BUILT_PRODUCTS_DIR; }; 25 | 92FAD5641FBE811C0031306A /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 26 | 92FAD5651FBE811C0031306A /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 27 | 92FAD5671FBE811D0031306A /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 28 | 92FAD5681FBE811D0031306A /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 29 | 92FAD56B1FBE811D0031306A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 30 | 92FAD56E1FBE811D0031306A /* CDDTitleRolling.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = CDDTitleRolling.xcdatamodel; sourceTree = ""; }; 31 | 92FAD5701FBE811D0031306A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 32 | 92FAD5731FBE811D0031306A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 33 | 92FAD5751FBE811D0031306A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 34 | 92FAD5761FBE811D0031306A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 35 | 92FAD57D1FBE817A0031306A /* DCTitleRolling.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DCTitleRolling.h; sourceTree = ""; }; 36 | 92FAD57E1FBE817A0031306A /* DCTitleRolling.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DCTitleRolling.m; sourceTree = ""; }; 37 | /* End PBXFileReference section */ 38 | 39 | /* Begin PBXFrameworksBuildPhase section */ 40 | 92FAD55E1FBE811C0031306A /* Frameworks */ = { 41 | isa = PBXFrameworksBuildPhase; 42 | buildActionMask = 2147483647; 43 | files = ( 44 | ); 45 | runOnlyForDeploymentPostprocessing = 0; 46 | }; 47 | /* End PBXFrameworksBuildPhase section */ 48 | 49 | /* Begin PBXGroup section */ 50 | 92FAD5581FBE811C0031306A = { 51 | isa = PBXGroup; 52 | children = ( 53 | 92FAD5631FBE811C0031306A /* CDDTitleRolling */, 54 | 92FAD5621FBE811C0031306A /* Products */, 55 | ); 56 | sourceTree = ""; 57 | }; 58 | 92FAD5621FBE811C0031306A /* Products */ = { 59 | isa = PBXGroup; 60 | children = ( 61 | 92FAD5611FBE811C0031306A /* CDDTitleRolling.app */, 62 | ); 63 | name = Products; 64 | sourceTree = ""; 65 | }; 66 | 92FAD5631FBE811C0031306A /* CDDTitleRolling */ = { 67 | isa = PBXGroup; 68 | children = ( 69 | 92FAD5641FBE811C0031306A /* AppDelegate.h */, 70 | 92FAD5651FBE811C0031306A /* AppDelegate.m */, 71 | 92FAD5671FBE811D0031306A /* ViewController.h */, 72 | 92FAD5681FBE811D0031306A /* ViewController.m */, 73 | 92FAD5801FBEB2670031306A /* CDDTitleRolling */, 74 | 92FAD56A1FBE811D0031306A /* Main.storyboard */, 75 | 92FAD5701FBE811D0031306A /* Assets.xcassets */, 76 | 92FAD5721FBE811D0031306A /* LaunchScreen.storyboard */, 77 | 92FAD5751FBE811D0031306A /* Info.plist */, 78 | 92FAD5761FBE811D0031306A /* main.m */, 79 | 92FAD56D1FBE811D0031306A /* CDDTitleRolling.xcdatamodeld */, 80 | ); 81 | path = CDDTitleRolling; 82 | sourceTree = ""; 83 | }; 84 | 92FAD5801FBEB2670031306A /* CDDTitleRolling */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | 92FAD57D1FBE817A0031306A /* DCTitleRolling.h */, 88 | 92FAD57E1FBE817A0031306A /* DCTitleRolling.m */, 89 | 923FB3FE1FC2AD970096DBC3 /* UIView+DCRolling.h */, 90 | 923FB3FD1FC2AD960096DBC3 /* UIView+DCRolling.m */, 91 | ); 92 | path = CDDTitleRolling; 93 | sourceTree = ""; 94 | }; 95 | /* End PBXGroup section */ 96 | 97 | /* Begin PBXNativeTarget section */ 98 | 92FAD5601FBE811C0031306A /* CDDTitleRolling */ = { 99 | isa = PBXNativeTarget; 100 | buildConfigurationList = 92FAD57A1FBE811D0031306A /* Build configuration list for PBXNativeTarget "CDDTitleRolling" */; 101 | buildPhases = ( 102 | 92FAD55D1FBE811C0031306A /* Sources */, 103 | 92FAD55E1FBE811C0031306A /* Frameworks */, 104 | 92FAD55F1FBE811C0031306A /* Resources */, 105 | ); 106 | buildRules = ( 107 | ); 108 | dependencies = ( 109 | ); 110 | name = CDDTitleRolling; 111 | productName = CDDTitleRolling; 112 | productReference = 92FAD5611FBE811C0031306A /* CDDTitleRolling.app */; 113 | productType = "com.apple.product-type.application"; 114 | }; 115 | /* End PBXNativeTarget section */ 116 | 117 | /* Begin PBXProject section */ 118 | 92FAD5591FBE811C0031306A /* Project object */ = { 119 | isa = PBXProject; 120 | attributes = { 121 | CLASSPREFIX = DC; 122 | LastUpgradeCheck = 0900; 123 | ORGANIZATIONNAME = com.RocketsChen; 124 | TargetAttributes = { 125 | 92FAD5601FBE811C0031306A = { 126 | CreatedOnToolsVersion = 9.0.1; 127 | ProvisioningStyle = Automatic; 128 | }; 129 | }; 130 | }; 131 | buildConfigurationList = 92FAD55C1FBE811C0031306A /* Build configuration list for PBXProject "CDDTitleRolling" */; 132 | compatibilityVersion = "Xcode 8.0"; 133 | developmentRegion = en; 134 | hasScannedForEncodings = 0; 135 | knownRegions = ( 136 | en, 137 | Base, 138 | ); 139 | mainGroup = 92FAD5581FBE811C0031306A; 140 | productRefGroup = 92FAD5621FBE811C0031306A /* Products */; 141 | projectDirPath = ""; 142 | projectRoot = ""; 143 | targets = ( 144 | 92FAD5601FBE811C0031306A /* CDDTitleRolling */, 145 | ); 146 | }; 147 | /* End PBXProject section */ 148 | 149 | /* Begin PBXResourcesBuildPhase section */ 150 | 92FAD55F1FBE811C0031306A /* Resources */ = { 151 | isa = PBXResourcesBuildPhase; 152 | buildActionMask = 2147483647; 153 | files = ( 154 | 92FAD5741FBE811D0031306A /* LaunchScreen.storyboard in Resources */, 155 | 92FAD5711FBE811D0031306A /* Assets.xcassets in Resources */, 156 | 92FAD56C1FBE811D0031306A /* Main.storyboard in Resources */, 157 | ); 158 | runOnlyForDeploymentPostprocessing = 0; 159 | }; 160 | /* End PBXResourcesBuildPhase section */ 161 | 162 | /* Begin PBXSourcesBuildPhase section */ 163 | 92FAD55D1FBE811C0031306A /* Sources */ = { 164 | isa = PBXSourcesBuildPhase; 165 | buildActionMask = 2147483647; 166 | files = ( 167 | 92FAD5691FBE811D0031306A /* ViewController.m in Sources */, 168 | 923FB3FF1FC2AD970096DBC3 /* UIView+DCRolling.m in Sources */, 169 | 92FAD5661FBE811C0031306A /* AppDelegate.m in Sources */, 170 | 92FAD57F1FBE817A0031306A /* DCTitleRolling.m in Sources */, 171 | 92FAD5771FBE811D0031306A /* main.m in Sources */, 172 | 92FAD56F1FBE811D0031306A /* CDDTitleRolling.xcdatamodeld in Sources */, 173 | ); 174 | runOnlyForDeploymentPostprocessing = 0; 175 | }; 176 | /* End PBXSourcesBuildPhase section */ 177 | 178 | /* Begin PBXVariantGroup section */ 179 | 92FAD56A1FBE811D0031306A /* Main.storyboard */ = { 180 | isa = PBXVariantGroup; 181 | children = ( 182 | 92FAD56B1FBE811D0031306A /* Base */, 183 | ); 184 | name = Main.storyboard; 185 | sourceTree = ""; 186 | }; 187 | 92FAD5721FBE811D0031306A /* LaunchScreen.storyboard */ = { 188 | isa = PBXVariantGroup; 189 | children = ( 190 | 92FAD5731FBE811D0031306A /* Base */, 191 | ); 192 | name = LaunchScreen.storyboard; 193 | sourceTree = ""; 194 | }; 195 | /* End PBXVariantGroup section */ 196 | 197 | /* Begin XCBuildConfiguration section */ 198 | 92FAD5781FBE811D0031306A /* Debug */ = { 199 | isa = XCBuildConfiguration; 200 | buildSettings = { 201 | ALWAYS_SEARCH_USER_PATHS = NO; 202 | CLANG_ANALYZER_NONNULL = YES; 203 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 204 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 205 | CLANG_CXX_LIBRARY = "libc++"; 206 | CLANG_ENABLE_MODULES = YES; 207 | CLANG_ENABLE_OBJC_ARC = YES; 208 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 209 | CLANG_WARN_BOOL_CONVERSION = YES; 210 | CLANG_WARN_COMMA = YES; 211 | CLANG_WARN_CONSTANT_CONVERSION = YES; 212 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 213 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 214 | CLANG_WARN_EMPTY_BODY = YES; 215 | CLANG_WARN_ENUM_CONVERSION = YES; 216 | CLANG_WARN_INFINITE_RECURSION = YES; 217 | CLANG_WARN_INT_CONVERSION = YES; 218 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 219 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 220 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 221 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 222 | CLANG_WARN_STRICT_PROTOTYPES = YES; 223 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 224 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 225 | CLANG_WARN_UNREACHABLE_CODE = YES; 226 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 227 | CODE_SIGN_IDENTITY = "iPhone Developer"; 228 | COPY_PHASE_STRIP = NO; 229 | DEBUG_INFORMATION_FORMAT = dwarf; 230 | ENABLE_STRICT_OBJC_MSGSEND = YES; 231 | ENABLE_TESTABILITY = YES; 232 | GCC_C_LANGUAGE_STANDARD = gnu11; 233 | GCC_DYNAMIC_NO_PIC = NO; 234 | GCC_NO_COMMON_BLOCKS = YES; 235 | GCC_OPTIMIZATION_LEVEL = 0; 236 | GCC_PREPROCESSOR_DEFINITIONS = ( 237 | "DEBUG=1", 238 | "$(inherited)", 239 | ); 240 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 241 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 242 | GCC_WARN_UNDECLARED_SELECTOR = YES; 243 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 244 | GCC_WARN_UNUSED_FUNCTION = YES; 245 | GCC_WARN_UNUSED_VARIABLE = YES; 246 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 247 | MTL_ENABLE_DEBUG_INFO = YES; 248 | ONLY_ACTIVE_ARCH = YES; 249 | SDKROOT = iphoneos; 250 | }; 251 | name = Debug; 252 | }; 253 | 92FAD5791FBE811D0031306A /* Release */ = { 254 | isa = XCBuildConfiguration; 255 | buildSettings = { 256 | ALWAYS_SEARCH_USER_PATHS = NO; 257 | CLANG_ANALYZER_NONNULL = YES; 258 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 259 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 260 | CLANG_CXX_LIBRARY = "libc++"; 261 | CLANG_ENABLE_MODULES = YES; 262 | CLANG_ENABLE_OBJC_ARC = YES; 263 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 264 | CLANG_WARN_BOOL_CONVERSION = YES; 265 | CLANG_WARN_COMMA = YES; 266 | CLANG_WARN_CONSTANT_CONVERSION = YES; 267 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 268 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 269 | CLANG_WARN_EMPTY_BODY = YES; 270 | CLANG_WARN_ENUM_CONVERSION = YES; 271 | CLANG_WARN_INFINITE_RECURSION = YES; 272 | CLANG_WARN_INT_CONVERSION = YES; 273 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 274 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 275 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 276 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 277 | CLANG_WARN_STRICT_PROTOTYPES = YES; 278 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 279 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 280 | CLANG_WARN_UNREACHABLE_CODE = YES; 281 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 282 | CODE_SIGN_IDENTITY = "iPhone Developer"; 283 | COPY_PHASE_STRIP = NO; 284 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 285 | ENABLE_NS_ASSERTIONS = NO; 286 | ENABLE_STRICT_OBJC_MSGSEND = YES; 287 | GCC_C_LANGUAGE_STANDARD = gnu11; 288 | GCC_NO_COMMON_BLOCKS = YES; 289 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 290 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 291 | GCC_WARN_UNDECLARED_SELECTOR = YES; 292 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 293 | GCC_WARN_UNUSED_FUNCTION = YES; 294 | GCC_WARN_UNUSED_VARIABLE = YES; 295 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 296 | MTL_ENABLE_DEBUG_INFO = NO; 297 | SDKROOT = iphoneos; 298 | VALIDATE_PRODUCT = YES; 299 | }; 300 | name = Release; 301 | }; 302 | 92FAD57B1FBE811D0031306A /* Debug */ = { 303 | isa = XCBuildConfiguration; 304 | buildSettings = { 305 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 306 | CODE_SIGN_STYLE = Automatic; 307 | DEVELOPMENT_TEAM = W2WUVUE5P6; 308 | INFOPLIST_FILE = CDDTitleRolling/Info.plist; 309 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 310 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 311 | PRODUCT_BUNDLE_IDENTIFIER = com.RocketsChen.CDDTitleRolling; 312 | PRODUCT_NAME = "$(TARGET_NAME)"; 313 | TARGETED_DEVICE_FAMILY = "1,2"; 314 | }; 315 | name = Debug; 316 | }; 317 | 92FAD57C1FBE811D0031306A /* Release */ = { 318 | isa = XCBuildConfiguration; 319 | buildSettings = { 320 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 321 | CODE_SIGN_STYLE = Automatic; 322 | DEVELOPMENT_TEAM = W2WUVUE5P6; 323 | INFOPLIST_FILE = CDDTitleRolling/Info.plist; 324 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 325 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 326 | PRODUCT_BUNDLE_IDENTIFIER = com.RocketsChen.CDDTitleRolling; 327 | PRODUCT_NAME = "$(TARGET_NAME)"; 328 | TARGETED_DEVICE_FAMILY = "1,2"; 329 | }; 330 | name = Release; 331 | }; 332 | /* End XCBuildConfiguration section */ 333 | 334 | /* Begin XCConfigurationList section */ 335 | 92FAD55C1FBE811C0031306A /* Build configuration list for PBXProject "CDDTitleRolling" */ = { 336 | isa = XCConfigurationList; 337 | buildConfigurations = ( 338 | 92FAD5781FBE811D0031306A /* Debug */, 339 | 92FAD5791FBE811D0031306A /* Release */, 340 | ); 341 | defaultConfigurationIsVisible = 0; 342 | defaultConfigurationName = Release; 343 | }; 344 | 92FAD57A1FBE811D0031306A /* Build configuration list for PBXNativeTarget "CDDTitleRolling" */ = { 345 | isa = XCConfigurationList; 346 | buildConfigurations = ( 347 | 92FAD57B1FBE811D0031306A /* Debug */, 348 | 92FAD57C1FBE811D0031306A /* Release */, 349 | ); 350 | defaultConfigurationIsVisible = 0; 351 | defaultConfigurationName = Release; 352 | }; 353 | /* End XCConfigurationList section */ 354 | 355 | /* Begin XCVersionGroup section */ 356 | 92FAD56D1FBE811D0031306A /* CDDTitleRolling.xcdatamodeld */ = { 357 | isa = XCVersionGroup; 358 | children = ( 359 | 92FAD56E1FBE811D0031306A /* CDDTitleRolling.xcdatamodel */, 360 | ); 361 | currentVersion = 92FAD56E1FBE811D0031306A /* CDDTitleRolling.xcdatamodel */; 362 | path = CDDTitleRolling.xcdatamodeld; 363 | sourceTree = ""; 364 | versionGroupType = wrapper.xcdatamodel; 365 | }; 366 | /* End XCVersionGroup section */ 367 | }; 368 | rootObject = 92FAD5591FBE811C0031306A /* Project object */; 369 | } 370 | -------------------------------------------------------------------------------- /CDDTitleRolling/CDDTitleRolling/CDDTitleRolling/DCTitleRolling.m: -------------------------------------------------------------------------------- 1 | // 2 | // DCTitleRolling.m 3 | // CDDTitleRolling 4 | // 5 | // Created by dashen on 2017/11/17. 6 | //Copyright © 2017年 com.RocketsChen. All rights reserved. 7 | // 8 | #define RollingBtnTag 1000 9 | 10 | #define RollingViewHeight self.frame.size.height 11 | #define RollingViewWidth self.frame.size.width 12 | #define RollingMargin 10 13 | 14 | #import "DCTitleRolling.h" 15 | 16 | // Controllers 17 | 18 | // Models 19 | 20 | // Views 21 | 22 | // Vendors 23 | 24 | // Categories 25 | #import "UIView+DCRolling.h" 26 | // Others 27 | 28 | @interface DCTitleRolling () 29 | 30 | /** 定时器的循环时间 */ 31 | @property (nonatomic , assign) NSInteger interval; 32 | /* 定时器 */ 33 | @property (strong , nonatomic)NSTimer *timer; 34 | /* 图片 */ 35 | @property (strong , nonatomic)NSString *leftImage; 36 | /* 按钮提示文字 */ 37 | @property (strong , nonatomic)NSString *rightbuttonTitle; 38 | 39 | /* 标题 */ 40 | @property (strong , nonatomic)NSArray *rolTitles; 41 | /* tags */ 42 | @property (strong , nonatomic)NSArray *rolTags; 43 | /* 右边图片数组 */ 44 | @property (strong , nonatomic)NSArray *rightImages; 45 | /* 滚动时间 */ 46 | @property (assign , nonatomic)float rollingTime; 47 | /* 字体尺寸 */ 48 | @property (nonatomic , assign) NSInteger titleFont; 49 | /* 字体颜色 */ 50 | @property (strong , nonatomic)UIColor *titleColor; 51 | 52 | /* 滚动按钮数组 */ 53 | @property (strong , nonatomic)NSMutableArray *saveMiddleArray; 54 | /** 是否显示tagLabel边框 */ 55 | @property (nonatomic,assign)BOOL isShowTagBorder; 56 | 57 | @property (nonatomic, assign) CDDRollingGroupStyle rollingGroupStyle; 58 | 59 | @end 60 | 61 | @implementation DCTitleRolling 62 | 63 | #pragma mark - LazyLoad 64 | - (UIImageView *)leftImageView 65 | { 66 | if (!_leftImageView) { 67 | _leftImageView = [[UIImageView alloc] init]; 68 | _leftImageView.contentMode = UIViewContentModeCenter; 69 | [self addSubview:_leftImageView]; 70 | } 71 | return _leftImageView; 72 | } 73 | 74 | 75 | - (UIButton *)rightButton 76 | { 77 | if (!_rightButton) { 78 | _rightButton = [UIButton buttonWithType:UIButtonTypeCustom]; 79 | _rightButton.adjustsImageWhenHighlighted = NO; 80 | [_rightButton setTitleColor:[UIColor darkGrayColor] forState:0]; 81 | [self addSubview:_rightButton]; 82 | } 83 | return _rightButton; 84 | } 85 | 86 | - (NSMutableArray *)saveMiddleArray 87 | { 88 | if (!_saveMiddleArray) { 89 | _saveMiddleArray = [NSMutableArray array]; 90 | } 91 | return _saveMiddleArray; 92 | } 93 | 94 | #pragma mark - Intial 95 | - (instancetype)initWithFrame:(CGRect)frame WithTitleData:(void(^)(CDDRollingGroupStyle *rollingGroupStyle, NSString **leftImage,NSArray **rolTitles,NSArray **rolTags,NSArray **rightImages,NSString **rightbuttonTitle,NSInteger *interval,float *rollingTime,NSInteger *titleFont,UIColor **titleColor,BOOL *isShowTagBorder))titleDataBlock{ 96 | 97 | self = [super initWithFrame:frame]; 98 | if (self) { 99 | 100 | NSString *leftImage; 101 | NSString *rightbuttonTitle; 102 | 103 | NSArray *rolTitles; 104 | NSArray *rolTags; 105 | NSArray *rightImages; 106 | 107 | NSInteger interval; 108 | float rollingTime; 109 | NSInteger titleFont; 110 | UIColor *titleColor; 111 | 112 | BOOL isShowTagBorder; 113 | 114 | if (titleDataBlock) { 115 | titleDataBlock(&_rollingGroupStyle,&leftImage,&rolTitles,&rolTags,&rightImages,&rightbuttonTitle,&interval,&rollingTime,&titleFont,&titleColor,&isShowTagBorder); 116 | 117 | self.leftImage = leftImage; 118 | self.rolTitles = rolTitles; 119 | self.rolTags = rolTags; 120 | self.rightImages = rightImages; 121 | self.interval = (interval == 0 || interval > 100) ? 5.0 : interval; //限定定时不大于100秒 122 | self.rollingTime = (rollingTime <= 0.1 || rollingTime > 1) ? 0.5 : rollingTime; //限定翻滚时间不能大于1秒 123 | self.rightbuttonTitle = rightbuttonTitle; 124 | self.titleFont = (titleFont == 0) ? 13 : titleFont; 125 | self.titleColor = (titleColor == nil) ? [UIColor blackColor] : titleColor; 126 | self.isShowTagBorder = isShowTagBorder; 127 | 128 | 129 | if (self.rolTags.count == 0 && self.rolTitles.count == 0) return 0; //若数组为0直接返回 130 | if (_rollingGroupStyle == CDDRollingTwoGroup) { 131 | 132 | [self setUpTwoGroupRollingUI]; //UI 133 | 134 | }else{ 135 | 136 | [self setUpOneGroupRollingUI]; //UI 137 | } 138 | }; 139 | 140 | } 141 | return self; 142 | } 143 | 144 | #pragma mark - 界面搭建【CDDRollingOneGroup】 145 | - (void)setUpOneGroupRollingUI 146 | { 147 | 148 | [self setUpRollingLeft]; 149 | 150 | [self setUpRollingCenter]; 151 | 152 | [self setUpRollingRight]; 153 | 154 | } 155 | 156 | #pragma mark - 界面搭建【CDDRollingTwoGroup】 157 | - (void)setUpTwoGroupRollingUI 158 | { 159 | [self setUpRollingLeft]; 160 | 161 | [self setUpRollingCenterRight]; 162 | } 163 | 164 | #pragma mark - 左边图片 165 | - (void)setUpRollingLeft 166 | { 167 | if (self.leftImage == nil)return; 168 | 169 | self.leftImageView.frame = CGRectMake(0, RollingViewHeight * 0.1, RollingViewHeight * 1.5, RollingViewHeight * 0.8); 170 | self.leftImageView.image = [UIImage imageNamed:self.leftImage]; 171 | 172 | } 173 | 174 | #pragma mark - 中间带右部 175 | - (void)setUpRollingCenterRight 176 | { 177 | if (self.saveMiddleArray.count > 0) return; 178 | 179 | if (_rolTitles.count > 1) {//@[@[],@[]] 180 | 181 | NSArray *firstTitleArrray = _rolTitles.firstObject; 182 | NSArray *firstTagArrray = _rolTags.firstObject; 183 | NSArray *lastTagArray = _rolTags.lastObject; 184 | NSArray *lastTitleArray = _rolTitles.lastObject; 185 | 186 | for (NSInteger i= 0; i < firstTitleArrray.count; i++) { 187 | 188 | UIButton *middleView = [self getBackMiddleViewWithFrame:CGRectMake(CGRectGetMaxX(self.leftImageView.frame), 0, RollingViewWidth - CGRectGetMaxX(self.leftImageView.frame), RollingViewHeight) WithIndex:i]; //中间View 189 | 190 | UILabel *contentTopLabel = [UILabel new]; 191 | [middleView addSubview:contentTopLabel]; 192 | 193 | UILabel *contentBottomLabel = [UILabel new]; 194 | [middleView addSubview:contentBottomLabel]; 195 | 196 | contentTopLabel.textAlignment = contentBottomLabel.textAlignment = NSTextAlignmentLeft; 197 | contentTopLabel.font = contentBottomLabel.font = [UIFont systemFontOfSize:self.titleFont]; 198 | contentTopLabel.textColor = contentBottomLabel.textColor = self.titleColor; 199 | 200 | UIImageView *rightImageView = [UIImageView new]; 201 | if (_rightImages.count == firstTitleArrray.count) { 202 | 203 | [middleView addSubview:rightImageView]; 204 | rightImageView.frame = CGRectMake(middleView.dc_width - (middleView.dc_height * 1.2), 0, middleView.dc_height * 1.2, middleView.dc_height); 205 | rightImageView.contentMode = UIViewContentModeCenter; 206 | rightImageView.image = [UIImage imageNamed:_rightImages[i]]; 207 | } 208 | 209 | contentTopLabel.text = firstTitleArrray[i]; 210 | contentBottomLabel.text = lastTitleArray[i]; 211 | 212 | if (_rolTags.count > 0 && firstTitleArrray.count == firstTagArrray.count) { 213 | 214 | UILabel *tagTopLabel = [UILabel new]; 215 | UILabel *tagBottomLabel = [UILabel new]; 216 | [middleView addSubview:tagTopLabel]; 217 | [middleView addSubview:tagBottomLabel]; 218 | 219 | tagTopLabel.font = tagBottomLabel.font = [UIFont systemFontOfSize:self.titleFont - 1.5]; 220 | tagTopLabel.textColor = tagBottomLabel.textColor = [UIColor orangeColor]; 221 | tagTopLabel.textAlignment = tagBottomLabel.textAlignment = NSTextAlignmentCenter; 222 | tagTopLabel.text = firstTagArrray[i]; 223 | tagBottomLabel.text = lastTagArray[i]; 224 | 225 | if (self.isShowTagBorder) { //是否tag显示边框 226 | [self dc_chageControlCircularWith:tagTopLabel AndSetCornerRadius:3 SetBorderWidth:1 SetBorderColor:tagTopLabel.textColor canMasksToBounds:YES]; 227 | [self dc_chageControlCircularWith:tagBottomLabel AndSetCornerRadius:3 SetBorderWidth:1 SetBorderColor:tagBottomLabel.textColor canMasksToBounds:YES]; 228 | } 229 | 230 | CGSize tagTopSize = [self labelAutoCalculateRectWith:firstTagArrray[i] FontSize:self.titleFont - 1 MaxSize:CGSizeMake(MAXFLOAT, RollingViewHeight)]; 231 | CGSize tagBottomSize = [self labelAutoCalculateRectWith:lastTagArray[i] FontSize:self.titleFont - 1 MaxSize:CGSizeMake(MAXFLOAT, RollingViewHeight)]; 232 | 233 | tagTopLabel.dc_size = CGSizeMake(tagTopSize.width + 4, tagTopSize.height + 4); 234 | tagBottomLabel.dc_size = CGSizeMake(tagBottomSize.width + 4, tagBottomSize.height + 4); 235 | 236 | contentTopLabel.frame = CGRectMake(CGRectGetMaxX(tagTopLabel.frame) + 5, 0, middleView.dc_width - rightImageView.dc_width, middleView.dc_height * 0.5); 237 | 238 | contentBottomLabel.frame = CGRectMake(CGRectGetMaxX(tagBottomLabel.frame) + 5, middleView.dc_height * 0.5, middleView.dc_width - rightImageView.dc_width, middleView.dc_height * 0.5); 239 | 240 | tagTopLabel.dc_x = tagBottomLabel.dc_x = 0; 241 | tagTopLabel.dc_centerY = contentTopLabel.dc_centerY; 242 | tagBottomLabel.dc_centerY = contentBottomLabel.dc_centerY; 243 | 244 | }else{ 245 | 246 | contentTopLabel.frame = CGRectMake(0, 0, middleView.dc_width - rightImageView.dc_width, middleView.dc_height * 0.5); 247 | contentBottomLabel.frame = CGRectMake(0, middleView.dc_height * 0.5, middleView.dc_width - rightImageView.dc_width, middleView.dc_height * 0.5); 248 | 249 | } 250 | 251 | [self setUpCATransform3DWithIndex:i WithButton:middleView];//旋转 252 | } 253 | } 254 | } 255 | 256 | #pragma mark - 中间滚动内容 257 | - (void)setUpRollingCenter 258 | { 259 | if (self.saveMiddleArray.count > 0) return; 260 | 261 | if (_rolTitles.count > 0) { 262 | for (NSInteger i = 0; i < _rolTitles.count; i++) { 263 | 264 | CGRect middleFrame = (self.rightbuttonTitle == nil) ? CGRectMake(CGRectGetMaxX(self.leftImageView.frame), 0, RollingViewWidth - CGRectGetMaxX(self.leftImageView.frame), RollingViewHeight) : CGRectMake(CGRectGetMaxX(self.leftImageView.frame), 0, RollingViewWidth - (CGRectGetMaxX(self.leftImageView.frame) + RollingViewWidth * 0.2), RollingViewHeight); 265 | 266 | UIButton *middleView = [self getBackMiddleViewWithFrame:middleFrame WithIndex:i]; 267 | 268 | UILabel *contentLabel = [UILabel new]; 269 | [middleView addSubview:contentLabel]; 270 | contentLabel.textAlignment = NSTextAlignmentLeft; 271 | contentLabel.font = [UIFont systemFontOfSize:self.titleFont]; 272 | contentLabel.textColor = self.titleColor; 273 | contentLabel.text = self.rolTitles[i]; 274 | 275 | if (self.rolTags.count > 0 && self.rolTitles.count == self.rolTags.count) { 276 | 277 | UILabel *tagLabel = [UILabel new]; 278 | [middleView addSubview:tagLabel]; 279 | tagLabel.font = [UIFont systemFontOfSize:self.titleFont - 1.5]; 280 | tagLabel.textColor = [UIColor redColor]; 281 | tagLabel.textAlignment = NSTextAlignmentCenter; 282 | 283 | tagLabel.text = self.rolTags[i]; 284 | if (self.isShowTagBorder) {//是否tag显示边框 285 | [self dc_chageControlCircularWith:tagLabel AndSetCornerRadius:3 SetBorderWidth:1 SetBorderColor:tagLabel.textColor canMasksToBounds:YES]; 286 | } 287 | 288 | CGSize tagSize = [self labelAutoCalculateRectWith:self.rolTags[i] FontSize:self.titleFont - 1 MaxSize:CGSizeMake(MAXFLOAT, RollingViewHeight)]; 289 | tagLabel.dc_size = CGSizeMake(tagSize.width + 4, tagSize.height + 4); 290 | tagLabel.dc_x = 0; 291 | tagLabel.dc_centerY = middleView.dc_centerY; 292 | 293 | contentLabel.frame = CGRectMake(CGRectGetMaxX(tagLabel.frame) + 5, 0, middleView.dc_width - CGRectGetMaxX(tagLabel.frame), middleView.dc_height); 294 | 295 | }else{ 296 | contentLabel.frame = CGRectMake(5, 0, middleView.dc_width - RollingMargin, middleView.dc_height); 297 | 298 | } 299 | 300 | [self setUpCATransform3DWithIndex:i WithButton:middleView]; //旋转 301 | } 302 | } 303 | } 304 | 305 | #pragma mark - 右边按钮 306 | - (void)setUpRollingRight 307 | { 308 | if (self.rightbuttonTitle == nil) return; 309 | 310 | self.rightButton.frame = CGRectMake(RollingViewWidth * 0.8, RollingViewHeight * 0.1, RollingViewWidth * 0.18, RollingViewHeight * 0.8); 311 | [self.rightButton setTitle:self.rightbuttonTitle forState:0]; 312 | self.rightButton.titleLabel.font = [UIFont systemFontOfSize:self.titleFont + 0.5]; 313 | 314 | [self.rightButton addTarget:self action:@selector(rightMoreButtonClick) forControlEvents:UIControlEventTouchUpInside]; 315 | 316 | UIView *btnLine = [UIView new]; 317 | btnLine.backgroundColor = [UIColor darkGrayColor]; 318 | btnLine.frame = CGRectMake(RollingViewWidth * 0.82, RollingViewHeight * 0.35, 1.5, RollingViewHeight * 0.3); 319 | [self addSubview:btnLine]; 320 | } 321 | 322 | 323 | 324 | #pragma mark - 开始滚动 325 | - (void)dc_beginRolling{ 326 | 327 | _timer = [NSTimer timerWithTimeInterval:self.interval target:self selector:@selector(titleRolling) userInfo:nil repeats:YES]; 328 | [[NSRunLoop currentRunLoop]addTimer:_timer forMode:NSRunLoopCommonModes]; 329 | } 330 | 331 | #pragma mark - 结束滚动 332 | - (void)dc_endRolling{ 333 | 334 | [_timer invalidate]; 335 | } 336 | 337 | 338 | #pragma mark - 标题滚动 339 | - (void)titleRolling{ 340 | 341 | if (self.saveMiddleArray.count > 1) { //所存的每组滚动 342 | __weak typeof(self)weakSelf = self; 343 | 344 | [UIView animateWithDuration:self.rollingTime animations:^{ 345 | 346 | [self getMiddleArrayWithIndex:0 WithAngle:- M_PI_2 Height:- RollingViewHeight / 2]; //第0组 347 | 348 | [self getMiddleArrayWithIndex:1 WithAngle:0 Height:0]; //第一组 349 | 350 | } completion:^(BOOL finished) { 351 | 352 | if (finished == YES) { //旋转结束 353 | UIButton *newMiddleView = [weakSelf getMiddleArrayWithIndex:0 WithAngle:M_PI_2 Height: -RollingViewHeight / 2]; 354 | [weakSelf.saveMiddleArray addObject:newMiddleView]; 355 | 356 | [weakSelf.saveMiddleArray removeObjectAtIndex:0]; 357 | } 358 | }]; 359 | } 360 | 361 | } 362 | 363 | #pragma mark - CATransform3D翻转 364 | - (UIButton *)getMiddleArrayWithIndex:(NSInteger)index WithAngle:(CGFloat)angle Height:(CGFloat)height 365 | { 366 | if (index > _saveMiddleArray.count) return 0; 367 | UIButton *middleView = self.saveMiddleArray[index]; 368 | 369 | CATransform3D trans = CATransform3DIdentity; 370 | trans = CATransform3DMakeRotation(angle, 1, 0, 0); 371 | trans = CATransform3DTranslate(trans, 0, height, height); 372 | middleView.layer.transform = trans; 373 | 374 | return middleView; 375 | } 376 | 377 | #pragma mark - 初始布局 378 | - (void)setUpCATransform3DWithIndex:(NSInteger)index WithButton:(UIButton *)contentButton 379 | { 380 | if (index != 0) { 381 | CATransform3D trans = CATransform3DIdentity; 382 | trans = CATransform3DMakeRotation(M_PI_2, 1, 0, 0); 383 | trans = CATransform3DTranslate(trans, 0, - RollingViewHeight / 2, -RollingViewHeight / 2); 384 | contentButton.layer.transform = trans; 385 | }else{ 386 | CATransform3D trans = CATransform3DIdentity; 387 | trans = CATransform3DMakeRotation(0, 1, 0, 0); 388 | trans = CATransform3DTranslate(trans, 0, 0, - RollingViewHeight / 2); 389 | contentButton.layer.transform = trans; 390 | } 391 | } 392 | 393 | #pragma mark - 初始化中间View 394 | - (UIButton *)getBackMiddleViewWithFrame:(CGRect)frame WithIndex:(NSInteger)index 395 | { 396 | UIButton *middleView = [UIButton buttonWithType:UIButtonTypeCustom]; 397 | middleView.adjustsImageWhenHighlighted = NO; 398 | middleView.tag = RollingBtnTag + index; 399 | [middleView addTarget:self action:@selector(titleButonAction:) forControlEvents:UIControlEventTouchUpInside]; 400 | middleView.frame = frame; 401 | [self addSubview:middleView]; 402 | [self.saveMiddleArray addObject:middleView]; 403 | 404 | return middleView; 405 | } 406 | 407 | #pragma mark - 点击更多 408 | - (void)rightMoreButtonClick 409 | { 410 | !_moreClickBlock ? : _moreClickBlock(); 411 | } 412 | 413 | - (void)titleButonAction:(UIButton *)sender 414 | { 415 | NSInteger tag = sender.tag - RollingBtnTag; 416 | if ([self.delegate respondsToSelector:@selector(dc_RollingViewSelectWithActionAtIndex:)]) { 417 | [self.delegate dc_RollingViewSelectWithActionAtIndex:tag]; 418 | } 419 | } 420 | 421 | @end 422 | --------------------------------------------------------------------------------