一尘不染

将通用类用作Interface Builder中的自定义视图

swift

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

import UIKit

@IBDesignable
class MyButton: UIButton {

    var array : [String]?

}

它是IBDesignable,并且已将其设置为情节提要中按钮之一的自定义类。我想使其通用,以便该数组不必是String对象之一。所以,我尝试了这个:

import UIKit

@IBDesignable
class MyButton<T>: UIButton {

    var array : [T]?

}

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

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

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


阅读 186

收藏
2020-07-07

共1个答案

一尘不染

Interface
Builder通过ObjC运行时与代码“对话”。这样,IB只能访问在ObjC运行时中可表示的代码功能。ObjC不执行泛型,因此IB无法告诉运行时要使用泛型类的哪个专业化。(而且Swift泛型类不能在没有专门化的情况下实例化,因此尝试实例化a
MyButton而不是实例化时会出现错误MyButton<WhateverConcreteType>。)

(当您破坏其他情况时,您可以识别IB中的ObjC运行时:尝试在nib /
storyboard中使用带有出口/动作的纯Swift类会产生有关ObjC自省的运行时错误。将出口连接起来,其对应的代码声明已更改或消失会导致有关KVC的运行时错误。等等。)

要忽略运行时问题,并以稍微不同的方式进行处理…让我们回到IB需要了解的内容。请记住,笔尖加载系统是在运行时实例化情节提要中任何内容的系统。因此,即使您的类中带有泛型类型参数的部分不是@IBInspectable,笔尖仍然需要知道要加载的泛型类的什么特殊化。因此,为了使IB允许您将通用类用于视图,IB必须有一个位置供您标识笔尖应使用哪种专业。不需要-
但这会带来很棒的功能要求

同时,如果让您的MyButton班级涉及一些通用存储仍然很有帮助,也许您可​​以考虑MyButton参考另一个包含通用存储的类。(尽管这样做的方式必须确保在编译时不知道所述存储的类型,否则其他类的类型参数必须传播回MyButton。)

2020-07-07