I am trying to add a gradient layet to my UILabel
for some reasons the CAGradientLayer
covers my text.
Am I doing anything wrong
- (voi
If you for example need to subclass your UILabel
, then add some CALayer
which covers the text, it is recommended to add CATextLayer
to your CALayer
, here is an swift example:
@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)
}
}
I had the same problem. I made this method to get a reference for the shape layer and or generate it if it wasn't there. This method makes sure to throw that layer in the back so that it doesn't cover the label text layer. Just use this and you should be all good, no extra subclasses required.
- (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;
}
The CAGradientLayer
is covering the text of your label because the text is drawn by the content of the super layer that you explicitly covered by adding a sublayer.
Your easiest solution is to use two views. A UIView
subclass where you override +[UIView layerClass]
and return a [CAGradientLayer]
. Add a good init method to setup your gradient.
Next pup add the UILabel
as a subview of your custom gradient view.