ios - Protocol 只能用作泛型约束,因为它有 Self 或关联类型要求

标签 ios swift generics protocols

我有这个协议(protocol):

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!
}

我从 Storyboard中获取此 TemplateLabel 作为 UIView 并尝试将 UIView 转换为 ViewType 以分配它的 data 属性

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

但是我得到错误:

Protocol 'ViewType' can only be used as a generic constraint because it has Self or associated type requirements

Member 'data' cannot be used on value of protocol type 'ViewType'; use a generic constraint instead

最佳答案

我有一个答案给你,但那几乎是裸代码。我认为它真的在定义的上下文中很有用。

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

我认为您在这里真的不需要任何动态解决方案。您必须知道您正在实例化什么以及它可以接收哪些数据。

关于ios - Protocol 只能用作泛型约束,因为它有 Self 或关联类型要求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36795010/

相关文章:

php - 从我的 iOS 应用测试多部分表单 HTTP POST

iphone - 什么是 CG 插值质量?

ios - Swift:在特定浏览器选项卡中打开 URL?

swift - 仅在落地时跳跃

ios - 可选类型 'Float?' 的值未展开;您是要使用 '!' 还是 '?' ?

java - 在Java中使用泛型,有人可以解释一下我做错了什么吗

iphone - 当用户与 ios 中的 slider 交互时, ScrollView 不应滚动

ios - 如何将 ViewController 添加到我的页眉中?

c++ - 节点代码或算法的通用树父

ios - 符合协议(protocol)和类的 Swift 属性