iOS Mask屬性的詳細介紹及應用實例
前言:
在開發(fā)過程中,類似android和其他平臺的UI開發(fā)方法,需要通過一個mask圖顯示部分UI或者Icon資源。ios的控件自帶alpha的值,但是這個值都是整個icon或者UI的透明效果,不能做到自定義的透明或者鏤空效果。我們必須借助于mask資源圖。
Mask屬性介紹
Mask平時用的最多的是masksToBounds 吧. 其實除此以外Mask使用場景很多,看完之后你會發(fā)現(xiàn)好真是好用的不要不要的...
先來了解下Mask屬性到底是什么?
Mask 英文解釋是蒙板/面罩,平時我們稱為蒙層. 在蘋果官方文檔里如下圖,意思是Mask是一個可選的Layer,它可以是根據(jù)透明度來掩蓋Layer的內(nèi)容.
這么一說好像...還是不曉得有什么卵用...
那再看下面這個說明,意思是Layer的透明度決定了Layer內(nèi)容是否可以顯示,非透明的內(nèi)容和背景可以顯示,透明的則無法顯示.
Mask 實例使用
實例1:漸變進度條
先看"臉" 再談"內(nèi)涵"
整個動畫效果主要可以分成4步驟:
1.創(chuàng)建一個CALayer 做為背景色進度條
CALayer *bgLayer = [CALayer layer]; bgLayer.frame = CGRectMake(kNumberMarkWidth / 2, self.numberMarkView.bottom + 10.f, self.width - kNumberMarkWidth / 2, kProcessHeight); bgLayer.backgroundColor = [UIColor colorWithHex:0xF5F5F5].CGColor; bgLayer.masksToBounds = YES; bgLayer.cornerRadius = kProcessHeight / 2; [self.layer addSublayer:bgLayer];
2.創(chuàng)建一個CAGradientLayer 漸變效果的Layer
self.gradientLayer = [CAGradientLayer layer]; self.gradientLayer.frame = bgLayer.frame; self.gradientLayer.masksToBounds = YES; self.gradientLayer.cornerRadius = kProcessHeight / 2; // 設置漸變顏色數(shù)組 [self.gradientLayer setColors:[NSArray arrayWithObjects: (id)[[UIColor colorWithHex:0xFF6347] CGColor], [(id)[UIColor colorWithHex:0xFFEC8B] CGColor], (id)[[UIColor colorWithHex:0xEEEE00] CGColor], (id)[[UIColor colorWithHex:0x7FFF00] CGColor], nil]]; // 設置漸變位置數(shù)組 [self.gradientLayer setLocations:@[@0.3, @0.5, @0.7, @1]]; // 設置漸變開始和結(jié)束位置 [self.gradientLayer setStartPoint:CGPointMake(0, 0)]; [self.gradientLayer setEndPoint:CGPointMake(1, 0)];
3.創(chuàng)建一個Mask Layer,并設置為CAGradientLayer漸變層的Mask. 然后通過設置maskLayer 寬度來控制進度了. 是不是很簡單,不過好像沒有感覺不出Mask的強大之處...
self.maskLayer = [CALayer layer]; self.maskLayer.frame = CGRectMake(0, 0, (self.width - kNumberMarkWidth / 2) * self.percent / 100.f, kProcessHeight); [self.gradientLayer setMask:self.maskLayer];
- (void)circleAnimation { // 進度條動畫 [CATransaction begin]; [CATransaction setDisableActions:NO]; [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; [CATransaction setAnimationDuration:kAnimationTime]; self.maskLayer.frame = CGRectMake(0, 0, (self.width - kNumberMarkWidth / 2) * _percent / 100.f, kProcessHeight); [CATransaction commit]; }
4.文字漸變,這個就能看出Mask 的特點了.
先創(chuàng)建一個Label展示分數(shù),再同第2步創(chuàng)建一個一樣的漸變CAGradientLayer.將Label的關聯(lián)圖層設置為漸變CAGradientLayer 的Mask, 這樣就OK了.
上面有說過Mask屬性特點是內(nèi)容非透明則可以顯示,透明則隱藏.
實例中,Label做為漸變層的Mask, Label中文字部分是非透明的,其他是透明的.那么文字和文字背景(這里就是漸變層)可以顯示.大概就像鏤空文字部分,然后顯示出底下的漸變層.
最后只要移動Label 的位置就能看到我們所要的效果文字顏色漸變. 下左圖設置了Mask , 下右圖未設置Mask.
- (void)setNUmberMarkLayer { // 提示文字設置漸變色 CAGradientLayer *numberGradientLayer = [CAGradientLayer layer]; numberGradientLayer.frame = CGRectMake(0, kTopSpaces, self.width, kNumberMarkHeight); [numberGradientLayer setColors:self.colorArray]; [numberGradientLayer setLocations:self.colorLocationArray]; [numberGradientLayer setStartPoint:CGPointMake(0, 0)]; [numberGradientLayer setEndPoint:CGPointMake(1, 0)]; [self.layer addSublayer:numberGradientLayer]; [numberGradientLayer setMask:self.numberMark.layer]; self.numberMark.frame = numberGradientLayer.bounds; }
源碼可以進github查看: https://github.com/xl20071926/LXGradientProcessView
另外還有類似的仿照芝麻信用,用Mask和CAShaperLayer 做的,有興趣的也可以看下:https://github.com/xl20071926/LXCircleAnimationView
實例2:鏤空效果
新手引導大多數(shù)app都會有這個功能,然而據(jù)了解蠻多就是直接貼張圖片上面就搞定了.
額,這樣做確實簡單,可是這樣好Low而且做出來的效果不好,那我們來用逼格高點的鏤空方式實現(xiàn):
先來一個簡單的效果圖:
實現(xiàn)起來也很簡單,主要分3個步驟:
1.創(chuàng)建一個鏤空的路徑:
UIBezierPath 有個原生的方法- (void)appendPath:(UIBezierPath *)bezierPath, 這個方法作用是倆個路徑有疊加的部分則會鏤空.
這個方法實現(xiàn)原理應該是path的FillRule 默認是FillRuleEvenOdd(CALayer 有一個fillRule屬性的規(guī)則就有kCAFillRuleEvenOdd), 而EvenOdd 是一個奇偶規(guī)則,奇數(shù)則顯示,偶數(shù)則不顯示.疊加則是偶數(shù)故不顯示.
2.創(chuàng)建CAShapeLayer 將鏤空path賦值給shapeLayer
3.將shapeLayer 設置為背景視圖的Mask
UIView *backgroundView = [[UIView alloc] init]; backgroundView.frame = self.view.bounds; backgroundView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.7]; [self.view addSubview:backgroundView]; // 創(chuàng)建一個全屏大的path UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.view.bounds]; // 創(chuàng)建一個圓形path UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.view.center.x, self.view.center.y - 25) radius:50 startAngle:0 endAngle:2 * M_PI clockwise:NO]; [path appendPath:circlePath]; CAShapeLayer *shapeLayer = [CAShapeLayer layer]; shapeLayer.path = path.CGPath; backgroundView.layer.mask = shapeLayer;
順便提下,在實際開發(fā)中可能遇到這種需求,當tableView 滑動到某個位置的時候才顯示新手引導.
這時候就需要將tableView上的坐標轉(zhuǎn)化為相對于屏幕的坐標. 可用原生的方法:
- (CGRect)convertRect:(CGRect)rect toView:(nullable UIView *)view;
- (CGRect)convertRect:(CGRect)rect fromView:(nullable UIView *)view;
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
- IOS 貝塞爾曲線(UIBezierPath)屬性、方法整理
- iOS10 適配-Xcode8問題總結(jié)及解決方案
- iOS中視頻播放器的簡單封裝詳解
- iOS給圖片添加濾鏡&使用openGLES動態(tài)渲染圖片詳解及實例
- JS辨別訪問瀏覽器判斷是android還是ios系統(tǒng)
- js和html5實現(xiàn)手機端刮刮卡抽獎效果完美兼容android/IOS
- iOS開發(fā)中ViewController的頁面跳轉(zhuǎn)和彈出模態(tài)
- Nagios遠程監(jiān)控安裝與配置詳解圖文
- iOS開發(fā)中WebView的基本使用方法簡介
- js判斷客戶端是iOS還是Android等移動終端的方法
- IOS獲取各種文件目錄路徑的方法
- IOS開發(fā)代碼分享之用nstimer實現(xiàn)倒計時功能
相關文章
iOScollectionView廣告無限滾動實例(Swift實現(xiàn))
本篇文章主要介紹了iOScollectionView廣告無限滾動實例,可以實現(xiàn)廣告無限滾動,有興趣的可以了解一下。2016-11-11android中UIColletionView瀑布流布局實現(xiàn)思路以及封裝的實現(xiàn)
本篇文章主要介紹了android中UIColletionView瀑布流布局實現(xiàn)思路以及封裝的實現(xiàn),具有一定的參考價值,有興趣的可以了解一下。2017-02-02iOS11實現(xiàn)App內(nèi)自動連接Wi-Fi的方法
這篇文章主要給大家介紹了關于iOS11實現(xiàn)App內(nèi)自動連接Wi-Fi的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2018-10-10iOS開發(fā)中常見的項目文件與MVC結(jié)構(gòu)優(yōu)化思路解析
這篇文章主要介紹了iOS開發(fā)中常見的項目文件與MVC結(jié)構(gòu)優(yōu)化思路解析,示例代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下2015-12-12解決iOS7上UITextField限制字數(shù)輸入導致崩潰問題的方法
這篇文章主要為大家分享了解決iOS7上UITextField限制字數(shù)輸入導致崩潰問題的方法,感興趣的小伙伴們可以參考一下2016-03-03