2017-05-24 26 views
0

我很確定@IBOutletsuper.awakeFromNib()之後被初始化,但它是零?@ awakeFromNib中的IBOutlet未初始化

重現步驟:

  1. 創建一個新的子UIView的; MyView
  2. 創建一個.xib UIView並將「文件所有者」設置爲「MyView」
  3. 在UIViewController的視圖中的故事板中,將「Custom Class」設置爲MyView。
  4. 連接@IBOutlet
  5. 這會給你錯誤。 4.

更新:
這不,如果你直接使用故事板工作。

  1. 創建一個子UIView; MyView
  2. 在Storyboard UIViewController視圖中添加一個標籤。
  3. 在一個UIViewController的視圖設置「自定義類」故事板到MyView的
  4. 連接@IBOutlet
  5. 這工作。

    import UIKit 
    
    class MyView: UIView { 
    
    @IBOutlet weak var myLabel: UILabel! 
    
    override func awakeFromNib() { 
        super.awakeFromNib() 
        self.myLabel.text = "Hello world" 
    } 
    
    override func didMoveToSuperview() { 
        self.myLabel.text = "Hello world" 
    } 
    
    override func layoutSubviews() { 
        self.myLabel.text = "Hello world" 
    } 
    
    override func didMoveToWindow() { 
        self.myLabel.text = "Hello world"   
    } 
    
    } 
    
+1

確定插座已連接? – Oskar

+0

相同:致命錯誤:意外地發現零,同時展開一個可選值 –

+0

誰擁有導航欄?如果它是一個頂級的nib對象,那麼你需要連接一個強引用,否則它會在你到達awakeFromNib時解除分配。 – Darren

回答

0

故事板不加載xibs。你必須在你的視圖中明確加載xib。故事板創建使用init(coder:)的觀點:

func loadNib() -> UIView? { 
    guard 
     let nibName = NSStringFromClass(type(of: self)).components(separatedBy: ".").last, 
     let bundle = Bundle(for: type(of: self)) 
     let views = bundle.loadNibNamed(nibName, owner: self, options: nil), 
     let contentView = views.first as? UIView 
    else { 
     return nil 
    } 

    return contentView 
} 

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

    let contentView = self.loadNib()! 
    self.addSubview(contentView) 
    contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight] 
    contentView.frame = self.bounds 
} 

這將加載XIB的根視圖,將其添加到視圖。由於我們通過self作爲所有者,網點將被連接。