2011-08-26 34 views
11

Tôi đang cố gắng thêm một bố cục gradient vào UILabel vì một số lý do mà CAGradientLayer bao gồm văn bản của tôi. Tôi có làm điều gì sai tráiMục tiêu C - CAGradientLayer bao gồm văn bản trong 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]; 
} 

Trả lời

12

Các CAGradientLayer được bao gồm các nội dung của nhãn của bạn vì văn bản được vẽ bởi nội dung của các lớp siêu mà bạn một cách rõ ràng bao phủ bằng cách thêm một lớp con.

Giải pháp đơn giản nhất của bạn là sử dụng hai chế độ xem. A UIView lớp con nơi bạn ghi đè +[UIView layerClass] và trả lại [CAGradientLayer]. Thêm một phương pháp init tốt để thiết lập gradient của bạn.

Học sinh tiếp theo thêm UILabel làm chế độ xem phụ của chế độ xem gradient tùy chỉnh của bạn.

+0

Là một sang một bên và ra khỏi tò mò về một thực hiện cụ thể mà tôi chấp nhận nó sẽ là một ý tưởng rất nghèo để dựa vào ngay cả khi biết; Tôi đã không kiểm tra nhưng có lẽ UILabel sử dụng một CATextLayer như sẵn có của nó trong iOS 3.2? – Tommy

+0

@Tommy - 'UILabel' không được hỗ trợ bởi' CATextLayer' trước hoặc sau 3.2. Bạn có thể dễ dàng kiểm tra điều này với lớp "po [[someLabel layer]]" "sẽ tạo ra một' CALayer' cơ bản. Nó cũng khá rõ ràng vì 'CATextLayer' không có antialiasing phụ pixel nhưng' UILabel' làm. – PeyloW

+0

Loại lớp không phải lúc nào cũng mang tính hướng dẫn, vì bất kỳ ai đã từng thử [str isKindOfClass: [NSMutableString class]] đều có thể chứng thực. Đó là một vấn đề cầu nối và rõ ràng là CALayer không phải là chính thức miễn phí cầu nối với bất cứ điều gì, nhưng để giả định không có lớp học tương tự clustering hoặc aliasing trong CALayer chỉ là: một giả định. Tôi lấy ý kiến ​​của bạn rằng đầu mối antialiasing phụ pixel là khá dứt khoát mặc dù. – Tommy

0

Tôi gặp sự cố tương tự. Tôi đã thực hiện phương pháp này để có được một tham chiếu cho các lớp hình dạng và hoặc tạo ra nó nếu nó không có ở đó. Phương pháp này đảm bảo ném lớp đó ở phía sau để nó không che phủ lớp văn bản nhãn. Chỉ cần sử dụng này và bạn nên được tất cả tốt, không có lớp con phụ yêu cầu.

- (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

Nếu bạn ví dụ cần phải phân lớp UILabel của bạn, sau đó thêm một số CALayer trong đó bao gồm các văn bản, nó được khuyến khích để thêm CATextLayer để CALayer của bạn, đây là một ví dụ nhanh chóng:

@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) 
    } 
} 
Các vấn đề liên quan