有几种方法可以做到这一点。这里有一种方法:
创建UIView
子命名GradientView
管理梯度层。这很有帮助,因为这意味着您可以使用常规UIKit技术来管理渐变布局(自动布局约束,自动调整遮罩,UIKit动画)。
对于应该参与共同梯度,添加一个GradientView
子视图的每个视图。同样设置每个GradientView
的颜色,位置和起点和终点。
对于应该参与共同梯度,打开clipsToBounds
每个视图。
使用自动布局约束,以使每个GradientView
跨度所有参与superviews的。 (了解约束可以跨越超视图/子视图边界很重要)。
通过这种方法,自动布局需要使梯度覆盖所有的意见,即使他们改变大小或走动的照顾。例如,当用户旋转设备时,您不必做任何特别的操作就可以使渐变效果更好。
因此,你的两个视图例如,我建议您设置视图层次是这样的:
在上面的观点调试器的截图,我禁用裁剪。您可以看到两个渐变视图具有相同的渐变并共享相同的屏幕空间。该topGradient
是topView
和bottomGradient
子视图是bottomView
子视图。
如果我们把剪裁上,你只会看到里面topView
适合的topGradient
部分的界限,你只会看到里面bottomView
适合的bottomGradient
部分的界限。下面是它看起来像剪贴启用:
这是我的测试程序在模拟器的屏幕截图:
这里的源代码GradientView
:
@interface GradientView: UIView
@property (nonatomic, strong, readonly) CAGradientLayer *gradientLayer;
@end
@implementation GradientView
+ (Class)layerClass { return CAGradientLayer.class; }
- (CAGradientLayer *)gradientLayer { return (CAGradientLayer *)self.layer; }
@end
下面是我用来创建所有视图的代码:
- (void)viewDidLoad {
[super viewDidLoad];
UIView *topView = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 100, 50)];
topView.layer.cornerRadius = 10;
topView.clipsToBounds = YES;
UIView *topGradient = [self newGradientView];
[topView addSubview:topGradient];
[self.view addSubview:topView];
UIView *bottomView = [[UIView alloc] initWithFrame:CGRectMake(20, 90, 100, 50)];
bottomView.layer.cornerRadius = 10;
bottomView.clipsToBounds = YES;
UIView *bottomGradient = [self newGradientView];
[bottomView addSubview:bottomGradient];
[self.view addSubview:bottomView];
[self constrainView:topGradient toCoverViews:@[topView, bottomView]];
[self constrainView:bottomGradient toCoverViews:@[topView, bottomView]];
}
- (GradientView *)newGradientView {
GradientView *gv = [[GradientView alloc] initWithFrame:CGRectZero];
gv.translatesAutoresizingMaskIntoConstraints = NO;
gv.gradientLayer.colors = @[(__bridge id)UIColor.blueColor.CGColor, (__bridge id)UIColor.redColor.CGColor];
return gv;
}
这里就是我如何创建,使一个GradientView
(或任何视图)的约束涵盖了一系列的观点:
- (void)constrainView:(UIView *)coverer toCoverViews:(NSArray<UIView *> *)coverees {
for (UIView *coveree in coverees) {
NSArray<NSLayoutConstraint *> *cs;
cs = @[
[coverer.leftAnchor constraintLessThanOrEqualToAnchor:coveree.leftAnchor],
[coverer.rightAnchor constraintGreaterThanOrEqualToAnchor:coveree.rightAnchor],
[coverer.topAnchor constraintLessThanOrEqualToAnchor:coveree.topAnchor],
[coverer.bottomAnchor constraintGreaterThanOrEqualToAnchor:coveree.bottomAnchor]];
[NSLayoutConstraint activateConstraints:cs];
cs = @[
[coverer.leftAnchor constraintEqualToAnchor:coveree.leftAnchor],
[coverer.rightAnchor constraintEqualToAnchor:coveree.rightAnchor],
[coverer.topAnchor constraintEqualToAnchor:coveree.topAnchor],
[coverer.bottomAnchor constraintEqualToAnchor:coveree.bottomAnchor]];
for (NSLayoutConstraint *c in cs) { c.priority = UILayoutPriorityDefaultHigh; }
[NSLayoutConstraint activateConstraints:cs];
}
}
的greaterThanOrEqual
/lessThanOrEqual
的限制,这(默认)已要求优先,请确保coverer
覆盖每个coveree
的整个帧。具有较低优先级的equal
约束条件确保coverer
占用每个coveree
所需的最小空间。
一个“高”视图与两个圆角矩形“切口”通过图层蒙版。 – DonMag