问题:在用masonry布局时,想给按钮添加一个渐变的背景色。
渐变背景色用CAGradientLayer
来创建。
一、 CAGradientLayer
的介绍
CAGradientLayer是CALayer的子类,可以直接将设置好的图层添加到UIView的layer上,使用方便。
- 方法简介
// 渐变颜色的数组(CGColorRef对象)
@property(nullable, copy) NSArray *colors;
// 渐变颜色位置,[0-1]范围,递增,数量和colors数量相等,否则无效
@property(nullable, copy) NSArray<NSNumber *> *locations;
// 渐变的起点和终点,[0,0]-[1,1]
// [0,0]是左下角,[1,1]是右上角。默认值分别为[.5,0]和[.5,1]
@property CGPoint startPoint;
@property CGPoint endPoint;
// 将绘制的渐变类型。 目前唯一允许值为“轴”(默认值)可以忽略
@property(copy) NSString *type;
二、Masonry
的原理
首先你要知道autolayout和frame的关系,autolayout最终也是转成frame,masonry是建立在autolayout之上的。你没获取到正确的值,那是因为约束还没布局完成。相当于就是我们给一定的约束,系统内部自己去根据约束条件转成对应的frame,而这需要一个过程。想要拿到正确的frame最好的就是让autolayout完成之后,什么时候完成呢?那就是在layoutsubviews for view or didlayoutsubviews for controller 里获取,当然在控制器的viewdidappear里也拿得到,但是正确做法和最佳做法还是在控制器里的viewdidlayout里获取最好~因为autolayout会根据约束,不停的去改变frame,这方法里最后拿到的frame就是最终姿势.
那么约束什么时候能完成frame的转换呢?
答案:下一帧的时候。
完整代码
//ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor lightGrayColor];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setTitle:@"点我试试" forState:UIControlStateNormal];
[self.view addSubview:button];
[button mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(button.superview).inset(12);
make.height.mas_equalTo(44);
make.bottom.equalTo(self.view).offset(-20);
}];
CAGradientLayer *gradientLayer = [CAGradientLayer new];
gradientLayer.colors = @[(id)[UIColor redColor].CGColor,(id)[UIColor greenColor].CGColor,(id)[UIColor blueColor].CGColor];
gradientLayer.startPoint = CGPointMake(0, 0);
gradientLayer.endPoint = CGPointMake(1, 0);
[button.layer addSublayer:gradientLayer];
//一定要在获取frame之前调用layoutIfNeed
[self.view layoutIfNeeded];
gradientLayer.frame = button.bounds;
}
这里要感谢自负的大撸sir
的提示!!!