带有圆角的 UIView CAGradient?

Posted

技术标签:

【中文标题】带有圆角的 UIView CAGradient?【英文标题】:UIView CAGradient with rounded corners? 【发布时间】:2011-11-25 18:58:07 【问题描述】:

我有一个带有圆角和阴影的 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;

这是我尝试实现它的代码,但渐变层位于视图中的所有内容之上。如何使渐变在所有控件和标签下?每一个响应的帮助将不胜感激。

【问题讨论】:

【参考方案1】:

在斯威夫特中:

let gradientLayer = CAGradientLayer()
gradientLayer.cornerRadius = 20.0

【讨论】:

【参考方案2】:

添加到视图中的层 (addSublayer) 被绘制在视图自己的层之前,这是所有视图绘制的地方。您想要的是将渐变绘制到视图的 own 层中。为此,请在您的视图中实现+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 的示例? 好的,谢谢!但是self.layer 给了我一个错误。它没有在我的头文件中声明。它应该是怎样的? 记住,我说过代码需要在视图自己的代码中。您需要创建一个 UIView 子类才能放置它。 但是为什么@gcamp贴出的方法有误?使用它有什么缺点吗? @Jacos - 方法没有错。他说的是错误的。视图有自己的主层,该层可以有子视图。您可以在视图自己的图层中绘制圆角矩形、阴影和渐变,这就是我向您展示的方法;或者您可以添加一个子图层并在该子图层中绘制圆角矩形、阴影和渐变,就像您现在正在做的那样。只要您了解您在做什么,这并不重要。他说您需要使用insertSublayer:atIndex: 的声明往往会破坏任何此类理解。【参考方案3】:

当您addSublayer: 时,它会将图层添加到所有子图层的顶部。

您可能应该使用类似的东西:

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

这样,CAGradientLayer 将低于其他所有内容。

【讨论】:

谢谢,我以前也试过这个。但是当我实现它时,圆角消失了。对此有什么想法吗? 编辑我让它工作了,只需要让渐变也有圆角。 这是错误的。渐变层仍然在视图层的前面。它必须是:子层始终位于其超层的前面。 @Jacos 或许可以让新图层按他想要的方式显示,但他不会按照他的要求将渐变图层作为他视图的实际背景。 好吧,您可能有更好的答案(赞成),但这并没有错。他希望渐变层低于其他标签和控件,我的回答符合他的要求。 错了。你说insertSublayer:atIndex:。这没有任何区别,只是误导了 OP。他正在绕过视图层的角落。你的代码仍然把渐变层放在前面。【参考方案4】:

除了 gcamp 建议的 insertSublayer:atIndex: 之外,您还可以使用 insertSublayer:above: 和 insertSublayer:below: 将图层放置在特定位置。

[self.view.layer insertSublayer:gradient below:someUIObject];

【讨论】:

【参考方案5】:

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

+ (Class)layerClass

    return [CAGradientLayer class];

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

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

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

并将你的渐变分配给它。

干净整洁...

【讨论】:

以上是关于带有圆角的 UIView CAGradient?的主要内容,如果未能解决你的问题,请参考以下文章

带有圆角和阴影的 UIView?

带有圆角和阴影的 UIView?

带有 PatternImage 的 UIView 圆角

带有圆角和阴影的 Swift uiview 不起作用

带有透明圆角矩形的 UIView?

带有 UILabel 的 UIView transitionWithView 在过渡期间会丢失圆角