iOS實(shí)現(xiàn)滾動(dòng)字幕的動(dòng)畫特效
效果圖
開始上代碼
滾動(dòng)字幕的原理是用timer定時(shí)器間隔一定的時(shí)間來驅(qū)動(dòng)scrollView
上的內(nèi)容偏移,來實(shí)現(xiàn)滾動(dòng)的效果,原理比較簡單,關(guān)鍵是有些細(xì)節(jié)需要處理好,實(shí)現(xiàn)流暢效果的同時(shí)要考慮到性能優(yōu)化
這里是.h文件的接口方法及屬性,可適應(yīng)大部分自定義場(chǎng)景
/*初始化*/ -(instancetype)initWithFrame:(CGRect)frame textArray:(NSArray *)textArray colorArray:(NSArray *)textColorArray; //滾動(dòng)字幕數(shù)組 @property(nonatomic,strong) NSArray<NSString *> *textArray; //字幕顏色數(shù)組 @property(nonatomic,strong) NSArray<UIColor *> *textColorArray; //字幕背景顏色 @property(nonatomic,strong) UIColor *backgroundColorOfCanvas; //標(biāo)簽背景圖片 @property(nonatomic,strong) UIImage *backgroundImageOfCanvas; //字體大小 @property(nonatomic,assign) CGFloat fontOfSize; //定時(shí)器 @property(nonatomic,strong) NSTimer *timer;
實(shí)現(xiàn)滾動(dòng)字幕的思路和無限輪播圖相似,這里用了一點(diǎn)小技巧即可實(shí)現(xiàn)字幕的收尾連續(xù)相接:將同樣的字幕內(nèi)容復(fù)制一份拼接到后面就可以了,當(dāng)字幕的scrollView
滾動(dòng)到復(fù)制的那份內(nèi)容開頭時(shí),將contentOffset
偏移量設(shè)置到原始內(nèi)容的開頭,這樣就可以實(shí)現(xiàn)無縫的連續(xù)循環(huán)滾動(dòng)了
#pragma mark - 創(chuàng)建scrollView內(nèi)容 -(void)createContentOfScrollView{ //創(chuàng)建contentView self.contentSize=CGSizeMake(0, self.bounds.size.height); //偏移量初值設(shè)為0 self.contentOffset=CGPointMake(0, 0); //關(guān)閉指示條 self.showsHorizontalScrollIndicator=NO; //創(chuàng)建label CGFloat labelY=0; CGFloat labelW=200; CGFloat labelH=self.bounds.size.height; //添加兩次一樣的內(nèi)容,無限循環(huán)使用 for (int j=0; j<2;j++ ) { for (int i=0; i<self.textArray.count; i++) { UILabel *textLabel=[[UILabel alloc] initWithFrame:CGRectMake(self.contentSize.width, labelY, labelW, labelH)]; //******標(biāo)簽背景****** UIImageView *labelBackGroundView=[[UIImageView alloc] initWithFrame:textLabel.frame]; //標(biāo)簽背景圖片 labelBackGroundView.image=self.backgroundImageOfCanvas; //*****label文字****** if (i<self.textArray.count) { textLabel.text=self.textArray[i]; }else{ textLabel.text=@"----"; } //label文字顏色(判斷文字顏色數(shù)組是否存有對(duì)應(yīng)的顏色,沒有則使用默認(rèn)顏色) if (i<self.textColorArray.count) { textLabel.textColor=self.textColorArray[i]; }else{ //默認(rèn)顏色 textLabel.textColor=[UIColor blackColor]; } //******字體大小******** textLabel.font=[UIFont systemFontOfSize:self.fontOfSize]; //label標(biāo)簽tag值 textLabel.tag=LABEL_TAG_INIT + i + 100 * j; //每創(chuàng)建一個(gè)label在contenSize上加上一個(gè)label的寬度 self.contentSize=CGSizeMake(self.contentSize.width+labelW, self.bounds.size.height); [self addSubview:labelBackGroundView]; [self addSubview:textLabel]; } } }
這里注意定時(shí)器timer
的使用,要將timer
加入到runloop
里,注意是CommonModes
,如果用defaultModes
的話就會(huì)出現(xiàn)卡頓(與滑動(dòng)等事件處于同一runLoop
,系統(tǒng)會(huì)優(yōu)先響應(yīng)滑動(dòng))
小tips:定時(shí)器是可以暫停的
NSTimer
系統(tǒng)是沒有提供暫停的方法的,方法列表中只提供了-fire
(啟動(dòng)) 和 -invalidate
(廢除)兩個(gè)方法,invalidate
后是完全廢除不可再重啟
但是這里有個(gè)@property (copy) NSDate *fireDate
的屬性,我們可以借助這個(gè)屬性來實(shí)現(xiàn)定時(shí)器的暫停和重啟
//立即啟動(dòng)定時(shí)器 [timer setFireDate:[NSDate date]]; //暫停定時(shí)器 [timer setFireDate:[NSDate distantFuture]];
是不是有種很奇妙的感覺,這里利用定時(shí)器的啟動(dòng)時(shí)間屬性巧妙的達(dá)到了暫停和重啟的目的
//************自動(dòng)滾動(dòng)timer************ NSTimer *timer=[NSTimer scheduledTimerWithTimeInterval:SCROLL_TIME_INTERVAL target:self selector:@selector(autoScroll) userInfo:nil repeats:YES]; [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; //立即啟動(dòng)定時(shí)器 [timer setFireDate:[NSDate date]]; self.timer=timer;
這里是定時(shí)器驅(qū)動(dòng)scrollView
滾動(dòng)的方法
這里注意了如果要達(dá)到字幕連續(xù)滾動(dòng)不斷幀的效果的話,timer
調(diào)用需要非常頻繁(1秒調(diào)用10次以上),此時(shí)再看看CPU使用率.瞬間飆升了20%左右,雖然還在能接受的范圍,但在這種小地方耗費(fèi)CPU顯然不劃算
解決方法:給個(gè)動(dòng)畫過渡就好了嘛,UIView animateWithDuration
輕松應(yīng)付,過渡很流暢,世界也瞬間安靜了。
后遺癥:用動(dòng)畫過渡唯一的問題就是,控制器跳轉(zhuǎn)后再回來的話,動(dòng)畫會(huì)直接結(jié)束跳到尾幀,細(xì)心的用戶會(huì)發(fā)覺這奇怪的地方,這就只有在性能和效果之間調(diào)和一下取最優(yōu)解了
//滾動(dòng)時(shí)間間隔 #define SCROLL_TIME_INTERVAL 3 //每次滾動(dòng)距離 #define SCROLL_DISTANCE 100
//自動(dòng)滾動(dòng) - (void)autoScroll{ //滾動(dòng)速度 CGFloat offSet=SCROLL_DISTANCE; //若果字幕滾動(dòng)到第二部分重復(fù)的部分則把偏移置0,設(shè)為第一部分,實(shí)現(xiàn)無限循環(huán) if (self.contentOffset.x>=self.contentSize.width / 2) { self.contentOffset=CGPointMake(0, 0); } //切割每次動(dòng)畫滾動(dòng)距離 [UIView animateWithDuration:SCROLL_TIME_INTERVAL delay:0 options:UIViewAnimationOptionCurveLinear animations:^{ self.contentOffset=CGPointMake(self.contentOffset.x+offSet, self.contentOffset.y); } completion:nil]; }
總結(jié)
好了,以上就是這篇文章的全部內(nèi)容了,親們有什么意見和問題記得及時(shí)反饋哦,希望這篇文章的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作帶來一定的幫助。
- IOS上iframe的滾動(dòng)條失效的解決辦法
- iOS應(yīng)用開發(fā)中UIScrollView滾動(dòng)視圖的基本用法總結(jié)
- IOS中UITableView滾動(dòng)到指定位置
- iOS ScrollView嵌套tableView聯(lián)動(dòng)滾動(dòng)的思路與最佳實(shí)踐
- IOS 的彈性滾動(dòng)解決方案
- iOS使用UICollectionView實(shí)現(xiàn)橫向滾動(dòng)照片效果
- ios之UIScrollerView滾動(dòng)視圖總結(jié)
- iOS Swift UICollectionView橫向分頁滾動(dòng),cell左右排版問題詳解
- 在IOS系統(tǒng)上滾動(dòng)條滾動(dòng)到指定的位置出現(xiàn)空白頁面的解決方案
- iOS實(shí)現(xiàn)循環(huán)滾動(dòng)公告欄
相關(guān)文章
IOS CoreLocation實(shí)現(xiàn)系統(tǒng)自帶定位的方法
本篇文章主要介紹了IOS Core Location實(shí)現(xiàn)系統(tǒng)自帶定位的方法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下。2017-02-02iOS應(yīng)用設(shè)計(jì)模式開發(fā)中職責(zé)鏈(責(zé)任鏈)模式的實(shí)現(xiàn)解析
這篇文章主要介紹了iOS應(yīng)用設(shè)計(jì)模式開發(fā)中職責(zé)鏈模式的相關(guān)實(shí)現(xiàn)解析,示例代碼為傳統(tǒng)的Objective-C,需要的朋友可以參考下2016-03-03iOS開發(fā)輸入自動(dòng)填充UITextField背景色
如何在iOS中實(shí)現(xiàn)輸入時(shí)自動(dòng)填充背景色的效果,首先,我們?cè)O(shè)置UITextField的背景色為初始顏色,然后,通過設(shè)置UITextField的代理,并監(jiān)聽UITextField的輸入事件,我們?cè)谟脩糸_始輸入時(shí)將其背景色改變?yōu)楦吡令伾?在用戶結(jié)束輸入時(shí)恢復(fù)為初始顏色2023-10-10iOS實(shí)現(xiàn)文字水平無間斷滾動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了iOS實(shí)現(xiàn)文字水平無間斷滾動(dòng)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08iOS實(shí)現(xiàn)封裝一個(gè)獲取通訊錄的工具類詳解
這篇文章主要給大家介紹了關(guān)于iOS如何實(shí)現(xiàn)封裝一個(gè)獲取通訊錄的工具類的相關(guān)資料,這是自己平時(shí)封裝的一個(gè)工具類,使用非常方便,文中給出了詳細(xì)的示例代碼,需要的朋友們可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-10-10