Objective c 目标C-CAGradientLayer覆盖UILabel中的文本?

Objective c 目标C-CAGradientLayer覆盖UILabel中的文本?,objective-c,uiview,calayer,cagradientlayer,Objective C,Uiview,Calayer,Cagradientlayer,我正试图将渐变层添加到我的UILabel中,由于某些原因,CAGradientLayer覆盖了我的文本。 我做错什么了吗 - (void)viewDidLoad { [super viewDidLoad]; CAGradientLayer *gradient = [CAGradientLayer layer]; gradient.frame = CGRectMake(0, 0, myLabel.frame.size.width, myLabel.frame.size.heig

我正试图将渐变层添加到我的
UILabel
中,由于某些原因,
CAGradientLayer
覆盖了我的文本。 我做错什么了吗

- (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];
}

CAGradientLayer
覆盖了标签的文本,因为文本是通过添加子层显式覆盖的超层内容绘制的

最简单的解决方案是使用两个视图。一个
UIView
子类,在其中重写
+[UIView layerClass]
并返回一个
[cagradintlayer]
。添加一个好的init方法来设置渐变


下一步,添加
UILabel
作为自定义渐变视图的子视图。

我也遇到了同样的问题。我使用这种方法是为了获得形状层的参考,或者如果它不在那里就生成它。此方法确保将该层放在后面,这样它就不会覆盖标签文本层。只要使用这个,你就应该很好,不需要额外的子类

- (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;
}
-(CAShapeLayer*)getShapeLayerForObject:(UIView*)对象{
CAShapeLayer*maskLayer;
int loc=-1;
对于(int x=0;x-1){
maskLayer=(CAShapeLayer*)[object.layer.sublayers objectAtIndex:loc];
}否则{
maskLayer=[[CAShapeLayer alloc]init];
[object.layer insertSublayer:maskLayer atIndex:0];
}
归来的泥瓦匠;
}

例如,如果您需要对
UILabel
进行子类化,然后添加一些覆盖文本的
CALayer
,建议将
CATextLayer
添加到
CALayer
,下面是一个swift示例:

@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)
    }
}

作为一个旁白,出于对具体实现的好奇,我认为即使已知,依赖它也是一个非常糟糕的想法;我还没有检查,但据推测UILabel使用的是iOS 3.2中可用的CATextLayer?@Tommy-
UILabel
在3.2之前或之后没有
CATextLayer
支持。您可以使用“
po[[someLabel layer]class]
”轻松检查这一点,它将生成一个基本的
CALayer
。由于
CATextLayer
没有亚像素抗锯齿功能,但
UILabel
do,这一点在视觉上也非常明显。但类类型并不总是有指导意义,任何尝试过[str iskindof Class:[NSMutableString Class]]的人都可以证明这一点。这是一个桥接问题,显然CALayer并没有正式免费桥接任何东西,但假设CALayer中没有类似的类集群或别名只是一个假设。我接受你的观点,亚像素反走样的线索是相当确定的。谢谢,奇怪,因为这在UIButton上很好,但在UILabel上不起作用。我认为它们都使用相同的方式来绘制文本。@aryaxt-如果您查看
UIButton.h
头文件,您将看到
UIButton
实际上有一个名为
\u titleView
的实例变量。因此,对于按钮视图,这很简单,因为按钮不绘制自己的文本,这是由子标签子视图完成的。