From 68bddda5f89543671b8776e666cb66701e8bf1a8 Mon Sep 17 00:00:00 2001 From: tingxins Date: Tue, 8 Nov 2016 23:00:22 +0800 Subject: [PATCH] add Demo. --- TXScrollLabelView/TXScrollLabelView.h | 42 + TXScrollLabelView/TXScrollLabelView.m | 273 +++ TXScrollLabelView/UIView+TXFrame.h | 32 + TXScrollLabelView/UIView+TXFrame.m | 111 + .../project.pbxproj | 562 ++++++ .../contents.xcworkspacedata | 7 + .../TXScrollLabelViewDemo/AppDelegate.h | 17 + .../TXScrollLabelViewDemo/AppDelegate.m | 51 + .../AppIcon.appiconset/Contents.json | 48 + .../Base.lproj/LaunchScreen.storyboard | 27 + .../Base.lproj/Main.storyboard | 1777 +++++++++++++++++ .../TXScrollLabelViewDemo/Info.plist | 38 + .../TXScrollLabelView/TXScrollLabelView.h | 76 + .../TXScrollLabelView/TXScrollLabelView.m | 396 ++++ .../TXScrollLabelView/UIView+TXFrame.h | 32 + .../TXScrollLabelView/UIView+TXFrame.m | 111 + .../TXScrollLabelViewDemo/ViewController.h | 15 + .../TXScrollLabelViewDemo/ViewController.m | 52 + .../TXScrollLabelViewDemo/main.m | 16 + .../TXScrollLabelViewDemoTests/Info.plist | 22 + .../TXScrollLabelViewDemoTests.m | 39 + .../TXScrollLabelViewDemoUITests/Info.plist | 22 + .../TXScrollLabelViewDemoUITests.m | 40 + 23 files changed, 3806 insertions(+) create mode 100644 TXScrollLabelView/TXScrollLabelView.h create mode 100644 TXScrollLabelView/TXScrollLabelView.m create mode 100644 TXScrollLabelView/UIView+TXFrame.h create mode 100644 TXScrollLabelView/UIView+TXFrame.m create mode 100644 TXScrollLabelViewDemo/TXScrollLabelViewDemo.xcodeproj/project.pbxproj create mode 100644 TXScrollLabelViewDemo/TXScrollLabelViewDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 TXScrollLabelViewDemo/TXScrollLabelViewDemo/AppDelegate.h create mode 100644 TXScrollLabelViewDemo/TXScrollLabelViewDemo/AppDelegate.m create mode 100644 TXScrollLabelViewDemo/TXScrollLabelViewDemo/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 TXScrollLabelViewDemo/TXScrollLabelViewDemo/Base.lproj/LaunchScreen.storyboard create mode 100644 TXScrollLabelViewDemo/TXScrollLabelViewDemo/Base.lproj/Main.storyboard create mode 100644 TXScrollLabelViewDemo/TXScrollLabelViewDemo/Info.plist create mode 100644 TXScrollLabelViewDemo/TXScrollLabelViewDemo/TXScrollLabelView/TXScrollLabelView.h create mode 100644 TXScrollLabelViewDemo/TXScrollLabelViewDemo/TXScrollLabelView/TXScrollLabelView.m create mode 100644 TXScrollLabelViewDemo/TXScrollLabelViewDemo/TXScrollLabelView/UIView+TXFrame.h create mode 100644 TXScrollLabelViewDemo/TXScrollLabelViewDemo/TXScrollLabelView/UIView+TXFrame.m create mode 100644 TXScrollLabelViewDemo/TXScrollLabelViewDemo/ViewController.h create mode 100644 TXScrollLabelViewDemo/TXScrollLabelViewDemo/ViewController.m create mode 100644 TXScrollLabelViewDemo/TXScrollLabelViewDemo/main.m create mode 100644 TXScrollLabelViewDemo/TXScrollLabelViewDemoTests/Info.plist create mode 100644 TXScrollLabelViewDemo/TXScrollLabelViewDemoTests/TXScrollLabelViewDemoTests.m create mode 100644 TXScrollLabelViewDemo/TXScrollLabelViewDemoUITests/Info.plist create mode 100644 TXScrollLabelViewDemo/TXScrollLabelViewDemoUITests/TXScrollLabelViewDemoUITests.m diff --git a/TXScrollLabelView/TXScrollLabelView.h b/TXScrollLabelView/TXScrollLabelView.h new file mode 100644 index 0000000..e3f75b3 --- /dev/null +++ b/TXScrollLabelView/TXScrollLabelView.h @@ -0,0 +1,42 @@ +// +// TXScrollLabelView.h +// +// Created by tingxins on 2/23/16. +// Copyright © 2016 tingxins. All rights reserved. +// 滚动视图 + +typedef enum { + TXScrollLabelViewType_LR, + TXScrollLabelViewType_UD, + TXScrollLabelViewType_Flip, + TXScrollLabelViewType_FlipNoCle +}TXScrollLabelViewType; + +#import + +@interface TXScrollLabelView : UIScrollView + +#pragma mark - Property +/** 滚动文字 */ +@property (copy, nonatomic) NSString *scrollTitle; +/** 滚动类型 */ +@property (assign, nonatomic) TXScrollLabelViewType scrollType; +/** 滚动速率 */ +@property (assign, nonatomic) NSTimeInterval scrollVelocity; + +#pragma mark - Methods +/** + * 开始滚动 + */ +- (void) beginScrolling; +/** + * 停止滚动 + */ +- (void) stopScrolling; + +/** + * 暂停滚动 + */ +- (void) pauseScrolling; + +@end diff --git a/TXScrollLabelView/TXScrollLabelView.m b/TXScrollLabelView/TXScrollLabelView.m new file mode 100644 index 0000000..d344ae7 --- /dev/null +++ b/TXScrollLabelView/TXScrollLabelView.m @@ -0,0 +1,273 @@ +// +// TXScrollLabelView.m +// +// Created by tingxins on 2/23/16. +// Copyright © 2016 tingxins. All rights reserved. +// +#define TXScrollLabelFont [UIFont systemFontOfSize:14] +#import "TXScrollLabelView.h" +#import "UIView+TXFrame.h" +#import + +@interface TXScrollLabelView () + +@property (weak, nonatomic) UILabel *scrollLabel0; + +@property (weak, nonatomic) UILabel *scrollLabel1; + +@property (weak, nonatomic) UITextView *scrollTextView; + +@property (strong, nonatomic) NSTimer *scrollTimer; + +@property (strong, nonatomic) NSArray *scrollArray; + +@end + +@implementation TXScrollLabelView + +- (NSArray *)scrollArray { + if (_scrollArray) return _scrollArray; + return _scrollArray = [self getSeparatedLinesFromLabel]; +} + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + self.backgroundColor = [UIColor blackColor]; + UILabel *scrollLabel0 = [[UILabel alloc]init]; + scrollLabel0.numberOfLines = 0; + self.scrollLabel0 = scrollLabel0; + self.scrollLabel0.font = TXScrollLabelFont; + self.scrollLabel0.textColor = [UIColor whiteColor]; + [self addSubview:scrollLabel0]; + + UILabel *scrollLabel1 = [[UILabel alloc]init]; + scrollLabel1.numberOfLines = 0; + self.scrollLabel1 = scrollLabel1; + self.scrollLabel1.font = TXScrollLabelFont; + self.scrollLabel1.textColor = [UIColor whiteColor]; + [self addSubview:scrollLabel1]; + + scrollLabel0.lineBreakMode = NSLineBreakByWordWrapping; + scrollLabel1.lineBreakMode = NSLineBreakByWordWrapping; + scrollLabel0.textAlignment = NSTextAlignmentCenter; + scrollLabel1.textAlignment = NSTextAlignmentCenter; + self.scrollEnabled = NO; + } + return self; +} + +- (void)setScrollTitle:(NSString *)scrollTitle { + _scrollTitle = [scrollTitle copy]; + + switch (self.scrollType) { + case TXScrollLabelViewType_LR: + { + CGSize scrollLabelS = [self.scrollTitle boundingRectWithSize:CGSizeMake(0, 30) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: TXScrollLabelFont} context:nil].size; + self.scrollLabel0.frame = CGRectMake(10, 0, scrollLabelS.width, 30); + self.scrollLabel0.text = self.scrollTitle; + + self.scrollLabel1.frame = CGRectMake(CGRectGetMaxX(self.scrollLabel0.frame) + 20, 0, scrollLabelS.width, 30); + self.scrollLabel1.text = self.scrollTitle; + self.contentSize = CGSizeMake(scrollLabelS.width * 2 + 40, scrollLabelS.height); + CGFloat maxWidth = 200; + self.bounds = CGRectMake(0, 0, MIN(maxWidth, scrollLabelS.width), 30); + } + break; + + case TXScrollLabelViewType_UD: + { + + CGSize scrollLabelS = [self.scrollTitle boundingRectWithSize:CGSizeMake(200, 0) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: TXScrollLabelFont} context:nil].size; + self.scrollLabel0.frame = CGRectMake(0, 0, scrollLabelS.width, scrollLabelS.height); + self.scrollLabel0.text = self.scrollTitle; + + self.scrollLabel1.frame = CGRectMake(0, CGRectGetMaxY(self.scrollLabel0.frame), scrollLabelS.width, scrollLabelS.height); + self.scrollLabel1.text = self.scrollTitle; + self.contentSize = CGSizeMake(scrollLabelS.width, scrollLabelS.height * 2); + self.bounds = CGRectMake(0, 0, scrollLabelS.width, 30); + } + break; + + case TXScrollLabelViewType_Flip: + { + + CGSize scrollLabelS = [self.scrollTitle boundingRectWithSize:CGSizeMake(200, 30) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: TXScrollLabelFont} context:nil].size; + self.scrollLabel0.frame = CGRectMake(0, 0, scrollLabelS.width, 30); + self.scrollLabel0.text = self.scrollTitle; + + self.scrollLabel1.frame = CGRectMake(0, CGRectGetMaxY(self.scrollLabel0.frame), scrollLabelS.width, 30);; + self.scrollLabel1.text = self.scrollTitle; + self.contentSize = CGSizeMake(scrollLabelS.width, scrollLabelS.height * 2); + self.bounds = CGRectMake(0, 0, scrollLabelS.width, 30); + } + break; + + + case TXScrollLabelViewType_FlipNoCle: + { + NSMutableParagraphStyle *paraStyle = [[NSMutableParagraphStyle alloc]init]; + paraStyle.lineSpacing = 10; + NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:_scrollTitle]; + [attributedStr addAttributes:@{NSFontAttributeName:TXScrollLabelFont, NSParagraphStyleAttributeName:paraStyle} range:NSMakeRange(0, attributedStr.length)]; + + CGSize scrollLabelS = [attributedStr boundingRectWithSize:CGSizeMake(self.tx_width, 0) options:NSStringDrawingUsesLineFragmentOrigin context:nil].size; + + self.scrollLabel0.frame = CGRectMake(0, 0, scrollLabelS.width, self.tx_height); + self.scrollLabel1.frame = CGRectMake(0, CGRectGetMaxY(self.scrollLabel0.frame), scrollLabelS.width, self.tx_height); + + CGFloat width = scrollLabelS.width; + if (!self.tx_width) { + self.tx_width = width; + } + self.contentSize = CGSizeMake(self.tx_width, scrollLabelS.height * 2); + self.bounds = CGRectMake(0, 0, self.tx_width, self.tx_height); + } + break; + + default: + break; + } +} + +- (void)beginScrolling { + [self stopScrolling]; + self.scrollTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(updateScrolling) userInfo:nil repeats:YES]; + [[NSRunLoop mainRunLoop] addTimer:self.scrollTimer forMode:NSRunLoopCommonModes]; +} + +- (void)stopScrolling { + [self.scrollTimer invalidate]; + self.scrollTimer = nil; +} + +- (void)pauseScrolling { + [self.scrollTimer invalidate]; + self.scrollTimer = nil; +} + +- (void)updateScrolling { + switch (self.scrollType) { + case TXScrollLabelViewType_LR: + { + if (self.contentSize.width * 0.5 == self.contentOffset.x || self.contentOffset.x > self.contentSize.width * 0.5) { + [self stopScrolling]; + self.contentOffset = CGPointMake(2, 0);//x增加偏移量,防止卡顿 + [self beginScrolling]; + return; + } + self.contentOffset = CGPointMake(self.contentOffset.x + 1, self.contentOffset.y); + + } + break; + + case TXScrollLabelViewType_UD: + { + if (self.contentOffset.y > self.scrollLabel0.frame.size.height) { + [self stopScrolling]; + self.contentOffset = CGPointMake(0, 2);//y增加偏移量,防止卡顿 + [self beginScrolling]; + return; + } + self.contentOffset = CGPointMake(self.contentOffset.x, self.contentOffset.y + 1); + + } + break; + + case TXScrollLabelViewType_Flip: + { + + [self stopScrolling]; + self.scrollTimer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(updateScrolling) userInfo:nil repeats:YES]; + [[NSRunLoop mainRunLoop] addTimer:self.scrollTimer forMode:NSRunLoopCommonModes]; + + [self flipAnimationWithDelay:0]; + } + break; + + case TXScrollLabelViewType_FlipNoCle: + { + + [self stopScrolling]; + NSTimeInterval velocity = self.scrollVelocity ? self.scrollVelocity : 2; + + self.scrollTimer = [NSTimer scheduledTimerWithTimeInterval:velocity target:self selector:@selector(updateScrolling) userInfo:nil repeats:YES]; + [[NSRunLoop mainRunLoop] addTimer:self.scrollTimer forMode:NSRunLoopCommonModes]; + + [self flipNoCleAnimationWithDelay:velocity]; + } + break; + + default: + break; + } +} + +- (void)flipAnimationWithDelay:(NSTimeInterval)delay { + [UIView transitionWithView:self.scrollLabel0 duration:delay * 0.5 options:UIViewAnimationOptionTransitionFlipFromTop animations:^{ + self.scrollLabel0.tx_bottom = 0; + [UIView transitionWithView:self.scrollLabel0 duration:delay * 0.5 options:UIViewAnimationOptionTransitionFlipFromTop animations:^{ + self.scrollLabel1.tx_y = 0; + } completion:^(BOOL finished) { + self.scrollLabel0.tx_y = self.tx_height; + UILabel *tempLabel = self.scrollLabel0; + self.scrollLabel0 = self.scrollLabel1; + self.scrollLabel1 = tempLabel; + }]; + } completion:nil]; +} + +- (void)flipNoCleAnimationWithDelay:(NSTimeInterval)delay { + static int count = 0; + + self.scrollLabel0.text = self.scrollArray[count]; + + count ++; + + if (count == self.scrollArray.count) count = 0; + + self.scrollLabel1.text = self.scrollArray[count]; + + [self flipAnimationWithDelay:delay]; +} + +#pragma mark - 文字分行 + +-(NSArray *)getSeparatedLinesFromLabel { + + NSString *text = _scrollTitle; + UIFont *font = [UIFont systemFontOfSize:15]; + + CTFontRef myFont = CTFontCreateWithName((__bridge CFStringRef)([font fontName]), [font pointSize], NULL); + + NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] initWithString:text]; + + [attStr addAttribute:(NSString *)kCTFontAttributeName value:(__bridge id)myFont range:NSMakeRange(0, attStr.length)]; + + CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)attStr); + + CGMutablePathRef path = CGPathCreateMutable(); + + CGPathAddRect(path, NULL, CGRectMake(0,0,self.tx_width,100000)); + + CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, NULL); + + NSArray *lines = (__bridge NSArray *)CTFrameGetLines(frame); + + NSMutableArray *linesArray = [[NSMutableArray alloc]init]; + + for (id line in lines) { + + CTLineRef lineRef = (__bridge CTLineRef )line; + + CFRange lineRange = CTLineGetStringRange(lineRef); + + NSRange range = NSMakeRange(lineRange.location, lineRange.length); + + NSString *lineString = [text substringWithRange:range]; + + [linesArray addObject:lineString]; + } + return (NSArray *)linesArray; +} + +@end diff --git a/TXScrollLabelView/UIView+TXFrame.h b/TXScrollLabelView/UIView+TXFrame.h new file mode 100644 index 0000000..4b60622 --- /dev/null +++ b/TXScrollLabelView/UIView+TXFrame.h @@ -0,0 +1,32 @@ +// +// UIView+TXFrame.h +// TXSwipeTableViewTest +// +// Created by tingxins on 9/1/16. +// Copyright © 2016 tingxins. All rights reserved. +// + +#import + +@interface UIView (TXFrame) +/** 设置x值 */ +@property (assign, nonatomic) CGFloat tx_x; +/** 设置y值 */ +@property (assign, nonatomic) CGFloat tx_y; +/** 设置width */ +@property (assign, nonatomic) CGFloat tx_width; +/** 设置height */ +@property (assign, nonatomic) CGFloat tx_height; +/** 设置size */ +@property (assign, nonatomic) CGSize tx_size; +/** 设置origin */ +@property (assign, nonatomic) CGPoint tx_origin; +/** 设置center */ +@property (assign, nonatomic) CGPoint tx_center; +/** 设置center.x */ +@property (assign, nonatomic) CGFloat tx_centerX; +/** 设置center.y */ +@property (assign, nonatomic) CGFloat tx_centerY; +/** 设置bottom */ +@property (assign, nonatomic) CGFloat tx_bottom; +@end diff --git a/TXScrollLabelView/UIView+TXFrame.m b/TXScrollLabelView/UIView+TXFrame.m new file mode 100644 index 0000000..a6cde8c --- /dev/null +++ b/TXScrollLabelView/UIView+TXFrame.m @@ -0,0 +1,111 @@ +// +// UIView+TXFrame.m +// TXSwipeTableViewTest +// +// Created by tingxins on 9/1/16. +// Copyright © 2016 tingxins. All rights reserved. +// + +#import "UIView+TXFrame.h" + +@implementation UIView (TXFrame) + +- (CGFloat)tx_x { + return self.frame.origin.x; +} + +- (void)setTx_x:(CGFloat)tx_x { + CGRect frame = self.frame; + frame.origin.x = tx_x; + self.frame = frame; +} + +- (CGFloat)tx_y { + return self.frame.origin.y; +} + +- (void)setTx_y:(CGFloat)tx_y { + CGRect frame = self.frame; + frame.origin.y = tx_y; + self.frame = frame; +} + +- (CGFloat)tx_width { + return self.frame.size.width; +} + +- (void)setTx_width:(CGFloat)tx_width { + CGRect frame = self.frame; + frame.size.width = tx_width; + self.frame = frame; +} + +- (CGFloat)tx_height { + return self.frame.size.height; +} + +- (void)setTx_height:(CGFloat)tx_height { + CGRect frame = self.frame; + frame.size.height = tx_height; + self.frame = frame; +} + +- (CGSize)tx_size { + return self.frame.size; +} + +- (void)setTx_size:(CGSize)tx_size { + CGRect frame = self.frame; + frame.size = tx_size; + self.frame = frame; +} + +- (CGPoint)tx_origin { + return self.frame.origin; +} + +- (void)setTx_origin:(CGPoint)tx_origin { + CGRect frame = self.frame; + frame.origin = tx_origin; + self.frame = frame; +} + +- (CGPoint)tx_center { + return self.center; +} + +- (void)setTx_center:(CGPoint)tx_center { + self.center = tx_center; +} + +- (CGFloat)tx_centerX { + return self.center.x; +} + +- (void)setTx_centerX:(CGFloat)tx_centerX { + CGPoint center = self.center; + center.x = tx_centerX; + self.center = center; +} + +- (CGFloat)tx_centerY { + return self.center.y; +} + +- (void)setTx_centerY:(CGFloat)tx_centerY { + CGPoint center = self.center; + center.y = tx_centerY; + self.center = center; +} + +- (CGFloat)tx_bottom { + return CGRectGetMaxY(self.frame); +} + +- (void)setTx_bottom:(CGFloat)tx_bottom { + CGRect frame = self.frame; + frame.origin.y = tx_bottom - frame.size.height; + self.frame = frame; +} + +@end diff --git a/TXScrollLabelViewDemo/TXScrollLabelViewDemo.xcodeproj/project.pbxproj b/TXScrollLabelViewDemo/TXScrollLabelViewDemo.xcodeproj/project.pbxproj new file mode 100644 index 0000000..12f085e --- /dev/null +++ b/TXScrollLabelViewDemo/TXScrollLabelViewDemo.xcodeproj/project.pbxproj @@ -0,0 +1,562 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 973DB2411DB9FBED00DE9D77 /* TXScrollLabelView.m in Sources */ = {isa = PBXBuildFile; fileRef = 973DB23E1DB9FBED00DE9D77 /* TXScrollLabelView.m */; }; + 973DB2421DB9FBED00DE9D77 /* UIView+TXFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 973DB2401DB9FBED00DE9D77 /* UIView+TXFrame.m */; }; + 97886D991DB8E0AF00A0B326 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97886D981DB8E0AF00A0B326 /* main.m */; }; + 97886D9C1DB8E0AF00A0B326 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 97886D9B1DB8E0AF00A0B326 /* AppDelegate.m */; }; + 97886D9F1DB8E0AF00A0B326 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 97886D9E1DB8E0AF00A0B326 /* ViewController.m */; }; + 97886DA21DB8E0AF00A0B326 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97886DA01DB8E0AF00A0B326 /* Main.storyboard */; }; + 97886DA41DB8E0AF00A0B326 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97886DA31DB8E0AF00A0B326 /* Assets.xcassets */; }; + 97886DA71DB8E0AF00A0B326 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97886DA51DB8E0AF00A0B326 /* LaunchScreen.storyboard */; }; + 97886DB21DB8E0AF00A0B326 /* TXScrollLabelViewDemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 97886DB11DB8E0AF00A0B326 /* TXScrollLabelViewDemoTests.m */; }; + 97886DBD1DB8E0AF00A0B326 /* TXScrollLabelViewDemoUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 97886DBC1DB8E0AF00A0B326 /* TXScrollLabelViewDemoUITests.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 97886DAE1DB8E0AF00A0B326 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 97886D8C1DB8E0AF00A0B326 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 97886D931DB8E0AF00A0B326; + remoteInfo = TXScrollLabelViewDemo; + }; + 97886DB91DB8E0AF00A0B326 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 97886D8C1DB8E0AF00A0B326 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 97886D931DB8E0AF00A0B326; + remoteInfo = TXScrollLabelViewDemo; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 973DB23D1DB9FBED00DE9D77 /* TXScrollLabelView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TXScrollLabelView.h; sourceTree = ""; }; + 973DB23E1DB9FBED00DE9D77 /* TXScrollLabelView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXScrollLabelView.m; sourceTree = ""; }; + 973DB23F1DB9FBED00DE9D77 /* UIView+TXFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+TXFrame.h"; sourceTree = ""; }; + 973DB2401DB9FBED00DE9D77 /* UIView+TXFrame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+TXFrame.m"; sourceTree = ""; }; + 97886D941DB8E0AF00A0B326 /* TXScrollLabelViewDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TXScrollLabelViewDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97886D981DB8E0AF00A0B326 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97886D9A1DB8E0AF00A0B326 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 97886D9B1DB8E0AF00A0B326 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 97886D9D1DB8E0AF00A0B326 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + 97886D9E1DB8E0AF00A0B326 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + 97886DA11DB8E0AF00A0B326 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97886DA31DB8E0AF00A0B326 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97886DA61DB8E0AF00A0B326 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97886DA81DB8E0AF00A0B326 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 97886DAD1DB8E0AF00A0B326 /* TXScrollLabelViewDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TXScrollLabelViewDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 97886DB11DB8E0AF00A0B326 /* TXScrollLabelViewDemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TXScrollLabelViewDemoTests.m; sourceTree = ""; }; + 97886DB31DB8E0AF00A0B326 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 97886DB81DB8E0AF00A0B326 /* TXScrollLabelViewDemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TXScrollLabelViewDemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 97886DBC1DB8E0AF00A0B326 /* TXScrollLabelViewDemoUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TXScrollLabelViewDemoUITests.m; sourceTree = ""; }; + 97886DBE1DB8E0AF00A0B326 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97886D911DB8E0AF00A0B326 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97886DAA1DB8E0AF00A0B326 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97886DB51DB8E0AF00A0B326 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 973DB23C1DB9FBED00DE9D77 /* TXScrollLabelView */ = { + isa = PBXGroup; + children = ( + 973DB23D1DB9FBED00DE9D77 /* TXScrollLabelView.h */, + 973DB23E1DB9FBED00DE9D77 /* TXScrollLabelView.m */, + 973DB23F1DB9FBED00DE9D77 /* UIView+TXFrame.h */, + 973DB2401DB9FBED00DE9D77 /* UIView+TXFrame.m */, + ); + path = TXScrollLabelView; + sourceTree = ""; + }; + 97886D8B1DB8E0AF00A0B326 = { + isa = PBXGroup; + children = ( + 97886D961DB8E0AF00A0B326 /* TXScrollLabelViewDemo */, + 97886DB01DB8E0AF00A0B326 /* TXScrollLabelViewDemoTests */, + 97886DBB1DB8E0AF00A0B326 /* TXScrollLabelViewDemoUITests */, + 97886D951DB8E0AF00A0B326 /* Products */, + ); + sourceTree = ""; + }; + 97886D951DB8E0AF00A0B326 /* Products */ = { + isa = PBXGroup; + children = ( + 97886D941DB8E0AF00A0B326 /* TXScrollLabelViewDemo.app */, + 97886DAD1DB8E0AF00A0B326 /* TXScrollLabelViewDemoTests.xctest */, + 97886DB81DB8E0AF00A0B326 /* TXScrollLabelViewDemoUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 97886D961DB8E0AF00A0B326 /* TXScrollLabelViewDemo */ = { + isa = PBXGroup; + children = ( + 973DB23C1DB9FBED00DE9D77 /* TXScrollLabelView */, + 97886D9A1DB8E0AF00A0B326 /* AppDelegate.h */, + 97886D9B1DB8E0AF00A0B326 /* AppDelegate.m */, + 97886D9D1DB8E0AF00A0B326 /* ViewController.h */, + 97886D9E1DB8E0AF00A0B326 /* ViewController.m */, + 97886DA01DB8E0AF00A0B326 /* Main.storyboard */, + 97886DA31DB8E0AF00A0B326 /* Assets.xcassets */, + 97886DA51DB8E0AF00A0B326 /* LaunchScreen.storyboard */, + 97886DA81DB8E0AF00A0B326 /* Info.plist */, + 97886D971DB8E0AF00A0B326 /* Supporting Files */, + ); + path = TXScrollLabelViewDemo; + sourceTree = ""; + }; + 97886D971DB8E0AF00A0B326 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97886D981DB8E0AF00A0B326 /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 97886DB01DB8E0AF00A0B326 /* TXScrollLabelViewDemoTests */ = { + isa = PBXGroup; + children = ( + 97886DB11DB8E0AF00A0B326 /* TXScrollLabelViewDemoTests.m */, + 97886DB31DB8E0AF00A0B326 /* Info.plist */, + ); + path = TXScrollLabelViewDemoTests; + sourceTree = ""; + }; + 97886DBB1DB8E0AF00A0B326 /* TXScrollLabelViewDemoUITests */ = { + isa = PBXGroup; + children = ( + 97886DBC1DB8E0AF00A0B326 /* TXScrollLabelViewDemoUITests.m */, + 97886DBE1DB8E0AF00A0B326 /* Info.plist */, + ); + path = TXScrollLabelViewDemoUITests; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97886D931DB8E0AF00A0B326 /* TXScrollLabelViewDemo */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97886DC11DB8E0AF00A0B326 /* Build configuration list for PBXNativeTarget "TXScrollLabelViewDemo" */; + buildPhases = ( + 97886D901DB8E0AF00A0B326 /* Sources */, + 97886D911DB8E0AF00A0B326 /* Frameworks */, + 97886D921DB8E0AF00A0B326 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = TXScrollLabelViewDemo; + productName = TXScrollLabelViewDemo; + productReference = 97886D941DB8E0AF00A0B326 /* TXScrollLabelViewDemo.app */; + productType = "com.apple.product-type.application"; + }; + 97886DAC1DB8E0AF00A0B326 /* TXScrollLabelViewDemoTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97886DC41DB8E0AF00A0B326 /* Build configuration list for PBXNativeTarget "TXScrollLabelViewDemoTests" */; + buildPhases = ( + 97886DA91DB8E0AF00A0B326 /* Sources */, + 97886DAA1DB8E0AF00A0B326 /* Frameworks */, + 97886DAB1DB8E0AF00A0B326 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 97886DAF1DB8E0AF00A0B326 /* PBXTargetDependency */, + ); + name = TXScrollLabelViewDemoTests; + productName = TXScrollLabelViewDemoTests; + productReference = 97886DAD1DB8E0AF00A0B326 /* TXScrollLabelViewDemoTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 97886DB71DB8E0AF00A0B326 /* TXScrollLabelViewDemoUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97886DC71DB8E0AF00A0B326 /* Build configuration list for PBXNativeTarget "TXScrollLabelViewDemoUITests" */; + buildPhases = ( + 97886DB41DB8E0AF00A0B326 /* Sources */, + 97886DB51DB8E0AF00A0B326 /* Frameworks */, + 97886DB61DB8E0AF00A0B326 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 97886DBA1DB8E0AF00A0B326 /* PBXTargetDependency */, + ); + name = TXScrollLabelViewDemoUITests; + productName = TXScrollLabelViewDemoUITests; + productReference = 97886DB81DB8E0AF00A0B326 /* TXScrollLabelViewDemoUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97886D8C1DB8E0AF00A0B326 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0800; + ORGANIZATIONNAME = tingxins; + TargetAttributes = { + 97886D931DB8E0AF00A0B326 = { + CreatedOnToolsVersion = 8.0; + DevelopmentTeam = X37JS8D42G; + ProvisioningStyle = Automatic; + }; + 97886DAC1DB8E0AF00A0B326 = { + CreatedOnToolsVersion = 8.0; + DevelopmentTeam = X37JS8D42G; + ProvisioningStyle = Automatic; + TestTargetID = 97886D931DB8E0AF00A0B326; + }; + 97886DB71DB8E0AF00A0B326 = { + CreatedOnToolsVersion = 8.0; + DevelopmentTeam = X37JS8D42G; + ProvisioningStyle = Automatic; + TestTargetID = 97886D931DB8E0AF00A0B326; + }; + }; + }; + buildConfigurationList = 97886D8F1DB8E0AF00A0B326 /* Build configuration list for PBXProject "TXScrollLabelViewDemo" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97886D8B1DB8E0AF00A0B326; + productRefGroup = 97886D951DB8E0AF00A0B326 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97886D931DB8E0AF00A0B326 /* TXScrollLabelViewDemo */, + 97886DAC1DB8E0AF00A0B326 /* TXScrollLabelViewDemoTests */, + 97886DB71DB8E0AF00A0B326 /* TXScrollLabelViewDemoUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97886D921DB8E0AF00A0B326 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97886DA71DB8E0AF00A0B326 /* LaunchScreen.storyboard in Resources */, + 97886DA41DB8E0AF00A0B326 /* Assets.xcassets in Resources */, + 97886DA21DB8E0AF00A0B326 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97886DAB1DB8E0AF00A0B326 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97886DB61DB8E0AF00A0B326 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97886D901DB8E0AF00A0B326 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 973DB2421DB9FBED00DE9D77 /* UIView+TXFrame.m in Sources */, + 973DB2411DB9FBED00DE9D77 /* TXScrollLabelView.m in Sources */, + 97886D9F1DB8E0AF00A0B326 /* ViewController.m in Sources */, + 97886D9C1DB8E0AF00A0B326 /* AppDelegate.m in Sources */, + 97886D991DB8E0AF00A0B326 /* main.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97886DA91DB8E0AF00A0B326 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97886DB21DB8E0AF00A0B326 /* TXScrollLabelViewDemoTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97886DB41DB8E0AF00A0B326 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97886DBD1DB8E0AF00A0B326 /* TXScrollLabelViewDemoUITests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 97886DAF1DB8E0AF00A0B326 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 97886D931DB8E0AF00A0B326 /* TXScrollLabelViewDemo */; + targetProxy = 97886DAE1DB8E0AF00A0B326 /* PBXContainerItemProxy */; + }; + 97886DBA1DB8E0AF00A0B326 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 97886D931DB8E0AF00A0B326 /* TXScrollLabelViewDemo */; + targetProxy = 97886DB91DB8E0AF00A0B326 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 97886DA01DB8E0AF00A0B326 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97886DA11DB8E0AF00A0B326 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97886DA51DB8E0AF00A0B326 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97886DA61DB8E0AF00A0B326 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 97886DBF1DB8E0AF00A0B326 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVES = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 97886DC01DB8E0AF00A0B326 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVES = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97886DC21DB8E0AF00A0B326 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = X37JS8D42G; + INFOPLIST_FILE = TXScrollLabelViewDemo/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.tingxins.TXScrollLabelViewDemo; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 97886DC31DB8E0AF00A0B326 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = X37JS8D42G; + INFOPLIST_FILE = TXScrollLabelViewDemo/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.tingxins.TXScrollLabelViewDemo; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 97886DC51DB8E0AF00A0B326 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + DEVELOPMENT_TEAM = X37JS8D42G; + INFOPLIST_FILE = TXScrollLabelViewDemoTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.tingxins.TXScrollLabelViewDemoTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TXScrollLabelViewDemo.app/TXScrollLabelViewDemo"; + }; + name = Debug; + }; + 97886DC61DB8E0AF00A0B326 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + DEVELOPMENT_TEAM = X37JS8D42G; + INFOPLIST_FILE = TXScrollLabelViewDemoTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.tingxins.TXScrollLabelViewDemoTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TXScrollLabelViewDemo.app/TXScrollLabelViewDemo"; + }; + name = Release; + }; + 97886DC81DB8E0AF00A0B326 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEVELOPMENT_TEAM = X37JS8D42G; + INFOPLIST_FILE = TXScrollLabelViewDemoUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.tingxins.TXScrollLabelViewDemoUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_TARGET_NAME = TXScrollLabelViewDemo; + }; + name = Debug; + }; + 97886DC91DB8E0AF00A0B326 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEVELOPMENT_TEAM = X37JS8D42G; + INFOPLIST_FILE = TXScrollLabelViewDemoUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.tingxins.TXScrollLabelViewDemoUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_TARGET_NAME = TXScrollLabelViewDemo; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97886D8F1DB8E0AF00A0B326 /* Build configuration list for PBXProject "TXScrollLabelViewDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97886DBF1DB8E0AF00A0B326 /* Debug */, + 97886DC01DB8E0AF00A0B326 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97886DC11DB8E0AF00A0B326 /* Build configuration list for PBXNativeTarget "TXScrollLabelViewDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97886DC21DB8E0AF00A0B326 /* Debug */, + 97886DC31DB8E0AF00A0B326 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97886DC41DB8E0AF00A0B326 /* Build configuration list for PBXNativeTarget "TXScrollLabelViewDemoTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97886DC51DB8E0AF00A0B326 /* Debug */, + 97886DC61DB8E0AF00A0B326 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97886DC71DB8E0AF00A0B326 /* Build configuration list for PBXNativeTarget "TXScrollLabelViewDemoUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97886DC81DB8E0AF00A0B326 /* Debug */, + 97886DC91DB8E0AF00A0B326 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97886D8C1DB8E0AF00A0B326 /* Project object */; +} diff --git a/TXScrollLabelViewDemo/TXScrollLabelViewDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/TXScrollLabelViewDemo/TXScrollLabelViewDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..17d52d5 --- /dev/null +++ b/TXScrollLabelViewDemo/TXScrollLabelViewDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/TXScrollLabelViewDemo/TXScrollLabelViewDemo/AppDelegate.h b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/AppDelegate.h new file mode 100644 index 0000000..e0b3b13 --- /dev/null +++ b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/AppDelegate.h @@ -0,0 +1,17 @@ +// +// AppDelegate.h +// TXScrollLabelViewDemo +// +// Created by tingxins on 20/10/2016. +// Copyright © 2016 tingxins. All rights reserved. +// + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/TXScrollLabelViewDemo/TXScrollLabelViewDemo/AppDelegate.m b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/AppDelegate.m new file mode 100644 index 0000000..cd6e00c --- /dev/null +++ b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/AppDelegate.m @@ -0,0 +1,51 @@ +// +// AppDelegate.m +// TXScrollLabelViewDemo +// +// Created by tingxins on 20/10/2016. +// Copyright © 2016 tingxins. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + + +- (void)applicationWillResignActive:(UIApplication *)application { + // 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. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. +} + + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // 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. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // 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. +} + + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // 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. +} + + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + + +@end diff --git a/TXScrollLabelViewDemo/TXScrollLabelViewDemo/Assets.xcassets/AppIcon.appiconset/Contents.json b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b8236c6 --- /dev/null +++ b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,48 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/TXScrollLabelViewDemo/TXScrollLabelViewDemo/Base.lproj/LaunchScreen.storyboard b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..fdf3f97 --- /dev/null +++ b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TXScrollLabelViewDemo/TXScrollLabelViewDemo/Base.lproj/Main.storyboard b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/Base.lproj/Main.storyboard new file mode 100644 index 0000000..648bff5 --- /dev/null +++ b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/Base.lproj/Main.storyboard @@ -0,0 +1,1777 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TXScrollLabelViewDemo/TXScrollLabelViewDemo/Info.plist b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/Info.plist new file mode 100644 index 0000000..38e98af --- /dev/null +++ b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/Info.plist @@ -0,0 +1,38 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/TXScrollLabelViewDemo/TXScrollLabelViewDemo/TXScrollLabelView/TXScrollLabelView.h b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/TXScrollLabelView/TXScrollLabelView.h new file mode 100644 index 0000000..d7a0d4c --- /dev/null +++ b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/TXScrollLabelView/TXScrollLabelView.h @@ -0,0 +1,76 @@ +// +// TXScrollLabelView.h +// +// Created by tingxins on 2/23/16. +// Copyright © 2016 tingxins. All rights reserved. +// 滚动视图 + +#define TXScrollLabelViewDeprecated(instead) NS_DEPRECATED(2_0, 2_0, 2_0, 2_0, instead) + +#import +#import "UIView+TXFrame.h" + +@interface TXScrollLabelView : UIScrollView + +typedef NS_ENUM(NSInteger, TXScrollLabelViewType) { + TXScrollLabelViewTypeLeftRight = 0, + TXScrollLabelViewTypeUpDown, + TXScrollLabelViewTypeFlipRepeat, + TXScrollLabelViewTypeFlipNoRepeat +}; + +#pragma mark - Property +/** 滚动文字 */ +@property (copy, nonatomic) NSString *tx_scrollTitle; +/** 滚动类型 */ +@property (assign, nonatomic) TXScrollLabelViewType tx_scrollType; +/** 滚动速率 */ +@property (assign, nonatomic) NSTimeInterval tx_scrollVelocity; +/** 滚动显示范围 */ +@property (assign, nonatomic) CGRect tx_scrollContentSize; +/** 文本颜色 */ +@property (strong, nonatomic) UIColor *tx_scrollTitleColor; + +#pragma mark - Class Methods + +- (instancetype)initWithScrollTitle:(NSString *)scrollTitle + scrollType:(TXScrollLabelViewType)scrollType + scrollVelocity:(NSTimeInterval)scrollVelocity + options:(UIViewAnimationOptions)options; + ++ (instancetype)tx_setScrollTitle:(NSString *)scrollTitle; + ++ (instancetype)tx_setScrollTitle:(NSString *)scrollTitle + scrollType:(TXScrollLabelViewType)scrollType; + ++ (instancetype)tx_setScrollTitle:(NSString *)scrollTitle + scrollType:(TXScrollLabelViewType)scrollType + scrollVelocity:(NSTimeInterval)scrollVelocity; +/** + 类初始化方法 + @param scrollTitle 滚动文本 + @param scrollType 滚动类型 + @param scrollVelocity 滚动速率 + @param options Now, supports the type of TXScrollLabelViewTypeFlipNoRepeat only. + */ ++ (instancetype)tx_setScrollTitle:(NSString *)scrollTitle + scrollType:(TXScrollLabelViewType)scrollType + scrollVelocity:(NSTimeInterval)scrollVelocity + options:(UIViewAnimationOptions)options; + +#pragma mark - Operation Methods +/** + * 开始滚动 + */ +- (void) beginScrolling; +/** + * 停止滚动 + */ +- (void) endScrolling; + +/** + * 暂停滚动(暂不支持恢复) + */ +- (void) pauseScrolling; + +@end diff --git a/TXScrollLabelViewDemo/TXScrollLabelViewDemo/TXScrollLabelView/TXScrollLabelView.m b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/TXScrollLabelView/TXScrollLabelView.m new file mode 100644 index 0000000..9cf65ae --- /dev/null +++ b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/TXScrollLabelView/TXScrollLabelView.m @@ -0,0 +1,396 @@ +// +// TXScrollLabelView.m +// +// Created by tingxins on 2/23/16. +// Copyright © 2016 tingxins. All rights reserved. +// + +#define TXScrollLabelFont [UIFont systemFontOfSize:14] +#import "TXScrollLabelView.h" +#import + +static const NSInteger TXScrollDefaultTimeInterval = 2.0;//滚动默认时间 + +@interface NSTimer (TXTimerTarget) + ++ (NSTimer *)tx_scheduledTimerWithTimeInterval:(NSTimeInterval)interval repeat:(BOOL)yesOrNo block:(void(^)(NSTimer *timer))block; + +@end + + +@implementation NSTimer (TXTimerTarget) + ++ (NSTimer *)tx_scheduledTimerWithTimeInterval:(NSTimeInterval)interval repeat:(BOOL)yesOrNo block:(void (^)(NSTimer *))block{ + return [self scheduledTimerWithTimeInterval:interval target:self selector:@selector(startTimer:) userInfo:[block copy] repeats:yesOrNo]; +} + ++ (void)startTimer:(NSTimer *)timer { + void (^block)(NSTimer *timer) = timer.userInfo; + if (block) { + block(timer); + } +} + +@end + +@interface TXScrollLabelView () + +@property (assign, nonatomic) UIViewAnimationOptions options; + +@property (weak, nonatomic) UILabel *upLabel; + +@property (weak, nonatomic) UILabel *downLabel; +//定时器 +@property (strong, nonatomic) NSTimer *scrollTimer; +//文本行分割数组 +@property (strong, nonatomic) NSArray *scrollArray; + +@end + +@implementation TXScrollLabelView + +#pragma mark - init Methods + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + /** Default BgColor. */ + self.backgroundColor = [UIColor blackColor]; + + UILabel *upLabel = [[UILabel alloc]init]; + upLabel.numberOfLines = 0; + self.upLabel = upLabel; + self.upLabel.font = TXScrollLabelFont; + self.upLabel.textColor = [UIColor whiteColor]; + [self addSubview:upLabel]; + + UILabel *downLabel = [[UILabel alloc]init]; + downLabel.numberOfLines = 0; + self.downLabel = downLabel; + self.downLabel.font = TXScrollLabelFont; + self.downLabel.textColor = [UIColor whiteColor]; + [self addSubview:downLabel]; + + upLabel.lineBreakMode = NSLineBreakByWordWrapping; + downLabel.lineBreakMode = NSLineBreakByWordWrapping; + + upLabel.textAlignment = NSTextAlignmentCenter; + downLabel.textAlignment = NSTextAlignmentCenter; + self.scrollEnabled = NO; + } + return self; +} + +- (instancetype)initWithScrollTitle:(NSString *)scrollTitle + scrollType:(TXScrollLabelViewType)scrollType + scrollVelocity:(NSTimeInterval)scrollVelocity + options:(UIViewAnimationOptions)options { + if (self = [super init]) { + self.tx_scrollTitle = scrollTitle; + self.tx_scrollType = scrollType; + self.tx_scrollVelocity = scrollVelocity; + self.options = options; + } + return self; +} + ++ (instancetype)tx_setScrollTitle:(NSString *)scrollTitle { + + return [self tx_setScrollTitle:scrollTitle + scrollType:TXScrollLabelViewTypeLeftRight]; +} + ++ (instancetype)tx_setScrollTitle:(NSString *)scrollTitle + scrollType:(TXScrollLabelViewType)scrollType { + + return [self tx_setScrollTitle:scrollTitle + scrollType:scrollType + scrollVelocity:TXScrollDefaultTimeInterval]; +} + ++ (instancetype)tx_setScrollTitle:(NSString *)scrollTitle + scrollType:(TXScrollLabelViewType)scrollType + scrollVelocity:(NSTimeInterval)scrollVelocity { + + return [self tx_setScrollTitle:scrollTitle + scrollType:scrollType + scrollVelocity:scrollVelocity + options:UIViewAnimationOptionCurveEaseInOut]; +} + ++ (instancetype)tx_setScrollTitle:(NSString *)scrollTitle + scrollType:(TXScrollLabelViewType)scrollType + scrollVelocity:(NSTimeInterval)scrollVelocity + options:(UIViewAnimationOptions)options { + + return [[self alloc] initWithScrollTitle:scrollTitle + scrollType:scrollType + scrollVelocity:scrollVelocity + options:options]; +} + +#pragma mark - Getter & Setter Methods + +- (UIViewAnimationOptions)options { + if (_options) return _options; + return _options = UIViewAnimationOptionCurveEaseInOut; +} + +- (NSArray *)scrollArray { + if (_scrollArray) return _scrollArray; + return _scrollArray = [self getSeparatedLinesFromLabel]; +} + +- (void)setTx_scrollContentSize:(CGRect)tx_scrollContentSize{ + _tx_scrollContentSize = tx_scrollContentSize; + self.frame = _tx_scrollContentSize; + [self setupSubviewsLayout]; +} + +- (void)setTx_scrollTitleColor:(UIColor *)tx_scrollTitleColor { + _tx_scrollTitleColor = tx_scrollTitleColor; + self.upLabel.textColor = _tx_scrollTitleColor; + self.downLabel.textColor = _tx_scrollTitleColor; +} + +#pragma mark - SubviewsLayout Methods +//,,, +- (void)setupSubviewsLayout { + switch (_tx_scrollType) { + case TXScrollLabelViewTypeLeftRight: + { + CGSize scrollLabelS = [_tx_scrollTitle boundingRectWithSize:CGSizeMake(0, self.tx_height) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: TXScrollLabelFont} context:nil].size; + self.upLabel.frame = CGRectMake(10, 0, scrollLabelS.width, self.tx_height); + self.upLabel.text = _tx_scrollTitle; + + self.downLabel.frame = CGRectMake(CGRectGetMaxX(self.upLabel.frame) + 20, 0, scrollLabelS.width, self.tx_height); + self.downLabel.text = _tx_scrollTitle; + self.contentSize = CGSizeMake(scrollLabelS.width * 2 + 40, scrollLabelS.height); + self.bounds = CGRectMake(0, 0, MIN(self.tx_width, scrollLabelS.width), self.tx_height); + } + break; + + case TXScrollLabelViewTypeUpDown: + { + + CGSize scrollLabelS = [_tx_scrollTitle boundingRectWithSize:CGSizeMake(self.tx_width, 0) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: TXScrollLabelFont} context:nil].size; + CGFloat scrollLabelH = MAX(scrollLabelS.height, self.tx_height); + self.upLabel.frame = CGRectMake(0, 0, scrollLabelS.width, scrollLabelH); + self.upLabel.text = _tx_scrollTitle; + + self.downLabel.frame = CGRectMake(0, CGRectGetMaxY(self.upLabel.frame), scrollLabelS.width, scrollLabelH); + self.downLabel.text = _tx_scrollTitle; + self.contentSize = CGSizeMake(scrollLabelS.width, scrollLabelH * 2); + self.bounds = CGRectMake(0, 0, MIN(self.tx_width, scrollLabelS.width), self.tx_height); + } + break; + + case TXScrollLabelViewTypeFlipRepeat: + { + CGSize scrollLabelS = [_tx_scrollTitle boundingRectWithSize:CGSizeMake(self.tx_width, self.tx_height) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: TXScrollLabelFont} context:nil].size; + self.upLabel.frame = CGRectMake(0, 0, scrollLabelS.width, self.tx_height); + self.upLabel.text = _tx_scrollTitle; + + self.downLabel.frame = CGRectMake(0, CGRectGetMaxY(self.upLabel.frame), scrollLabelS.width, self.tx_height);; + self.downLabel.text = _tx_scrollTitle; + self.contentSize = CGSizeMake(scrollLabelS.width, scrollLabelS.height * 2); + self.bounds = CGRectMake(0, 0, MIN(self.tx_width, scrollLabelS.width), self.tx_height); + } + break; + + + case TXScrollLabelViewTypeFlipNoRepeat: + { + NSMutableParagraphStyle *paraStyle = [[NSMutableParagraphStyle alloc]init]; + paraStyle.lineSpacing = 10; + NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:_tx_scrollTitle]; + [attributedStr addAttributes:@{NSFontAttributeName:TXScrollLabelFont, NSParagraphStyleAttributeName:paraStyle} range:NSMakeRange(0, attributedStr.length)]; + + CGSize scrollLabelS = [attributedStr boundingRectWithSize:CGSizeMake(self.tx_width, 0) options:NSStringDrawingUsesLineFragmentOrigin context:nil].size; + + self.upLabel.frame = CGRectMake(0, 0, scrollLabelS.width, self.tx_height); + self.downLabel.frame = CGRectMake(0, CGRectGetMaxY(self.upLabel.frame), scrollLabelS.width, self.tx_height); + + CGFloat width = scrollLabelS.width; + if (!self.tx_width) { + self.tx_width = width; + } + self.contentSize = CGSizeMake(self.tx_width, scrollLabelS.height * 2); + self.bounds = CGRectMake(0, 0, MIN(self.tx_width, scrollLabelS.width), self.tx_height); + } + break; + + default: + break; + } +} + +#pragma mark - Scrolling Operation Methods + +- (void)beginScrolling { + [self endScrolling]; + + __weak typeof(self) weakSelf = self; + self.scrollTimer = [NSTimer tx_scheduledTimerWithTimeInterval:0.1 repeat:YES block:^(NSTimer *timer) { + TXScrollLabelView *strongSelf = weakSelf; + if (strongSelf) { + [self updateScrolling]; + } + }]; + + [[NSRunLoop mainRunLoop] addTimer:self.scrollTimer forMode:NSRunLoopCommonModes]; +} + +- (void)endScrolling { + [self.scrollTimer invalidate]; + self.scrollTimer = nil; +} + +- (void)pauseScrolling { + [self.scrollTimer invalidate]; + self.scrollTimer = nil; +} + +#pragma mark - Scrolling Animation Methods + +- (void)updateScrolling { + __weak typeof(self) weakSelf = self; + switch (self.tx_scrollType) { + case TXScrollLabelViewTypeLeftRight: + { + if (self.contentSize.width * 0.5 == self.contentOffset.x || self.contentOffset.x > self.contentSize.width * 0.5) { + [self endScrolling]; + self.contentOffset = CGPointMake(2, 0);//x增加偏移量,防止卡顿 + [self beginScrolling]; + return; + } + self.contentOffset = CGPointMake(self.contentOffset.x + 1, self.contentOffset.y); + + } + break; + + case TXScrollLabelViewTypeUpDown: + { + if (self.contentOffset.y > self.upLabel.frame.size.height) { + [self endScrolling]; + self.contentOffset = CGPointMake(0, 2);//y增加偏移量,防止卡顿 + [self beginScrolling]; + return; + } + self.contentOffset = CGPointMake(self.contentOffset.x, self.contentOffset.y + 1); + + } + break; + + case TXScrollLabelViewTypeFlipRepeat: + { + + [self endScrolling]; + + NSTimeInterval velocity = self.tx_scrollVelocity ? self.tx_scrollVelocity : 2; + + self.scrollTimer = [NSTimer tx_scheduledTimerWithTimeInterval:velocity repeat:YES block:^(NSTimer *timer) { + TXScrollLabelView *strongSelf = weakSelf; + if (strongSelf) { + [self updateScrolling]; + } + }]; + + [[NSRunLoop mainRunLoop] addTimer:self.scrollTimer forMode:NSRunLoopCommonModes]; + + [self flipAnimationWithDelay:velocity]; + } + break; + + case TXScrollLabelViewTypeFlipNoRepeat: + { + + [self endScrolling]; + + NSTimeInterval velocity = self.tx_scrollVelocity ? self.tx_scrollVelocity : 2; + + self.scrollTimer = [NSTimer tx_scheduledTimerWithTimeInterval:velocity repeat:YES block:^(NSTimer *timer) { + TXScrollLabelView *strongSelf = weakSelf; + if (strongSelf) { + [self updateScrolling]; + } + }]; + + [[NSRunLoop mainRunLoop] addTimer:self.scrollTimer forMode:NSRunLoopCommonModes]; + + [self flipNoCleAnimationWithDelay:velocity]; + } + break; + + default: + break; + } +} + +- (void)flipAnimationWithDelay:(NSTimeInterval)delay { + [UIView transitionWithView:self.upLabel duration:delay * 0.5 options:self.options animations:^{ + self.upLabel.tx_bottom = 0; + [UIView transitionWithView:self.upLabel duration:delay * 0.5 options:self.options animations:^{ + self.downLabel.tx_y = 0; + } completion:^(BOOL finished) { + self.upLabel.tx_y = self.tx_height; + UILabel *tempLabel = self.upLabel; + self.upLabel = self.downLabel; + self.downLabel = tempLabel; + }]; + } completion:nil]; +} + +- (void)flipNoCleAnimationWithDelay:(NSTimeInterval)delay { + static int count = 0; + self.upLabel.text = self.scrollArray[count]; + count ++; + if (count == self.scrollArray.count) count = 0; + self.downLabel.text = self.scrollArray[count]; + [self flipAnimationWithDelay:delay]; +} + +#pragma mark - 文本行分割 + +-(NSArray *)getSeparatedLinesFromLabel { + + NSString *text = _tx_scrollTitle; + UIFont *font = [UIFont systemFontOfSize:15]; + + CTFontRef myFont = CTFontCreateWithName((__bridge CFStringRef)([font fontName]), [font pointSize], NULL); + + NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] initWithString:text]; + + [attStr addAttribute:(NSString *)kCTFontAttributeName value:(__bridge id)myFont range:NSMakeRange(0, attStr.length)]; + + CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)attStr); + + CGMutablePathRef path = CGPathCreateMutable(); + + CGPathAddRect(path, NULL, CGRectMake(0,0,self.tx_width,100000)); + + CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, NULL); + + NSArray *lines = (__bridge NSArray *)CTFrameGetLines(frame); + + NSMutableArray *linesArray = [[NSMutableArray alloc]init]; + + for (id line in lines) { + + CTLineRef lineRef = (__bridge CTLineRef )line; + + CFRange lineRange = CTLineGetStringRange(lineRef); + + NSRange range = NSMakeRange(lineRange.location, lineRange.length); + + NSString *lineString = [text substringWithRange:range]; + + [linesArray addObject:lineString]; + } + return (NSArray *)linesArray; +} + +- (void)dealloc { + [self endScrolling]; +} + +@end diff --git a/TXScrollLabelViewDemo/TXScrollLabelViewDemo/TXScrollLabelView/UIView+TXFrame.h b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/TXScrollLabelView/UIView+TXFrame.h new file mode 100644 index 0000000..4b60622 --- /dev/null +++ b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/TXScrollLabelView/UIView+TXFrame.h @@ -0,0 +1,32 @@ +// +// UIView+TXFrame.h +// TXSwipeTableViewTest +// +// Created by tingxins on 9/1/16. +// Copyright © 2016 tingxins. All rights reserved. +// + +#import + +@interface UIView (TXFrame) +/** 设置x值 */ +@property (assign, nonatomic) CGFloat tx_x; +/** 设置y值 */ +@property (assign, nonatomic) CGFloat tx_y; +/** 设置width */ +@property (assign, nonatomic) CGFloat tx_width; +/** 设置height */ +@property (assign, nonatomic) CGFloat tx_height; +/** 设置size */ +@property (assign, nonatomic) CGSize tx_size; +/** 设置origin */ +@property (assign, nonatomic) CGPoint tx_origin; +/** 设置center */ +@property (assign, nonatomic) CGPoint tx_center; +/** 设置center.x */ +@property (assign, nonatomic) CGFloat tx_centerX; +/** 设置center.y */ +@property (assign, nonatomic) CGFloat tx_centerY; +/** 设置bottom */ +@property (assign, nonatomic) CGFloat tx_bottom; +@end diff --git a/TXScrollLabelViewDemo/TXScrollLabelViewDemo/TXScrollLabelView/UIView+TXFrame.m b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/TXScrollLabelView/UIView+TXFrame.m new file mode 100644 index 0000000..a6cde8c --- /dev/null +++ b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/TXScrollLabelView/UIView+TXFrame.m @@ -0,0 +1,111 @@ +// +// UIView+TXFrame.m +// TXSwipeTableViewTest +// +// Created by tingxins on 9/1/16. +// Copyright © 2016 tingxins. All rights reserved. +// + +#import "UIView+TXFrame.h" + +@implementation UIView (TXFrame) + +- (CGFloat)tx_x { + return self.frame.origin.x; +} + +- (void)setTx_x:(CGFloat)tx_x { + CGRect frame = self.frame; + frame.origin.x = tx_x; + self.frame = frame; +} + +- (CGFloat)tx_y { + return self.frame.origin.y; +} + +- (void)setTx_y:(CGFloat)tx_y { + CGRect frame = self.frame; + frame.origin.y = tx_y; + self.frame = frame; +} + +- (CGFloat)tx_width { + return self.frame.size.width; +} + +- (void)setTx_width:(CGFloat)tx_width { + CGRect frame = self.frame; + frame.size.width = tx_width; + self.frame = frame; +} + +- (CGFloat)tx_height { + return self.frame.size.height; +} + +- (void)setTx_height:(CGFloat)tx_height { + CGRect frame = self.frame; + frame.size.height = tx_height; + self.frame = frame; +} + +- (CGSize)tx_size { + return self.frame.size; +} + +- (void)setTx_size:(CGSize)tx_size { + CGRect frame = self.frame; + frame.size = tx_size; + self.frame = frame; +} + +- (CGPoint)tx_origin { + return self.frame.origin; +} + +- (void)setTx_origin:(CGPoint)tx_origin { + CGRect frame = self.frame; + frame.origin = tx_origin; + self.frame = frame; +} + +- (CGPoint)tx_center { + return self.center; +} + +- (void)setTx_center:(CGPoint)tx_center { + self.center = tx_center; +} + +- (CGFloat)tx_centerX { + return self.center.x; +} + +- (void)setTx_centerX:(CGFloat)tx_centerX { + CGPoint center = self.center; + center.x = tx_centerX; + self.center = center; +} + +- (CGFloat)tx_centerY { + return self.center.y; +} + +- (void)setTx_centerY:(CGFloat)tx_centerY { + CGPoint center = self.center; + center.y = tx_centerY; + self.center = center; +} + +- (CGFloat)tx_bottom { + return CGRectGetMaxY(self.frame); +} + +- (void)setTx_bottom:(CGFloat)tx_bottom { + CGRect frame = self.frame; + frame.origin.y = tx_bottom - frame.size.height; + self.frame = frame; +} + +@end diff --git a/TXScrollLabelViewDemo/TXScrollLabelViewDemo/ViewController.h b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/ViewController.h new file mode 100644 index 0000000..48e7d01 --- /dev/null +++ b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/ViewController.h @@ -0,0 +1,15 @@ +// +// ViewController.h +// TXScrollLabelViewDemo +// +// Created by tingxins on 20/10/2016. +// Copyright © 2016 tingxins. All rights reserved. +// + +#import + +@interface ViewController : UIViewController + + +@end + diff --git a/TXScrollLabelViewDemo/TXScrollLabelViewDemo/ViewController.m b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/ViewController.m new file mode 100644 index 0000000..1270b43 --- /dev/null +++ b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/ViewController.m @@ -0,0 +1,52 @@ +// +// ViewController.m +// TXScrollLabelViewDemo +// +// Created by tingxins on 20/10/2016. +// Copyright © 2016 tingxins. All rights reserved. +// + +#import "ViewController.h" +#import "TXScrollLabelView.h" + +@interface ViewController () + +@property (weak, nonatomic) TXScrollLabelView *scrollLabelView; + +@end + +@implementation ViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + [self setViewInfos]; + + [self setSubviews]; + +} + +- (void)setViewInfos { + self.navigationController.navigationBar.translucent = NO; +} + +- (void)setSubviews { + + for (int options = 0; options < 4; ++ options) { + NSString *scrollTitle = @"If you don't control the image server you're using, you may not be able to change the URL when its content is updated. This is the case for Facebook avatar URLs for instance. In such case, you may use the SDWebImageRefreshCached flag. This will slightly degrade the performance but will respect the HTTP caching control headers"; + //options 是 TXScrollLabelViewType 枚举, 此处为了方便举例 + TXScrollLabelView *scrollLabelView = [TXScrollLabelView tx_setScrollTitle:scrollTitle scrollType:options scrollVelocity:2.0 options:UIViewAnimationOptionTransitionFlipFromTop]; + //布局 + scrollLabelView.tx_scrollContentSize = CGRectMake(50, 100 * (options + 0.7), 250, 30); + scrollLabelView.tx_centerX = [UIScreen mainScreen].bounds.size.width * 0.5; + //偏好设置 + scrollLabelView.backgroundColor = [UIColor blackColor]; + scrollLabelView.layer.cornerRadius = 5; + [self.view addSubview:scrollLabelView]; + + [scrollLabelView beginScrolling]; + self.scrollLabelView = scrollLabelView; + } +} + +@end diff --git a/TXScrollLabelViewDemo/TXScrollLabelViewDemo/main.m b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/main.m new file mode 100644 index 0000000..984497b --- /dev/null +++ b/TXScrollLabelViewDemo/TXScrollLabelViewDemo/main.m @@ -0,0 +1,16 @@ +// +// main.m +// TXScrollLabelViewDemo +// +// Created by tingxins on 20/10/2016. +// Copyright © 2016 tingxins. All rights reserved. +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/TXScrollLabelViewDemo/TXScrollLabelViewDemoTests/Info.plist b/TXScrollLabelViewDemo/TXScrollLabelViewDemoTests/Info.plist new file mode 100644 index 0000000..6c6c23c --- /dev/null +++ b/TXScrollLabelViewDemo/TXScrollLabelViewDemoTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/TXScrollLabelViewDemo/TXScrollLabelViewDemoTests/TXScrollLabelViewDemoTests.m b/TXScrollLabelViewDemo/TXScrollLabelViewDemoTests/TXScrollLabelViewDemoTests.m new file mode 100644 index 0000000..c5da428 --- /dev/null +++ b/TXScrollLabelViewDemo/TXScrollLabelViewDemoTests/TXScrollLabelViewDemoTests.m @@ -0,0 +1,39 @@ +// +// TXScrollLabelViewDemoTests.m +// TXScrollLabelViewDemoTests +// +// Created by tingxins on 20/10/2016. +// Copyright © 2016 tingxins. All rights reserved. +// + +#import + +@interface TXScrollLabelViewDemoTests : XCTestCase + +@end + +@implementation TXScrollLabelViewDemoTests + +- (void)setUp { + [super setUp]; + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testExample { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. +} + +- (void)testPerformanceExample { + // This is an example of a performance test case. + [self measureBlock:^{ + // Put the code you want to measure the time of here. + }]; +} + +@end diff --git a/TXScrollLabelViewDemo/TXScrollLabelViewDemoUITests/Info.plist b/TXScrollLabelViewDemo/TXScrollLabelViewDemoUITests/Info.plist new file mode 100644 index 0000000..6c6c23c --- /dev/null +++ b/TXScrollLabelViewDemo/TXScrollLabelViewDemoUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/TXScrollLabelViewDemo/TXScrollLabelViewDemoUITests/TXScrollLabelViewDemoUITests.m b/TXScrollLabelViewDemo/TXScrollLabelViewDemoUITests/TXScrollLabelViewDemoUITests.m new file mode 100644 index 0000000..9e0b053 --- /dev/null +++ b/TXScrollLabelViewDemo/TXScrollLabelViewDemoUITests/TXScrollLabelViewDemoUITests.m @@ -0,0 +1,40 @@ +// +// TXScrollLabelViewDemoUITests.m +// TXScrollLabelViewDemoUITests +// +// Created by tingxins on 20/10/2016. +// Copyright © 2016 tingxins. All rights reserved. +// + +#import + +@interface TXScrollLabelViewDemoUITests : XCTestCase + +@end + +@implementation TXScrollLabelViewDemoUITests + +- (void)setUp { + [super setUp]; + + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + self.continueAfterFailure = NO; + // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. + [[[XCUIApplication alloc] init] launch]; + + // 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. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testExample { + // Use recording to get started writing UI tests. + // Use XCTAssert and related functions to verify your tests produce the correct results. +} + +@end