带有圆角的 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?的主要内容,如果未能解决你的问题,请参考以下文章