前言
最近忙著公司的項目,零零散散的功能以及Flutter的研發,導致簡書有兩年時間沒更新了。今天趁著閑暇時間,把前段時間項目里涉及到的遮罩拿出來分享。網絡上的方式層出不窮甚至過于復雜,本人就帶來個簡化后的實現方式(不是什么高超技術,望大佬們高抬貴手哈)。
示意圖
遮罩前
遮罩后
實現方式
- UI布局
// 文字內容底部漸變
UIView *gradientView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 350, 200)];
[self.view addSubview:gradientView];
// 文字內容
UITextView *textView = [[UITextView alloc] initWithFrame:gradientView.bounds];
textView.backgroundColor = UIColor.clearColor;
textView.selectable = NO;
textView.textColor = UIColor.whiteColor;
textView.text = @"這是第1行文字。。。\n這是第2行文字。。。\n這是第3行文字。。。\n這是第4行文字。。。\n這是第5行文字。。。\n這是第6行文字。。。\n這是第7行文字。。。\n這是第8行文字。。。\n這是第9行文字。。。\n這是第10行文字。。。\n這是第11行文字。。。\n這是第12行文字。。。\n這是第13行文字。。。\n這是第14行文字。。。\n這是第15行文字。。。\n這是第16行文字。。。";
[gradientView addSubview:textView];
[self updateGradientLayer:gradientView];
- 實現漸變圖層
/// 更新漸變圖層
- (void)updateGradientLayer:(UIView *)gradientView {
NSObject *transparent = (NSObject*)[UIColor.clearColor CGColor];
NSObject *opaque = (NSObject*)[UIColor.blackColor CGColor];
CALayer *maskLayer = [CALayer layer];
maskLayer.frame = gradientView.bounds;
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = maskLayer.bounds;
gradientLayer.colors = @[opaque, opaque, transparent];
gradientLayer.locations = @[@(0), @(0.857), @(1)];
gradientLayer.startPoint = CGPointMake(0.5, 0);
gradientLayer.endPoint = CGPointMake(0.5, 1);
[maskLayer addSublayer:gradientLayer];
gradientView.layer.mask = maskLayer;
}
淺析
代碼其實還是很簡單的,一對父子關系的控件+漸變圖層的實現,即可完成此功能。接下來做個簡單的分析:
- 給需要加遮罩效果的視圖增加一個父級View,為了讓此容器內的所有控件都具有統一的遮罩效果;也是為了保證TextView能保持正常滾動。因為如果給TextView的layer增加遮罩的話,將會導致遮罩層跟著一起滾動,影響實際效果。
- CAGradientLayer的編寫。CAGradientLayer是個線性的圖層,經常用于漸變色效果。
colors:漸變色的顏色節點;
locations:顏色節點的位置,取值范圍[0,1];
startPoint、endPoint:起始點與結束點,可通過參數實現是水平、垂直還是斜向; - layer.mask。給gradientLayer增加一層遮罩。
maskLayer透明的地方,gradientLayer就不會渲染,而是變透明,顯示出gradientLayer之后的內容;
maskLayer不透明的地方,gradientLayer就會正常渲染。
Demo
多謝支持!