2016-04-22 46 views
2

我有這樣的協議:協議只能被用作通用約束,因爲它有自或相關聯的類型要求

protocol ViewType { 
    associatedtype T: ViewData.View 
    var data:T! {get set} 
} 

ViewData.View是一類

我有一個稱爲TemplateLabel類繼承UILabel和符合ViewType

class TemplateLabel:UILabel, ViewType { 
    var data: ViewData.View.Label! 
} 

我從買這個TemplateLabel toryboard爲UIView並嘗試UIView投進去ViewType來分配data屬性,它

let view = SB.instantiateViewControllerWithIdentifier("view_label").view 
if var v = view as? ViewType { // Error 
    v.data = data // Error 
} 

但我得到的錯誤:

協議「ViewType」只能作爲一種通用的約束,因爲它具有自我或相關類型要求

成員數據不能用於協議類型'ViewType'的值;使用一個通用的約束,而不是

+1

您應該投射到特定的實現,而不是約束協議。投射到'TemplateLabel'。並閱讀更多關於在Swift中的協議:) – werediver

+0

@werediver我有一個特定的原因不直接投到TemplateLabel,它是使事情變得動態,這只是一個簡單的例子 – Arbitur

+0

然後,你需要一個通用的方法...我可以顯示一個例子(在幾分鐘內)。另一種方法是進入刪除類型,但我認爲這太深了。 – werediver

回答

1

我有一個答案給你,但這幾乎是空的代碼。我認爲它可以確實在定義的上下文中有用。

import UIKit 

// Framework 

/** 
* Intended usage: 
* 
*  enum AppStoryboard: BundledStoryboard { 
* 
*   case Login 
*   case Main 
* 
*   var storyboard: UIStoryboard { 
*    return UIStoryboard(name: "\(self)", bundle: nil) 
*   } 
* 
*  } 
*/ 
protocol BundledStoryboard { 

    var storyboard: UIStoryboard { get } 

} 

protocol StoryboardViewController { 

    static var bundledStoryboard: BundledStoryboard { get } 
    static var storyboardId: String { get } 

    static func instantiateFromStoryboard() -> Self 

} 

extension StoryboardViewController { 

    static var storyboardId: String { return "\(self)" } 

    static func instantiateFromStoryboard() -> Self { 
     return bundledStoryboard.storyboard.instantiateViewControllerWithIdentifier(storyboardId) as! Self 
    } 

} 

// Application specific 

enum AppStoryboard: BundledStoryboard { 

    //case Login 
    case Main 

    var storyboard: UIStoryboard { 
     return UIStoryboard(name: "\(self)", bundle: nil) 
    } 

} 

extension StoryboardViewController { 

    static var bundledStoryboard: BundledStoryboard { return AppStoryboard.Main } 

} 

// View-Model relation 

protocol ViewType { 

    associatedtype Model 

    func loadModel(m: Model) 

} 

// ViewController 

final class ViewController: UIViewController, StoryboardViewController, ViewType { 

    override func viewDidLoad() { 
     super.viewDidLoad() 
    } 

    func loadModel(m: UIColor?) { 
     view.backgroundColor = m // Strange example, yeah. 
    } 

} 

// Then somewhere... 

let vc = ViewController.instantiateFromStoryboard() 
vc.loadModel(.redColor()) 

我不認爲你真的需要任何動態解決方案在這裏。您必須知道您正在實例化的內容以及可以接收哪些數據。

相關問題