簡體   English   中英

UIView init 覆蓋導致 IBDesignable 崩潰

[英]UIView init override causes IBDesignable to crash

我對 XCode 7.1 界面構建器有一個非常奇怪的問題。 我有一個非常簡單的 UIView 子類,它在故事板編輯器中呈現良好

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% 確定該初始化程序覆蓋使它崩潰,因為我已經復制了幾次。 如果我只注釋掉它,它會再次起作用。

任何人都知道為什么會發生這種情況,以及是否有辦法修復/解決它?

我一整天都在為此苦苦掙扎。 您需要實施:

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 原樣或將其轉換為方便的 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...
}

我遇到了類似的問題,發現在 prepareForInterfaceBuilder() 函數之外為 ibdesignable 視圖設置掩碼會導致渲染崩潰……prepareForInterfaceBuilder() 不是從系統調用的,而是由 interfaceBuilder 調用的,因此您需要設置此處和awakeFromNib() 中的maskView。

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

您需要覆蓋init(frame:)init?(coder:) 如果僅覆蓋兩者之一,IB 渲染將崩潰。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM