ios - 在 Interface Builder 中使用泛型类作为自定义 View

标签 ios generics swift interface-builder xcode6

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

import UIKit

@IBDesignable
class MyButton: UIButton {

    var array : [String]?

}

它是 IBDesignable,我已将它设置为 Storyboard中其中一个按钮的自定义类。我想让它成为通用的,这样数组就不必是 String 对象之一。所以,我尝试了这个:

import UIKit

@IBDesignable
class MyButton<T>: UIButton {

    var array : [T]?

}

但是,我不确定如何在 IB 中将其设置为现在的类(class)。我试着把 MyButton<String>MyButton<Int> , 但 Interface Builder 只是删除了尖括号部分并得到以下编译错误:

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

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

最佳答案

Interface Builder 通过 ObjC 运行时与您的代码“对话”。因此,IB 只能访问您的代码中可在 ObjC 运行时中表示的功能。 ObjC 不做泛型,所以 IB 没有办法告诉运行时要使用泛型类的哪个特化。 (如果没有专门化,Swift 泛型类就无法实例化,因此在尝试实例化 MyButton 而不是 MyButton<WhateverConcreteType> 时会出错。)

(当您破坏其他东西时,您可以识别出在 IB 中工作的 ObjC 运行时:尝试在 nib/ Storyboard中使用带有 socket / Action 的纯 Swift 类会给出关于 ObjC 自省(introspection)的运行时错误。保持 socket 连接其对应的代码declaration has changed or gone away 给出关于 KVC 的运行时错误。等等。)

要忽略运行时问题并以稍微不同的方式表达它...让我们回到 IB 需要知道的内容。请记住,nib 加载系统是在运行时实例化 Storyboard 中的任何内容的系统。因此,即使您的类中采用泛型类型参数的部分不是 @IBInspectable , nib 仍然需要知道要加载的泛型类的什么特化。因此,为了让 IB 允许您对 View 使用通用类,IB 必须有一个地方让您确定 nib 应该使用您的类的哪个特化。它没有——但那会很棒 feature request .

与此同时,如果它仍然对您有帮助 MyButton类涉及一些通用存储,也许你可以考虑拥有 MyButton引用另一个包含通用存储的类。 (不过,它必须以这样一种方式进行,即在编译时不知道所述存储的类型——否则其他类的类型参数将不得不传播回 MyButton。)

关于ios - 在 Interface Builder 中使用泛型类作为自定义 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25263882/

相关文章:

ios - 加载 View 后将重复数据添加到 REALM

swift - 让 Swift 泛型玩转重载函数

ios - 如何在运行时为 UIBarButtonItem 设置目标和操作

generics - 如何使用多个参数化类型(使用 where 子句)以便我可以使用任一参数

java - 如何获取 java 参数化集合类的类型?

ios - 在 swift 2.3 中使用 Alamofire 调用 Web 服务时出错

Swift 应用内购买不起作用

casting - 快速子类和类型转换

ios - 如何在按下完成时关闭 SwiftUI 键盘中的键盘?

ios - 保持纵向 View 但让 iOS 随手机旋转