Objective C - CAGradientLayer 覆盖 UILabel 中的文本?
Posted
技术标签:
【中文标题】Objective C - CAGradientLayer 覆盖 UILabel 中的文本?【英文标题】:Objective C - CAGradientLayer covers the text in UILabel? 【发布时间】:2011-08-26 19:05:32 【问题描述】:由于某些原因,CAGradientLayer
覆盖了我的文本,我正在尝试将渐变层添加到我的 UILabel
。
我做错什么了吗
- (void)viewDidLoad
[super viewDidLoad];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = CGRectMake(0, 0, myLabel.frame.size.width, myLabel.frame.size.height);
gradient.colors = myColors;
[myLabel.layer insertSublayer:gradient atIndex:0];
【问题讨论】:
【参考方案1】:CAGradientLayer
覆盖了标签的文本,因为文本是由您通过添加子层明确覆盖的超级层的内容绘制的。
您最简单的解决方案是使用两个视图。 UIView
子类,您可以在其中覆盖 +[UIView layerClass]
并返回 [CAGradientLayer]
。添加一个好的初始化方法来设置你的渐变。
下一个小狗将UILabel
添加为自定义渐变视图的子视图。
【讨论】:
顺便说一句,出于对特定实现的好奇,我接受即使已知,依赖它也是一个非常糟糕的主意;我还没有检查,但大概 UILabel 使用 CATextLayer,因为它在 ios 3.2 中的可用性? @Tommy -UILabel
在 3.2 之前或之后不受 CATextLayer
的支持。您可以使用“po [[someLabel layer] class]
”轻松检查它,这将产生一个基本的CALayer
。这在视觉上也很明显,因为CATextLayer
没有亚像素抗锯齿但UILabel
有。
类类型并不总是具有指导意义,任何尝试过 [str isKindOfClass:[NSMutableString class]] 的人都可以证明这一点。这是一个桥接问题,显然 CALayer 并没有与任何东西正式免费桥接,但是假设 CALayer 中没有类似的类聚类或别名只是一个假设。我认为你的观点是,亚像素抗锯齿线索是相当明确的。
谢谢,很奇怪,因为这在 UIButton 上可以正常工作,但在 UILabel 上不行。我认为他们都使用相同的方式来绘制文本。
@aryaxt - 如果您查看UIButton.h
头文件,您将看到UIButton
实际上有一个名为_titleView
的实例变量。因此,对于按钮视图,这很简单,因为按钮不会绘制自己的文本,这是由子标签子视图完成的。【参考方案2】:
我遇到了同样的问题。我使用这种方法来获取形状图层的参考,或者如果它不存在则生成它。此方法确保将该图层放在后面,使其不会覆盖标签文本图层。只需使用它,你应该一切都好,不需要额外的子类。
- (CAShapeLayer*) getShapeLayerForObject: (UIView*) object
CAShapeLayer *maskLayer;
int loc = -1;
for(int x = 0; x < object.layer.sublayers.count; x++)
if([[object.layer.sublayers objectAtIndex:x] isKindOfClass:[CAShapeLayer class]])
loc = x;
break;
if(loc > -1)
maskLayer = (CAShapeLayer*) [object.layer.sublayers objectAtIndex:loc];
else
maskLayer = [[CAShapeLayer alloc] init];
[object.layer insertSublayer:maskLayer atIndex:0];
return maskLayer;
【讨论】:
【参考方案3】:例如,如果您需要将UILabel
子类化,然后添加一些覆盖文本的CALayer
,建议将CATextLayer
添加到您的CALayer
,这是一个快速示例:
@IBDesignable class BWRoundedLabel: UILabel
override var text: String?
didSet
updateView()
@IBInspectable override var shadowColor: UIColor?
didSet
updateView()
private func updateView()
let width = bounds.size.width - 1
let height = bounds.size.height - 1
let shadowLayer = CAShapeLayer()
shadowLayer.path = UIBezierPath(roundedRect: CGRectMake(0, 0, width, height), cornerRadius: width/2).CGPath
shadowLayer.fillColor = UIColor.yellowOrange().CGColor
shadowLayer.shadowColor = shadowColor?.CGColor
shadowLayer.shadowPath = shadowLayer.path
shadowLayer.shadowOffset = CGSize(width: 0, height: 1.0)
shadowLayer.shadowOpacity = 1
shadowLayer.shadowRadius = 0
let textLayer = CATextLayer()
textLayer.foregroundColor = UIColor.whiteColor().CGColor
textLayer.string = text
textLayer.fontSize = font.pointSize
textLayer.font = "Calibri-Bold"
textLayer.alignmentMode = kCAAlignmentCenter
textLayer.frame = CGRectMake(0, (height - 16)/2, width, 16)
if let sublayers = layer.sublayers
for sublayer in sublayers
sublayer.removeFromSuperlayer()
layer.insertSublayer(shadowLayer, atIndex: 0)
layer.insertSublayer(textLayer, atIndex: 1)
【讨论】:
以上是关于Objective C - CAGradientLayer 覆盖 UILabel 中的文本?的主要内容,如果未能解决你的问题,请参考以下文章
在 Mac OS X 上结合 Objective-C 和 C/C++