view.frame IBDesignable 加载 xib 时未设置

view.frame is not set when IBDesignable loads xib

我创建了一个简单的 UIView 子类 @IBDesignable。 我重载了 init frameinit coder。我的代码从 .xib 文件加载视图描述。 .xib 文件加载后,我尝试设置:

view.clipsToBounds = true
view.layer.cornerRadius = frame.size.height / 2

获得 "rectangle with circular sides".

问题是当时frame.size.height = 0(在.xib被加载并且我的自定义视图第一次被Interface Builder绘制之后)。

有解决办法吗?

这是我的代码:

@IBDesignable
class CustomUIVIew: UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)
        xibSetup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        xibSetup()
    }

    private var view: UIView!
    private let nibName = "CustomUIView"

    private func xibSetup() {

        view = loadViewFromNib()
        view.frame = bounds
        view.autoresizingMask = [UIViewAutoresizing.flexibleWidth, UIViewAutoresizing.flexibleHeight]
        addSubview(view)
        setupView()
    }

    private func loadViewFromNib() -> UIView {

        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: nibName, bundle: bundle)
        let view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView

        return view
    }

    private func setupView() {

        view.clipsToBounds = true
        view.layer.cornerRadius = frame.size.height / 2
    }
}

谢谢你,卢卡-

prepareForInterfaceBuilder 完成任务

override func prepareForInterfaceBuilder() {
    view.clipsToBounds = true
    view.layer.cornerRadius = bounds.height / 2
}

您应该将任何与尺寸相关的调整移至 layoutSubviews。这样,它不仅会在 IB 中正确呈现,而且在设备上也会正确呈现,如果 window 的大小发生变化,cornerRadius 也会相应地进行调整。