我知道怎么做(1)但我该怎么做(2)?
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = view.bounds;
gradient.colors = @[(id)[UIColor blueColor].CGColor, (id)[UIColor redColor].CGColor];
[view.layer insertSublayer:gradient atIndex:0];
答案 0 :(得分:2)
有几种方法可以做到这一点。这是一种方式:
创建名为UIView
的{{1}}子类来管理渐变图层。这很有用,因为这意味着您可以使用普通的UIKit技术来管理渐变布局(自动布局约束,自动调整蒙版,UIKit动画)。
对于应参与常用渐变的每个视图,添加GradientView
子视图。同样设置每个GradientView
的颜色,位置以及起点和终点。
对于应参与常用渐变的每个视图,请启用GradientView
。
使用自动布局约束使每个clipsToBounds
跨越所有参与的超级视图。 (了解约束可以跨越超视图/子视图边界非常重要。)
通过这种方法,自动布局可以使渐变覆盖所有视图,即使它们改变了大小或移动。例如,当用户旋转设备时,您不必做任何特殊的操作来使渐变效果很好。
因此,对于您的双视图示例,我建议您设置这样的视图层次结构:
在上面的视图调试器屏幕截图中,我禁用了剪辑。您可以看到两个渐变视图具有相同的渐变并共享相同的屏幕空间。 GradientView
是topGradient
的子视图,topView
是bottomGradient
的子视图。
如果我们打开裁剪,你只会看到bottomView
的部分符合topGradient
的界限,你只会看到topView
的部分适合在bottomGradient
的范围内。以下是启用剪辑的情况:
这是我在模拟器中测试程序的屏幕截图:
以下是bottomView
的源代码:
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
所需的最小空间。
答案 1 :(得分:1)
您可以通过使用渐变在视图顶部添加视图,然后通过从topView
制作蒙版来剪切图形,然后将其添加到顶部的视图(让&#39 ; s称之为 let yourPath: UIBezierPath = //create the desired bezier path for your shapes
let mask = CAShapeLayer()
mask.path = yourPath.cgPath
topView.layer.mask = mask
):
html_entity_decode