在Interface Builder中使用泛型类作为自定义视图 [英] Use a generic class as a custom view in Interface Builder

查看:132
本文介绍了在Interface Builder中使用泛型类作为自定义视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  import UIKit 

@IBDesignable
class MyButton:UIButton {

var array:[String]?






它是IBDesignable,我将它设置为自定义类为我的故事板中的其中一个按钮。我想使它成为通用的,以便数组不必是String对象之一。所以,我试过了:

  import UIKit 

@IBDesignable $ b $ class MyButton< T> ;:UIButton {

var array:[T]?


$ / code>

然而,我不确定如何将它设置为类现在在IB。我试着把 MyButton< String> MyButton< Int> ,但Interface Builder只删除了尖括号部分,以下编译错误:

$ p $ 命令/Applications/Xcode6-Beta4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr / bin / swift失败,退出代码为254

有没有办法使用泛型自定义类,或者是不支持的吗?

解决方案

Interface Builder通过ObjC运行时向您的代码讲话。因此,IB可以只访问可在ObjC运行时中表示的代码功能。 ObjC不会去做泛型,所以IB没有办法告诉运行时你的泛型类需要使用哪些特化。 (并且Swift泛型类不能在没有专门化的情况下被实例化,所以当尝试实例化 MyButton 而不是 MyButton< WhateverConcreteType>>时出现错误; 。)



(当你打破其他事情时,你可以识别在IB工作的ObjC运行时:尝试使用纯Swift类在一个笔尖/故事板中的插座/动作给出了关于ObjC内省的运行时错误。留下一个连接的插座,它的相应的代码声明已经改变或消失,给出了关于KVC的运行时错误。)等等。

忽略运行时问题,并以稍微不同的方式进行......让我们回到IB需要知道的东西。请记住,nib加载系统是在运行时实例化故事板中的任何内容。因此,即使你的类的一部分接受泛型类型参数不是 @IBInspectable ,该笔尖仍然需要知道要加载的泛型类的特殊性。因此,IB允许您使用通用类来查看视图,IB必须有一个地方让您确定您的班级应该使用哪个专业化班级。它不会 - 但这会产生一个很棒的功能请求



同时,如果你的 MyButton 类涉及到一些通用存储仍然有帮助,也许你可以看看 MyButton 引用另一个包含通用存储的类。 (它必须这样做,以便在编译时不知道所述存储的类型,否则该其他类的类型参数将不得不传播回 MyButton 。)


I have a custom subclass of UIButton:

import UIKit

@IBDesignable
class MyButton: UIButton {

    var array : [String]?

}

It is IBDesignable and I have set it as the custom class for one of the buttons in my storyboard. I would like to make it generic so that the array does not have to be one of String objects. So, I tried this:

import UIKit

@IBDesignable
class MyButton<T>: UIButton {

    var array : [T]?

}

However, I am unsure how to set this as the class now in IB. I tried putting MyButton<String> or MyButton<Int>, but Interface Builder just removes the angle brackets portion and gets the following compile error:

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

Is there a way to use a generic custom class, or is it not supported?

解决方案

Interface Builder "talks" to your code through the ObjC runtime. As such, IB can can access only features of your code that are representable in the ObjC runtime. ObjC doesn't do generics, so there's not a way for IB to tell the runtime which specialization of your generic class to use. (And a Swift generic class can't be instantiated without a specialization, so you get an error trying to instantiate a MyButton instead of a MyButton<WhateverConcreteType>.)

(You can recognize the ObjC runtime at work in IB when you break other things: Attempting to use a pure Swift class with outlets/actions in a nib/storyboard gives runtime errors about ObjC introspection. Leaving an outlet connected whose corresponding code declaration has changed or gone away gives runtime errors about KVC. Et cetera.)

To ignore the runtime issues and put it in a slightly different way... let's go back to what IB needs to know. Remember that the nib loading system is what instantiates anything in a storyboard at runtime. So even if the parts of your class that take a generic type parameter aren't @IBInspectable, the nib still needs to know what specialization of your generic class to load. So, for IB to let you use generic classes for views, IB would have to have a place for you to identify which specialization of your class the nib should use. It doesn't — but that'd make a great feature request.

In the meantime, if it's still helpful for your MyButton class to involve some generic storage, perhaps you could look into having MyButton reference another class that includes generic storage. (It'd have to do so in such a way that the type of said storage isn't known at compile time, though — otherwise the type parameters of that other class would have to propagate back to MyButton.)

这篇关于在Interface Builder中使用泛型类作为自定义视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆