2011-08-26 8 views
11

Estoy tratando de agregar un layet degradado a mi UILabel por alguna razón el CAGradientLayer cubre mi texto. ¿Estoy haciendo algo malObjetivo C: ¿CAGradientLayer cubre el texto en 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]; 
} 

Respuesta

12

El CAGradientLayer está cubriendo el texto de la etiqueta, porque el texto es dibujado por el contenido de la capa de súper que le cubiertos explícitamente por la adición de una subcapa.

Su solución más fácil es usar dos vistas. Una subclase UIView donde anula +[UIView layerClass] y devuelve un [CAGradientLayer]. Agregue un buen método init para configurar su gradiente.

Siguiente cachorro agregue el UILabel como una subvista de su vista personalizada de degradado.

+0

Como Dejando de lado y por curiosidad acerca de una implementación específica que acepto, sería una idea muy pobre en la que confiar incluso si se conociera; No lo he comprobado, pero presumiblemente UILabel usa un CATextLayer a partir de su disponibilidad en iOS 3.2. – Tommy

+0

@Tommy - 'UILabel' no está respaldado por un' CATextLayer' antes o después de 3.2. Puede inspeccionar fácilmente esto con "' po [[someLabel layer] class] '" que producirá un 'CALayer' básico. También es bastante visualmente evidente ya que 'CATextLayer' no tiene un antialiasing sub-píxel, pero' UILabel' sí. – PeyloW

+0

El tipo de clase no siempre es instructivo, como cualquiera que haya probado alguna vez [str isKindOfClass: [NSMutableString class]] puede dar fe. Esa es una cuestión de puente y, obviamente, CALayer no tiene ningún puente de conexión oficialmente con nada, pero suponer que no hay agrupamiento de clase similar o aliasing dentro de CALayer es solo eso: una suposición. Considero que la pista antialias sub-pixel es bastante definitiva. – Tommy

0

Tuve el mismo problema. Hice este método para obtener una referencia para la capa de forma y/o generarla si no estaba allí. Este método se asegura de tirar esa capa en la parte posterior para que no cubra la capa de texto de la etiqueta. Solo use esto y debería estar todo bien, no se requieren subclases adicionales.

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

Si, por ejemplo, necesita subclase su UILabel, a continuación, añadir un poco de CALayer que cubre el texto, se recomienda añadir CATextLayer a su CALayer, aquí es un ejemplo rápido:

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