UIView init覆盖导致IBDesignable崩溃

时间:2015-11-06 14:55:11

标签: ios xcode swift uiview

我对XCode 7.1界面构建器有一个非常奇怪的问题。我有一个非常简单的UIView子类,在storyboard编辑器中渲染得很好

import UIKit

@IBDesignable
class DashboardHeaderView: UIView {

    @IBInspectable
    var maskClipHeight: CGFloat = 40.0

    override func layoutSubviews() {
        super.layoutSubviews()
        self.setMask()
    }

    private func setMask() {
        let mask = CAShapeLayer()
        mask.path = self.createMaskPath()
        self.layer.mask = mask
    }

    private func createMaskPath() -> CGPath {
        let maskPath = UIBezierPath()
        maskPath.moveToPoint(CGPoint(x: bounds.minX, y: bounds.minY))
        maskPath.addLineToPoint(CGPoint(x: bounds.maxX, y: bounds.minY))
        maskPath.addLineToPoint(CGPoint(x: bounds.maxX, y: bounds.maxY - self.maskClipHeight))
        maskPath.addLineToPoint(CGPoint(x: bounds.minX, y: bounds.maxY))
        maskPath.closePath()

        return maskPath.CGPath
    }

}

但是,如果我只添加初始化程序覆盖:

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

失败并出现错误:

  • 错误:IB Designables:无法更新自动布局状态:代理崩溃
  • 错误:IB Designables:无法呈现DashboardHeaderView的实例:代理程序崩溃

我100%确定初始化程序覆盖使其崩溃,因为我已经多次重现它。如果我只是评论它,它会再次起作用。

任何人都知道为什么会发生这种情况,是否有办法解决/解决它?

3 个答案:

答案 0 :(得分:2)

我整天都在苦苦挣扎。你需要实现;

override init(frame: frame)
{
    super.init(frame: frame);
}

这是IBDesignable代理用于实例化类的初始化。所以,在我的情况下,我还有另一个初始化器;

init(frame: CGRect, maxValue: Double, minValue: Double)
{
    super.init(frame: frame)

    self.maxValue = maxValue
    self.minValue = minValue
}

我的init阻止了IBDesignable需要的init。一旦我如上所述覆盖了默认的init,我可以选择将我的init保留原样或将其转换为一个方便的初始化;

convenience init(frame: CGRect, maxValue: Double, minValue: Double)
{
    self.init(frame: frame)

    self.maxValue = maxValue
    self.minValue = minValue
}

现在我可以为IBDesigner添加一些默认行为;

var initForIB = false;

init(frame: CGRect, maxValue: Double, minValue: Double)
{
    super.init(frame: frame)

    self.maxValue = maxValue
    self.minValue = minValue
    initForIB = false;
}

override init(frame: CGRect)
{
    super.init(frame: frame);
    initForIB = true
}

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

override func drawRect(rect: CGRect)
{
    if (initForIB)
    {
        initIBDefaults()
    }
    ...do some other stuff...
}

答案 1 :(得分:0)

我遇到了类似的问题,发现在prepareForInterfaceBuilder()函数之外为ibdesignable视图设置掩码会导致渲染崩溃... prepareForInterfaceBuilder()不是从系统调用的,只是通过interfaceBuilder调用,所以你需要在这里和awakeFromNib()中设置maskView。

答案 2 :(得分:0)

我在另一个SO页面上找到了答案: @IBDesignable crashing agent

您需要同时覆盖init(frame:)init?(coder:)。如果仅覆盖两者之一,则IB渲染将崩溃。