UIView CAGradient带圆角?

5

我有一个带有圆角和阴影的UIView,已经实现并且正常工作。但是这个UIView的背景色很无聊,是白色的。所以我想把渐变层作为背景。在标签、按钮和最重要的是使圆角仍然出现的地方下面。

CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = subHudView.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor blackColor] CGColor], (id)[[UIColor whiteColor] CGColor], nil];
[subHudView.layer addSublayer:gradient];
subHudView.layer.cornerRadius = 8;
subHudView.layer.masksToBounds = NO;
subHudView.layer.shadowOffset = CGSizeMake(-5, 5);
subHudView.layer.shadowRadius = 8;
subHudView.layer.shadowOpacity = 0.75;

这是我的代码实现,但渐变层位于视图中的所有控件和标签之上。我该如何使渐变在所有控件和标签下方?感谢每一位提供帮助的人。

5个回答

11

在 Swift 中:

let gradientLayer = CAGradientLayer()
gradientLayer.cornerRadius = 20.0

2

您在视图中添加的图层(addSublayer)会被绘制在视图自己的图层前面,而视图自身的所有绘制都发生在该图层中。您需要的是将渐变绘制到视图自己的图层中。为此,请在视图中实现+layerClass,指定您希望您的视图图层成为一个渐变视图。

例如(在视图自己的代码中):

+(Class)layerClass {
    return [CAGradientLayer class];
}

-(void)awakeFromNib {
    [super awakeFromNib];
    CAGradientLayer* layer = (CAGradientLayer*)self.layer;
    layer.colors = [NSArray arrayWithObjects:(id)[[UIColor blackColor] CGColor], (id)[[UIColor whiteColor] CGColor], nil];
    layer.cornerRadius = 8;
    layer.masksToBounds = NO;
    layer.shadowOffset = CGSizeMake(-5, 5);
    layer.shadowRadius = 8;
    layer.shadowOpacity = 0.75;
}

如果您实现了drawRect:方法,那么您当然会擦除渐变和圆角。但是,有一些解决方法...

请问您能否给我展示一下如何实现+layerClass的例子? - Jacob
好的,谢谢!但是 self.layer 给了我一个错误。它在我的头文件中没有声明。应该怎么做? - Jacob
记住,我说过那段代码需要在视图自己的代码中。你需要创建一个UIView子类来放置它。 - matt
但是为什么@gcamp发布的方法是错误的呢?使用它有什么缺点吗? - Jacob
@Jacos - 这个方法本身没有错,他说的是错的。一个视图有自己的主要层,而该层可以有子视图。您可以在视图自己的层中绘制圆角矩形、阴影和渐变,这正是我向您演示的;或者您可以添加一个子层,并在该子层中绘制圆角矩形、阴影和渐变,就像您现在所做的那样。只要你明白你正在做什么,这没关系。他声称需要使用 insertSublayer:atIndex: 会破坏对这种理解的任何努力。 - matt
显示剩余2条评论

1

当你使用addSublayer:方法时,它会将图层添加到所有子图层的顶部。

你应该考虑使用以下方法代替:

[subHudView.layer insertSublayer:gradient atIndex:0];

这样,CAGradientLayer 就会在其他所有内容下面。


谢谢,我之前也试过这个方法。但是当我实现它时,圆角就消失了。你有什么想法吗?编辑 我已经解决了,只需要让渐变也有圆角即可。 - Jacob
这是错误的。渐变层仍然在您视图的层前面。它必须是:子层始终在其父层的前面。@Jacos可能能够使新层以他想要的方式显示,但他并没有将渐变层作为实际背景添加到他的视图中,正如他所要求的那样。 - matt
你可能有更好的答案(被点赞),但这并不是错误的。他想要渐变层在其他标签和控件下面,我的答案做到了他要求的。 - gcamp
这是错误的。你说要使用 insertSublayer:atIndex:。这没有任何区别,只会误导 OP。他正在将视图层的角落变圆。你的代码仍然将渐变层放在其前面。 - matt

0
除了gcamp建议的insertSublayer:atIndex:之外,您还可以使用insertSublayer:above:和insertSublayer:below:来将图层放置在指定位置。
[self.view.layer insertSublayer:gradient below:someUIObject];

0

不要创建新的图层,覆盖您的视图的图层方法:

+ (Class)layerClass
{
    return [CAGradientLayer class];
}

这将确保您的视图创建一个CAGradientLayer,而不是基本的CALayer作为基础层。

然后,在初始化期间获取该层:

CAGradientLayer *gradLayer = self.layer;
gradLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor blackColor] CGColor], (id)[[UIColor whiteColor] CGColor], nil];

并将您的梯度分配给它。

漂亮而干净...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接