添加到UIStackView时,IBDesignable无法正常工作

时间:2016-12-12 14:18:01

标签: ios swift uistackview ibdesignable

我有一个相当简单的IBDesignable RoundedLabel。它在Interface Builder中以及在模拟器中运行时呈现得很好。如果我将视图添加到UIStackView,即使它在IB中渲染得很好,角半径也仅应用于左上角。

import UIKit

@IBDesignable class RoundedLabel: UILabel {
    @IBInspectable var cornerRadius : CGFloat = 46 {
        didSet {
            self.drawTheLabel()
        }
    }

    @IBInspectable var roundRightCorners : Bool = false {
        didSet {
            self.drawTheLabel()
        }
    }

    @IBInspectable var roundLeftCorners : Bool = false {
        didSet {
            self.drawTheLabel()
        }
    }
    @IBInspectable var borderRadius : CGFloat = 3 {
        didSet {
            self.layer.borderWidth = borderRadius
        }
    }
    @IBInspectable var borderColor : UIColor = .black {
        didSet {
            self.layer.borderColor = borderColor.cgColor
        }
    }

    private func drawTheLabel() {
        var tCorners : UIRectCorner = []
        if roundRightCorners {
            tCorners.insert(.topRight)
            tCorners.insert(.bottomRight)
        }
        if roundLeftCorners {
            tCorners.insert(.bottomLeft)
            tCorners.insert(.topLeft)
        }

        let path = UIBezierPath(roundedRect:self.bounds,
                                byRoundingCorners:tCorners,
                                cornerRadii: CGSize(width: cornerRadius, height:  cornerRadius))

        let maskLayer = CAShapeLayer()

        maskLayer.path = path.cgPath
        self.layer.mask = maskLayer
        self.layer.masksToBounds = true
    }

}

不在uistackview

时的视图

enter image description here

添加到uistackview

时的视图

enter image description here

2 个答案:

答案 0 :(得分:1)

问题在于这一行:

let path = UIBezierPath(roundedRect:self.bounds,

self实际 正确bounds之前,该行没有任何意义。但是当正在调用drawTheLabel时,它还没有还有正确的bounds。 (它可能是1000x1000或其他一些无意义的大小;您可以轻松地记录/调试并查找。)您在堆栈视图已对其排列执行布局之前,过早地调用drawTheLabel 子视图。

因此,您添加的蒙版对于最终尺寸的视图来说太大了,您只能看到蒙版的左上角;面具的其他角落一直向右和向下,对视图没有影响,因为它们不会重叠。

答案 1 :(得分:1)

您必须覆盖layoutSubviews并调用super,然后调用drawTheLabel()

每当帧发生变化时,这将应用圆角效果。