最近閒來無事,做了一個跑馬燈的效果,感覺效果還湊合,故和大家分享一下。
至於為什麼說一句話,看一下我在ViewController中 初始化跑馬燈的Demo:
1 WQLPaoMaView *paoma = [[WQLPaoMaView alloc]initWithFrame:CGRectMake(0, 100, self.view.frame.size.width, 50) withTitle:@'全場賣兩塊,買啥都兩塊,兩塊錢,你買不了吃虧,兩塊錢,你買不了上當,真正的物有所值。拿啥啥便宜 買啥啥不貴,都兩塊,買啥都兩塊,全場賣兩塊,隨便挑,隨便選,都兩塊~~ ']; 2 3 [self.view addSubview:paoma];
你只需要在初始化視圖時傳入視圖的frame、要顯示的文本即可實現跑馬燈的效果了。
然後看一下效果圖:
可以點擊停止按鈕,讓文本暫停滾動。點擊開始按鈕,讓文本繼續滾動。
在ViewController中需要做的事情很少,那麼我們把重點放在自定義的視圖中。
自定義的視圖
WQLPaoMaView.h文件中:
1 #import <UIKit/UIKit.h> 2 3 @interface WQLPaoMaView : UIView 4 5 - (instancetype)initWithFrame:(CGRect)frame withTitle:(NSString *)title; 6 7 - (void)start; 8 9 - (void)stop; 10 11 @end
WQLPaoMaView.m文件:
1 - (instancetype)initWithFrame:(CGRect)frame withTitle:(NSString *)title 2 { 3 self = [super initWithFrame:frame]; 4 5 if (self) { 6 7 CGFloat viewHeight = frame.size.height; 8 labelHeight = viewHeight; 9 10 //循環的時間這裡取的是4 此數越大速度越快 11 time = title.length/4; 12 13 UILabel *myLable = [[UILabel alloc]init]; 14 myLable.text = title; 15 myLable.font = [UIFont systemFontOfSize:16.0f]; 16 myLable.backgroundColor = [UIColor orangeColor]; 17 18 //計算文本的寬度 19 CGFloat calcuWidth = [self widthForTextString:title height:labelHeight fontSize:16.0f]; 20 21 //這兩個frame很重要 分別記錄的是左右兩個label的frame 而且後面也會需要到這兩個frame 22 currentFrame = CGRectMake(0, 0, calcuWidth, labelHeight); 23 behindFrame = CGRectMake(currentFrame.origin.x+currentFrame.size.width, 0, calcuWidth, labelHeight); 24 25 myLable.frame = currentFrame; 26 [self addSubview:myLable]; 27 28 labelArray = [NSMutableArray arrayWithObject:myLable]; 29 30 //如果文本的寬度大於視圖的寬度才開始跑 31 if (calcuWidth>frame.size.width) { 32 UILabel *behindLabel = [[UILabel alloc]init]; 33 behindLabel.frame = behindFrame; 34 behindLabel.text = title; 35 behindLabel.font = [UIFont systemFontOfSize:16.0f]; 36 behindLabel.backgroundColor = [UIColor orangeColor]; 37 [labelArray addObject:behindLabel]; 38 [self addSubview:behindLabel]; 39 [self doAnimation]; 40 } 41 } 42 return self; 43 } 44 45 - (void)doAnimation 46 { 47 //UIViewAnimationOptionCurveLinear是為了讓lable做勻速動畫 48 [UIView animateWithDuration:time delay:0 options:UIViewAnimationOptionCurveLinear animations:^{ 49 50 //取到兩個label 51 UILabel *lableOne = labelArray[0]; 52 UILabel *lableTwo = labelArray[1]; 53 54 //讓兩個label向左平移 55 lableOne.transform = CGAffineTransformMakeTranslation(-currentFrame.size.width, 0); 56 lableTwo.transform = CGAffineTransformMakeTranslation(-currentFrame.size.width, 0); 57 58 } completion:^(BOOL finished) { 59 //兩個label水平相鄰擺放 內容一樣 label1為初始時展示的 label2位於界面的右側,未顯示出來 60 //當完成動畫時,即第一個label在界面中消失,第二個label位於第一個label的起始位置時,把第一個label放置到第二個label的初始位置 61 UILabel *lableOne = labelArray[0]; 62 lableOne.transform = CGAffineTransformIdentity; 63 lableOne.frame = behindFrame; 64 65 UILabel *lableTwo = labelArray[1]; 66 lableTwo.transform = CGAffineTransformIdentity; 67 lableTwo.frame = currentFrame; 68 69 //在數組中將第一個label放置到右側,第二個label放置到左側(因為此時展示的就是labelTwo) 70 [labelArray replaceObjectAtIndex:1 withObject:lableOne]; 71 [labelArray replaceObjectAtIndex:0 withObject:lableTwo]; 72 73 //遞歸調用 74 [self doAnimation]; 75 }]; 76 }
其實跑馬燈的核心思想比較好理解,就是創建兩個label循環展示。
此外,比較關鍵的另外兩個方法就是跑馬燈的開始與結束:
1 - (void)start 2 { 3 UILabel *lableOne = labelArray[0]; 4 [self resumeLayer:lableOne.layer]; 5 6 UILabel *lableTwo = labelArray[1]; 7 [self resumeLayer:lableTwo.layer]; 8 9 isStop = NO; 10 11 } 12 13 - (void)stop 14 { 15 UILabel *lableOne = labelArray[0]; 16 [self pauseLayer:lableOne.layer]; 17 18 UILabel *lableTwo = labelArray[1]; 19 [self pauseLayer:lableTwo.layer]; 20 21 isStop = YES; 22 } 23 24 //暫停動畫 25 - (void)pauseLayer:(CALayer*)layer 26 { 27 CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil]; 28 29 layer.speed = 0; 30 31 layer.timeOffset = pausedTime; 32 } 33 34 //恢復動畫 35 - (void)resumeLayer:(CALayer*)layer 36 { 37 //當你是停止狀態時,則恢復 38 if (isStop) { 39 40 CFTimeInterval pauseTime = [layer timeOffset]; 41 42 layer.speed = 1.0; 43 44 layer.timeOffset = 0.0; 45 46 layer.beginTime = 0.0; 47 48 CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil]-pauseTime; 49 50 layer.beginTime = timeSincePause; 51 } 52 53 }
這樣就搭建好了整個自定義跑馬燈視圖。
動畫的暫停與開始的實質就是:使用動畫,讓label滾動,在點擊開始時,讓動畫開始。點擊結束時,讓動畫暫停。
感興趣的小伙伴可以查看完整Demo(附有注釋):https://github.com/Coolll/WQLPaoMaView
歡迎大家提出各種建議和意見,探討才能成長。