我的应用程序有一个详细视图控制器的协议,说明他们必须有一个viewModel属性:
protocol DetailViewController: class {
var viewModel: ViewModel? {get set}
}
Run Code Online (Sandbox Code Playgroud)
我还有一些实现协议的不同类:
class FormViewController: UITableViewController, DetailViewController {
// ...
}
class MapViewController: UIViewController, DetailViewController {
// ...
}
Run Code Online (Sandbox Code Playgroud)
我的主视图控制器需要一个可以设置为UIViewController实现DetailViewController协议的任何子类的属性.
不幸的是我找不到任何关于如何做到这一点的文档.在Objective-C中,它将是微不足道的:
@property (strong, nonatomic) UIViewController<DetailViewController>;
Run Code Online (Sandbox Code Playgroud)
似乎Swift中没有可用的语法来执行此操作.我最接近的是在我的类定义中声明一个泛型:
class MasterViewController<T where T:UIViewController, T:DetailViewController>: UITableViewController {
var detailViewController: T?
// ...
}
Run Code Online (Sandbox Code Playgroud)
但后来我得到一个错误,说"Class'MasterViewController'没有实现其超类的必需成员"
这似乎在Swift中应该像在Objective-C中一样容易,但是我找不到任何可以表明我如何去做的事情.
在Objective-C中,可以编写类似的东西:
@property(retain) UIView<Protocol1, Protocol2, ...> *myView;
Run Code Online (Sandbox Code Playgroud)
但是如何在swift中编写这段代码呢?
我已经知道如何使属性符合许多协议,但它不能使用继承:
var myView: ??? protocol<Protocol1, Protocol2, ...>
Run Code Online (Sandbox Code Playgroud)
编辑:
我使用许多UIView子类型UIImageView,UILabel或者其他类型,我需要使用一些UIView属性以及协议中定义的一些方法.在最坏的情况下,我可以UIViewProtocol使用所需的属性创建一个,但我知道在Swift中是否可以声明一个属性/变量,其类型和一些协议符合.
在Objective-C中,您可以将类型定义为给定类的类并实现协议:
- (UIView <Protocol> *)someMethod;
Run Code Online (Sandbox Code Playgroud)
这将告诉返回的值someMethod是UIView实现给定协议Protocol.有没有办法在Swift中强制执行类似的操作?
这不是In Swift的副本,我如何声明符合一个或多个协议的特定类型的变量?.这个问题是关于一个特定的用例,我需要一个元类型,并且如何做到这一点绝对不明显.
Swift 4允许声明一个变量,它是一个子类并符合多个协议:
var myVariable: MyClass & MyProtocol & MySecondProtocol
Run Code Online (Sandbox Code Playgroud)
我需要这样的一致性但不是实例,而是类型本身.但是对于以下语法:
var classForCell: UICollectionViewCell.Type & AdditionalHeightable.Type
Run Code Online (Sandbox Code Playgroud)
给我这个错误:
非协议,非类型类型'UICollectionViewCell.Type'不能在协议约束类型中使用
如何声明作为子类的元类型并符合Swift 4中的协议?
我想定义一个UIViewController符合哪种类型的变量P1.
题:
码:
protocol P1 {
func f1();
}
var v1 : P1 //But needs to be a UIViewController which conforms to `P1`
Run Code Online (Sandbox Code Playgroud) 由于有2个协议P1和P2,可以指定符合两国的协议,如类型:
typealias P = protocol<P1, P2>
Run Code Online (Sandbox Code Playgroud)
是否有类似的方式来指定类型的类型,并且也符合协议,例如像这样的东西(不起作用):
typealias P = UIView: P1
Run Code Online (Sandbox Code Playgroud)