
Demo詳見GitHub:JXTMarkLabel
鏤空文字 - JXTHollowOutLabel

鏤空文字效果的實現(xiàn)基于drawRect重繪,具體參考了兩篇帖子:
想了解原理的可以參考原文,根據(jù)帖子中提供的代碼,我這里稍作了簡化和封裝,也就是工程里的JXTHollowOutLabel類。
效果實現(xiàn)的核心代碼如下:
- (void)drawSubtractedText:(NSString *)text inRect:(CGRect)rect inContext:(CGContextRef)context {
// 將當(dāng)前圖形狀態(tài)推入堆棧
CGContextSaveGState(context);
// 設(shè)置混合色
CGContextSetBlendMode(context, kCGBlendModeDestinationOut);
// label上面添加label
UILabel *label = [[UILabel alloc] initWithFrame:rect];
label.font = _font;
label.text = text;
label.textAlignment = NSTextAlignmentCenter;
label.backgroundColor = _backgroundColor;
[label.layer drawInContext:context];
// 把堆棧頂部的狀態(tài)彈出,返回到之前的圖形狀態(tài)
CGContextRestoreGState(context);
}
該類的調(diào)用同系統(tǒng)的UILabel類似(該類是其子類),不過因為封裝的問題,初始化僅支持initWithFrame一種,也就是不支持xib。
再回到文章最開始的話題,因為有了鏤空文字,這個問題就很簡單了,只需要在這個label的底層添加一個可滑動的顏色塊,漸變效果也就有了,效果如下:

如果看得足夠仔細(xì),可以發(fā)現(xiàn)有幾個title之間存在很細(xì)的裂隙,那是因為我這里的標(biāo)題的label尺寸是根據(jù)文字長短動態(tài)計算的,用了boundingRectWithSize方法,實際發(fā)現(xiàn),一旦title的內(nèi)容是中文和數(shù)字或字母混合的,例如圖中的b站,就會產(chǎn)生計算誤差,雖然很小。。。
基于CoreAnimation的KTV歌詞視圖
歌詞進(jìn)度顯示 - JXTProgressLabel
因為沒有像歌詞進(jìn)度顯示那樣有那么多顧慮,我這里使用了一種比較白癡的方法,這個方法原來是星級評價那里使用的,星級評價就是滿5星,根據(jù)數(shù)據(jù)動態(tài)展示幾點幾星的那個問題,有的人是直接幾星貼幾張圖,半星就是半顆星的圖,但實際上用兩層view再加一層控制的view,一共三層,疊加起來,就很容易實現(xiàn)這個效果:

上圖中:底層是白色字體的那個label,也就是backgroundLabel,中間層,也就是現(xiàn)在標(biāo)示的藍(lán)色的透明view,是clipView,最上層橙色文字的label,是foregroundLabel。
三者的層級關(guān)系如下:
[self addSubview:self.backgroundLabel];
[self.clipView addSubview:self.foregroundLabel];
[self addSubview:self.clipView];
foregroundLabel是clipView的子視圖,_clipView.clipsToBounds = YES需要設(shè)置,此時控制clipView的寬度,也就控制了foregroundLabel的文字顯示的進(jìn)度(label的顯示寬度),backgroundLabel和clipView是并列關(guān)系,后者在前者圖層的上層,也就展現(xiàn)了背景label隨著中間層clipView的動態(tài)寬度變化,從而動態(tài)渲染顏色的視覺假象。星級控制也是同樣的原理。
JXTProgressLabel的使用也同系統(tǒng)的UIlabel類似,初始化也僅支持initWithFrame一種,初始化時還需要設(shè)置前景和背景label的顏色:
_progressLabel.backgroundTextColor = [UIColor whiteColor];
_progressLabel.foregroundTextColor = [UIColor orangeColor];
控制顯示進(jìn)度時,支持兩種方法,一種是直接控制clipView的寬度,也就是
_progressLabel.clipWidth,但這種方式比較局限,推薦直接控制
_progressLabel2.dispProgress,dispProgress是0-1之間的小數(shù)。
JXTProgressLabel除了可以作為類似的歌詞進(jìn)度顯示,還可以做進(jìn)度指示器,具體用法看具體需求了。
歌詞進(jìn)度顯示的升級 - JXTSlideClipLabel
還是回到最開始的問題,如果直接使用之前提到的JXTProgressLabel,很明顯是不能直接滿足需求的,因為title的顏色是變過之后,又要變回的,所以,上面的JXTProgressLabel的clipView的寬度應(yīng)該是限定的或者說應(yīng)該是隨著title長短動態(tài)改變的,而不是一直增大的。
如果只是限制clipView的寬度,位置水平移動,很明顯,其子視圖foregroundLabel也會跟著移動,那么之前動態(tài)渲染的假象也就不復(fù)存在了,這里解決的方法也比較取巧:foregroundLabel的frame同backgroundLabel一樣,但是其坐標(biāo)隨著固定寬度的clipView的移動,反方向退行,三者之間的圖層關(guān)系還是不變的。

具體的效果就是最開始的那個展示。
JXTSlideClipLabel在Demo中只是原理的封裝,沒有考慮具體情境而普適,demo中是根據(jù)title數(shù)量,動態(tài)創(chuàng)建了label,其實只使用一個label應(yīng)該也是可以的,只要保證三者的圖層關(guān)系就好。只是用一個label做foregroundLabel或backgroundLabel的話,標(biāo)題組應(yīng)該拼接起來成一個字符串,具體沒有試,應(yīng)該是行得通的。
一種類似視差效果的視圖 - ParallaxView
雖然是這么叫的,但其實不是tableView的那種滑動的視察效果啦,只是不知道該怎么稱呼,記得是在哪個APP里見過這個效果的

這個的實現(xiàn)原理和JXTSlideClipLabel一樣,可以移動的view中貼了一張大圖,但限于clipView尺寸,只能顯示一部分,這一部分根據(jù)移動的坐標(biāo),也動態(tài)“退行”,就成了這個效果,好像一塊“透視鏡”,比較有意思,那個圓形的本來是想試著做成一個放大鏡的,但是方法后的視圖的坐標(biāo)變換沒有處理好,暫時放棄了……
ParallaxView的代碼同樣只是演示,滑動視圖的邊界沒有限定,可以自行處理。
原文鏈接:
參考文章: