Demo詳見GitHub:JXTMarkLabel
鏤空文字 - JXTHollowOutLabel
鏤空文字效果的實現基于drawRect重繪代虾,具體參考了兩篇帖子:
想了解原理的可以參考原文进肯,根據帖子中提供的代碼,我這里稍作了簡化和封裝棉磨,也就是工程里的JXTHollowOutLabel類江掩。
效果實現的核心代碼如下:
- (void)drawSubtractedText:(NSString *)text inRect:(CGRect)rect inContext:(CGContextRef)context {
// 將當前圖形狀態(tài)推入堆棧
CGContextSaveGState(context);
// 設置混合色
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);
}
該類的調用同系統的UILabel
類似(該類是其子類)乘瓤,不過因為封裝的問題环形,初始化僅支持initWithFrame
一種,也就是不支持xib
馅扣。
再回到文章最開始的話題斟赚,因為有了鏤空文字,這個問題就很簡單了差油,只需要在這個label
的底層添加一個可滑動的顏色塊,漸變效果也就有了任洞,效果如下:
如果看得足夠仔細蓄喇,可以發(fā)現有幾個title
之間存在很細的裂隙,那是因為我這里的標題的label尺寸是根據文字長短動態(tài)計算的交掏,用了boundingRectWithSize
方法妆偏,實際發(fā)現,一旦title的內容是中文和數字或字母混合的盅弛,例如圖中的b站钱骂,就會產生計算誤差,雖然很小挪鹏。见秽。。
基于CoreAnimation的KTV歌詞視圖
歌詞進度顯示 - JXTProgressLabel
因為沒有像歌詞進度顯示那樣有那么多顧慮讨盒,我這里使用了一種比較白癡的方法解取,這個方法原來是星級評價那里使用的,星級評價就是滿5星返顺,根據數據動態(tài)展示幾點幾星的那個問題禀苦,有的人是直接幾星貼幾張圖,半星就是半顆星的圖遂鹊,但實際上用兩層view再加一層控制的view振乏,一共三層,疊加起來秉扑,就很容易實現這個效果:
上圖中:底層是白色字體的那個label
慧邮,也就是backgroundLabel
,中間層,也就是現在標示的藍色的透明view
赋咽,是clipView
旧噪,最上層橙色文字的label
,是foregroundLabel
脓匿。
三者的層級關系如下:
[self addSubview:self.backgroundLabel];
[self.clipView addSubview:self.foregroundLabel];
[self addSubview:self.clipView];
foregroundLabel
是clipView
的子視圖淘钟,_clipView.clipsToBounds = YES
需要設置,此時控制clipView
的寬度陪毡,也就控制了foregroundLabel
的文字顯示的進度(label
的顯示寬度)米母,backgroundLabel
和clipView
是并列關系,后者在前者圖層的上層毡琉,也就展現了背景label
隨著中間層clipView
的動態(tài)寬度變化铁瞒,從而動態(tài)渲染顏色的視覺假象。星級控制也是同樣的原理桅滋。
JXTProgressLabel
的使用也同系統的UIlabel
類似慧耍,初始化也僅支持initWithFrame
一種,初始化時還需要設置前景和背景label
的顏色:
_progressLabel.backgroundTextColor = [UIColor whiteColor];
_progressLabel.foregroundTextColor = [UIColor orangeColor];
控制顯示進度時丐谋,支持兩種方法芍碧,一種是直接控制clipView的寬度,也就是
_progressLabel.clipWidth
号俐,但這種方式比較局限泌豆,推薦直接控制
_progressLabel2.dispProgress
,dispProgress
是0-1之間的小數吏饿。
JXTProgressLabel
除了可以作為類似的歌詞進度顯示踪危,還可以做進度指示器,具體用法看具體需求了猪落。
歌詞進度顯示的升級 - JXTSlideClipLabel
還是回到最開始的問題贞远,如果直接使用之前提到的JXTProgressLabel
,很明顯是不能直接滿足需求的许布,因為title
的顏色是變過之后兴革,又要變回的,所以蜜唾,上面的JXTProgressLabel的clipView
的寬度應該是限定的或者說應該是隨著title
長短動態(tài)改變的杂曲,而不是一直增大的。
如果只是限制clipView
的寬度袁余,位置水平移動擎勘,很明顯,其子視圖foregroundLabel
也會跟著移動颖榜,那么之前動態(tài)渲染的假象也就不復存在了棚饵,這里解決的方法也比較取巧:foregroundLabel
的frame
同backgroundLabel
一樣煤裙,但是其坐標隨著固定寬度的clipView
的移動,反方向退行噪漾,三者之間的圖層關系還是不變的硼砰。
具體的效果就是最開始的那個展示。
JXTSlideClipLabel
在Demo
中只是原理的封裝欣硼,沒有考慮具體情境而普適题翰,demo
中是根據title
數量,動態(tài)創(chuàng)建了label
诈胜,其實只使用一個label
應該也是可以的豹障,只要保證三者的圖層關系就好。只是用一個label
做foregroundLabel
或backgroundLabel
的話焦匈,標題組應該拼接起來成一個字符串血公,具體沒有試,應該是行得通的缓熟。
一種類似視差效果的視圖 - ParallaxView
雖然是這么叫的累魔,但其實不是tableView
的那種滑動的視察效果啦,只是不知道該怎么稱呼荚虚,記得是在哪個APP里見過這個效果的
這個的實現原理和JXTSlideClipLabel
一樣薛夜,可以移動的view
中貼了一張大圖,但限于clipView
尺寸版述,只能顯示一部分,這一部分根據移動的坐標寞冯,也動態(tài)“退行”渴析,就成了這個效果,好像一塊“透視鏡”吮龄,比較有意思俭茧,那個圓形的本來是想試著做成一個放大鏡的,但是方法后的視圖的坐標變換沒有處理好漓帚,暫時放棄了……
ParallaxView
的代碼同樣只是演示母债,滑動視圖的邊界沒有限定,可以自行處理尝抖。
原文鏈接:
參考文章: