2013-08-21 22 views
11

我正在嘗試爲一個圓角和筆畫/邊框創建一個標籤(或其他任何視圖)。我可以使用下面的代碼實現了前者:iOS中的行程蒙面CALayer

UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.label.bounds 
             byRoundingCorners:UIRectCornerBottomRight 
              cornerRadii:CGSizeMake(16.0f, 16.0f)]; 

CAShapeLayer *shape = [CAShapeLayer layer]; 
shape.frame = self.label.bounds; 
shape.path = maskPath.CGPath; 

self.label.layer.mask = shape; 

這爲圓角的偉大工程,但使用下面的代碼並不適用行程我想要的方式。取而代之的是生產一個黑色(或其他self.label設定的backgroundColor正方形邊框。

UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.label.bounds 
             byRoundingCorners:UIRectCornerBottomRight 
              cornerRadii:CGSizeMake(16.0f, 16.0f)]; 

CAShapeLayer *shape = [CAShapeLayer layer]; 
shape.frame = self.label.bounds; 
shape.path = maskPath.CGPath; 

// Add stroke 
shape.borderWidth = 1.0f; 
shape.borderColor = [UIColor whiteColor].CGColor; 

self.label.backgroundColor = [UIColor blackColor]; 
self.label.layer.mask = shape; 

任何關於如何應用遮罩路徑後的任意顏色描邊的建議?

回答

35

您正處於形狀層的正確軌道上。但你應該有兩個不同的層次。首先在第一個示例中遮罩您的視圖(遮擋您不想看到的區域)的遮罩層

然後,您也添加形狀圖層,但不能作爲遮罩圖層。另外,請確保不要使用borderWidth和borderColor,而是使用stroke。

// 
// Create your mask first 
// 
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.label.bounds 
             byRoundingCorners:UIRectCornerBottomRight 
              cornerRadii:CGSizeMake(16.0f, 16.0f)]; 

CAShapeLayer *maskLayer = [CAShapeLayer layer]; 
maskLayer.frame = self.label.bounds; 
maskLayer.path = maskPath.CGPath; 
self.label.layer.mask = maskLayer;  

// 
// And then create the outline layer 
// 
CAShapeLayer *shape = [CAShapeLayer layer]; 
shape.frame = self.label.bounds; 
shape.path = maskPath.CGPath; 
shape.lineWidth = 3.0f; 
shape.strokeColor = [UIColor whiteColor].CGColor; 
shape.fillColor = [UIColor clearColor].CGColor; 
[self.label.layer addSublayer:shape]; 

請注意,您的描邊圖層路徑應該在面罩的路徑內(小於)。否則,描邊路徑將被遮罩層遮罩。我已將lineWith設置爲3,這樣可以看到寬度的一半(1.5 px),而另一半則位於蒙版之外。

+0

那種作品,但現在標籤的文字已被「形狀」圖層覆蓋:( –

+1

確定我已經設法通過將掩碼應用到「UIView」並將「UILabel」添加爲子視圖來實現它的工作。非常感謝:) –

+8

StrokeLayer覆蓋標籤,所以我補充說,以解決這個問題 'shape.fillColor = [UIColor clearColor] .CGColor' –

0

如果你的子類爲CALayer,你可以用你想要的掩碼來實例化它,並且也可以覆蓋layoutSubLayers以在該掩碼上包含你想要的邊界。

可以通過幾種方法做到這一點。在Ill下面,通過使用給定掩碼的path並將其分配給要用於構建layoutSubLayers中新邊框的類屬性。這種方法有可能被多次調用,所以我也設置了一個布爾值來跟蹤它。 (也可以指定邊界作爲一個階級屬性,並刪除/重新添加每次現在,我用布爾檢查

斯威夫特3:

class CustomLayer: CALayer { 

    private var path: CGPath? 
    private var borderSet: Bool = false 

    init(maskLayer: CAShapeLayer) { 
     super.init() 
     self.path = maskLayer.path 
     self.frame = maskLayer.frame 
     self.bounds = maskLayer.bounds 
     self.mask = maskLayer 
    } 

    override func layoutSublayers() { 

     let newBorder = CAShapeLayer() 

     newBorder.lineWidth = 12 
     newBorder.path = self.path 
     newBorder.strokeColor = UIColor.black.cgColor 
     newBorder.fillColor = nil 


     if(!borderSet) { 
      self.addSublayer(newBorder) 
      self.borderSet = true 
     } 

    } 

    required override init(layer: Any) { 
     super.init(layer: layer) 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 
}