在Interface Builder中使用generics类作为自定义视图

我有一个UIButton的自定义子类:

import UIKit @IBDesignable class MyButton: UIButton { var array : [String]? } 

这是IBDesignable,我已经将它设置为我的故事板中button之一的自定义类。 我想使它通用,使数组不必是一个string对象。 所以,我试过这个:

 import UIKit @IBDesignable class MyButton<T>: UIButton { var array : [T]? } 

但是,我不确定如何将此设置为IB中的类。 我试着把MyButton<String>MyButton<Int> ,但接口生成器只是删除尖括号部分,并得到以下编译错误:

 Command /Applications/Xcode6-Beta4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift failed with exit code 254 

有没有办法使用通用的自定义类,或者不支持?

接口生成器通过ObjC运行时“与您的代码进行对话”。 因此,IB可以只访问在ObjC运行时中可表示的代码的特征。 ObjC不会做generics,所以IB没有办法告诉运行时你的generics类要使用哪种特化。 (Swiftgenerics类不能没有专门化,所以你会得到一个错误,试图实例化MyButton而不是MyButton<WhateverConcreteType>

(当你打破其他的事情时,你可以识别在IB工作的ObjC运行时:试图在nib / storyboard中使用带有outlet / actions的纯Swift类给出了关于ObjC introspection的运行时错误。或者消失,给出关于KVC的运行时错误。

要忽略运行时问题并以稍微不同的方式进行说明,让我们回到IB需要了解的内容。 请记住,nib加载系统是在运行时在故事板中实例化的东西。 所以,即使你的类的genericstypes参数部分不是@IBInspectable ,那么笔尖仍然需要知道要加载的generics类的@IBInspectable 。 所以,为了使IB能够使用generics类来查看视图,IB必须有一个地方让你确定你的类应该使用哪个特殊的类。 它不 – 但是这会提出很好的function要求 。

同时,如果MyButton类涉及到一些通用存储仍然有帮助,也许您可​​以考虑让MyButton引用另一个包含通用存储的类。 (它必须以这样一种方式这样做,即所谓的存储types在编译时是不知道的,否则其他类的types参数将不得不传播回MyButton 。)

我有同样的问题,因为我想要使用以下结构:

 import UIKit protocol MyDataObjectProtocol{ var name:String { get} } class MyObjectTypeOne:MyDataObjectProtocol{ var name:String { get { return "object1"}} } class MyObjectTypeTwo:MyDataObjectProtocol{ var name:String { get { return "object2"}} } class SpecializedTableViewControllerOne: GenericTableViewController<MyObjectTypeOne> { } class SpecializedTableViewControllerTwo: GenericTableViewController<MyObjectTypeTwo> { } class GenericTableViewController<T where T:MyDataObjectProtocol>: UITableViewController { // some common code I don't want to be duplicated in // SpecializedTableViewControllerOne and SpecializedTableViewControllerTwo // and that uses object of type MyDataObjectProtocol. } 

但正如前面的答案所解释的,这是不可能的。 所以我设法解决以下代码:

 import UIKit protocol MyDataObjectProtocol{ var name:String { get} } class MyObjectTypeOne:MyDataObjectProtocol{ var name:String { get { return "object1"}} } class MyObjectTypeTwo:MyDataObjectProtocol{ var name:String { get { return "object2"}} } class SpecializedTableViewControllerOne: GenericTableViewController { required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) super.object = MyObjectTypeOne() } } class SpecializedTableViewControllerTwo: GenericTableViewController { required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) super.object = MyObjectTypeTwo() } } class GenericTableViewController : UIViewController { var object : MyDataObjectProtocol? @IBOutlet weak var label: UILabel! override func viewDidLoad() { label.text = object?.name } // some common code I don't want to be duplicated in // SpecializedTableViewControllerOne and SpecializedTableViewControllerTwo // and that uses object of type MyDataObjectProtocol. } 

现在我的标签sockets显示“object1”,当我链接作为我的视图控制器在故事板的自定义类SpecializedTableViewControllerOne和“object2”如果我链接到SpecializedTableViewControllerTwo