首页 文章

协议只能用作通用约束,因为它具有Self或关联类型要求

提问于
浏览
2

我有这个协议:

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

ViewData.View 是一个 class

我有一个名为 TemplateLabel 的类,它继承 UILabel 并符合 ViewType

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

我从故事板中将 TemplateLabel 作为 UIView 并尝试将 UIView 转换为 ViewType 以将 data 属性赋予它

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

但我得到错误:

协议'ViewType'只能用作通用约束,因为它具有Self或相关类型要求成员'data'不能用于协议类型'ViewType'的值;改为使用通用约束

1 回答

  • 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())
    

    我认为你真的不需要任何动态解决方案 . 您必须知道您要实例化的内容以及它可以接收的数据 .

相关问题