2017-01-22 161 views
2

我有一個UIView加載某些類型和名稱的筆尖的延伸:獲取實際類型從一個普通的返回類型

extension UIView { 

    class func fromNib<T : UIView>() -> T? { 

     guard let nib = Bundle(for: T.self).loadNibNamed(String(describing: T.self), owner: nil, options: nil)?[0] 
      else { 
       return nil 
     } 
     return nib as? T 
    } 
} 

現在在我的Hint類(這是一個子類UIView)我用上面的延伸是這樣的:

if let view = Hint.fromNib(){ 
     self.addSubview(view) 
     view.frame = self.bounds   
} 

這不起作用,因爲T.self結果總是UIView的,即使有一絲類是什麼fromNib方法被調用。如果我嘗試像這樣硬編碼類:

Bundle(for: Hint.self).loadNibNamed(String(describing: Hint.self), owner: nil, options: nil) 

然後一切正常。如何獲得實際調用fromNib()方法的類的類型名稱?

這裏是我的提示類:

class Hint:UIView { 

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

     if let view = UIView.fromNib(){ 
      self.addSubview(view) 
      view.frame = self.bounds 

     } 

    } 

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

     if let view = UIView.fromNib(){ 
      self.addSubview(view) 
      view.frame = self.bounds 
     } 
    } 

    override func prepareForInterfaceBuilder() { 
     super.prepareForInterfaceBuilder() 
     if let view = UIView.fromNib(){ 
      self.addSubview(view) 
      view.frame = self.bounds 
     } 
    } 

} 

所以一切都非常簡單。一個nib文件只有一個標籤和一個圖像視圖,但我認爲這與當前問題幾乎無關。

+0

嘗試'讓提示:提示= UIView.fromNib()'。我遇到了同樣的問題。 – EmilioPelaez

+1

您是否曾嘗試在調用方法之前定義類型?即如果'讓視圖:提示= Hint.fromNib()' –

+0

哎呀..埃米利奧以10秒爲 –

回答

1

你想知道的類型fromNib()被稱爲類別方法內:

extension UIView { 
    class func fromNib<T : UIView>() -> T? { 
     guard 
      let nibs = Bundle(for: self).loadNibNamed(String(describing: self), owner: nil, options: nil), 
      let nib = nibs.first 
      else { 
       return nil 
     } 

     return nib as? T 
    } 
} 

以下:

if let viewFromXib = MyXib.fromNib(){    
    view.addSubview(viewFromXib) 
    viewFromXib.frame = CGRect(origin: CGPoint.zero, size: CGSize(width: 30, height: 30)) 
    print(viewFromXib) 
} 

作品和版畫:

<TESTS.MyXib: 0x7f9531408aa0; frame = (0 0; 30 30); autoresize = W+H; layer = <CALayer: 0x60000002b8e0>> 

我真的不明白的返回類型T是如何推斷雖然。


更新:

我挖的返回類型T是如何推斷答案是:沒有。

此:

class func fromNib() -> UIView? { 
    guard 
     let nibs = Bundle(for: self).loadNibNamed(String(describing: self), owner: nil, options: nil), 
     let nib = nibs.first 
     else { 
      return nil 
    } 

    return nib as? UIView 
} 

等同。

所以即使這個答案是解決伊核問題,不回答這個問題。

+0

是的,這工作。謝謝一堆! :) – Whirlwind

+0

謝謝!好問題也! – shallowThought

+0

用更多(也許很淺)的想法更新了答案。 – shallowThought

1

我碰到了完全相同的問題,完全相同的方法,甚至命名爲相同。我無法使用當前的類類型,因爲編譯器假定它是UIView而不是它的子類。

會發生什麼事是,Hint.fromNib()結束是完全一樣的爲UIView.fromNib(),因爲T不依賴於它被稱爲的類,所以T被推斷爲一個UIView。你需要做的是通過指定你期望得到的視圖類型來幫助編譯器推斷出正確的類型。

let hint: Hint? = UIView.fromNib()

我想補充一點,當你正確使用guardfirst[0]更安全,所以我會改變你的方法是這樣的:

let bundle = Bundle(for: T.self) 
let nib = bundle.loadNibNamed(String(describing: T.self), owner: nil, options: nil) 
guard let view = nib?.first as? T else { 
    return nil 
} 
return view 
+0

好吧,我也會嘗試你的代碼。 :T.self)'不會編譯一個顯式的AnyClass需要...編譯器提示這樣的:'讓包=包(用於:T.self爲AnyClass)' – Whirlwind

+0

可悲的是,同樣的結果,我只。獲得期望的結果,這是加載到我的定製視圖和在設計時(在故事板中可見)呈現的筆尖的1)具有含量,和2)裝在當然運行時,如果我硬編碼'Hint.self'代替' T.self' – Whirlwind

+0

我已經添加了我的提示類的實現...我希望它可以用於解決這個問題。 – Whirlwind