Swift:如何实现用户定义的运行时属性
Posted
技术标签:
【中文标题】Swift:如何实现用户定义的运行时属性【英文标题】:Swift: How to implement User Defined Runtime Attributes 【发布时间】:2014-06-26 08:01:10 【问题描述】:所以我正在实现一个自定义的“选择器”工具栏,就像 ios 等效的单选按钮集 (UISegmentedControl
)。只是一个分为选项的水平条。
为此,我创建了UIControl
的子类SegmentedControl
并实现了自定义绘图。但是,有了这样的观点,我需要设置可用选项的选项。我本可以从控制器的 viewDidLoad()
访问视图并将其设置在那里,但我喜欢使用界面生成器来处理这类东西。
所以我发现了这个奇妙的东西,叫做“用户定义的运行时属性”。我创建了一个带有buttonValues
键的String
属性并设置了一个值(这是一个简单的男性/女性选择器,所以我选择了“男性|女性”)。我发现您可以使用函数self.valueForKey()
访问这些值并传入密钥。我制作了一个解析器将该字符串转换为一个数组,然后为drawRect()
函数添加了功能以使用该数组来设置按钮。
当我运行应用程序时,我收到一个关于“键值编码合规性”的错误。
所以我查了一下,发现这个类必须有支持变量来存储属性。很好,我添加了一个名为buttonValues
的实例变量并将其初始化为""
。现在应用程序运行良好,但 self.valueForKey()
函数中的值是空的。我查找了有关如何设置用户定义的运行时属性的教程,但它们没有详细说明。他们谈论的关键值编码合规性就像我应该知道的那样。
我想确切地知道我必须做什么才能使其正常工作,详细说明。
【问题讨论】:
【参考方案1】:出于您的目的,您可以使用用户定义的运行时属性或将您的类和属性公开为在 Interface Builder 中可编辑。无论哪种方式,您都希望将您的属性声明为隐式展开的可选变量——IBOutlets
的创建方式相同。如果您的属性有值后需要进行其他更改,请给他们didSet
属性观察者。属性将在初始化期间为其默认值(如果未设置默认值,则为nil
)并在视图添加到超级视图时设置。
用户定义的运行时属性
这或多或少像你上面描述的那样工作——这是最简单的版本:
class LabeledView : UIView
var viewLabel: String!
didSet
println("didSet viewLabel, viewLabel = \(self.viewLabel)")
init(coder aDecoder: NSCoder!)
super.init(coder: aDecoder)
println("init with coder, viewLabel = \(self.viewLabel)")
然后在情节提要的视图中将viewLabel
属性设置为“Hello”,如下所示:
当你编译运行时,控制台会显示属性设置正确:
init with coder, viewLabel = nil
didSet viewLabel, viewLabel = Hello
@IBDesignable & @IBInspectable
这为您的自定义视图在 IB 中提供了一个更好的界面——在您的类上设置 @IBDesignable
属性并在每个属性上设置 @IBInspectable
属性。这是同一类:
@IBDesignable class LabeledView : UIView
@IBInspectable var viewLabel: String!
init(coder aDecoder: NSCoder!)
super.init(coder: aDecoder)
现在您可以在 Interface Builder 的 Attributes Inspector 顶部设置可检查的属性:
【讨论】:
您不应该使用用户定义的运行时属性。使用IB_DESIGNABLE
和 IBInspectable
以适当的 UI 公开属性。更多信息here.
是的,IBDesignable 和 IBInspectable 很棒。您不仅可以如上所示编辑类属性,还可以在 IB 中实际预渲染您的自定义视图(包括自定义绘图),而无需运行您的应用程序。见this。
嗨,您的回答对我帮助很大,但仍然存在一个问题。当我只用 didst 调用运行时属性时,它仍然得到 nil 值,然后是这个值,所以我的 Xcode 在真正的值到来之前不断得到空指针。
显然这在 Xcode 10/Swift 4.2 中不再起作用:Failed to set (url) user defined inspected property on (MyApp.ViewController): [<MyApp.ViewController 0x7f813620a591> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key url.
我们是不是要闭嘴说 IBDesignables 和 IBInspectable 有多少漏洞?不是说这是一个坏主意,只是问以上是关于Swift:如何实现用户定义的运行时属性的主要内容,如果未能解决你的问题,请参考以下文章