Swift:如何实现用户定义的运行时属性

jch*_*tel 16 xcode ios swift

所以我正在实现一个自定义的"选择器"工具栏,就像iOS相当于单选按钮组(UISegmentedControl).只是一个单杠分为选项.

为此,我创建了一个UIControl被调用SegmentedControl和实现的自定义绘图的子类.但是,有了这样的视图,我需要选项来设置可用的选项.我本来可以从控制器访问该视图viewDidLoad()并在那里设置它们,但我喜欢使用界面构建器来处理那种东西.

所以我发现了一个名为"用户定义的运行时属性"的奇妙之处.我String用键创建了一个属性buttonValues并设置了一个值(这是一个简单的男/女选择器,所以我选择了"男|女").我发现你可以使用该函数访问这些值self.valueForKey()并传入密钥.我创建了一个解析器将该字符串转换为数组,然后添加了该drawRect()函数的功能,以使用该数组来设置按钮.

当我运行该应用程序时,我收到有关"键值编码兼容性"的错误.

所以我查了一下,发现该类必须有支持变量来存储属性.很好,我添加了一个名为的实例变量buttonValues并将其初始化为"".现在应用程序运行正常,但该值从self.valueForKey()函数中清空.我查阅了有关如何设置用户定义的运行时属性的教程,但它们没有详细说明.他们谈论Key Value Coding-compliance,就像我应该知道的那样.

我想知道我必须做些什么才能使这个工作正常,详细的细节.

Nat*_*ook 19

出于您的目的,您可以使用用户定义的运行时属性,或者在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)")
    }
}
Run Code Online (Sandbox Code Playgroud)

然后viewLabel在故事板中的视图上将属性设置为"Hello",如下所示:

Xcode面板显示用户定义的运行时属性

在构建和运行时,控制台将显示正确设置了属性:

init with coder, viewLabel = nil
didSet viewLabel, viewLabel = Hello
Run Code Online (Sandbox Code Playgroud)

@IBDesignable和@IBInspectable

这为您的自定义视图提供了一个更好的IB界面 - @IBDesignable在您的类和@IBInspectable属性上设置每个属性的属性.这是同一个班级:

@IBDesignable class LabeledView : UIView {
    @IBInspectable var viewLabel: String!

    init(coder aDecoder: NSCoder!)  {
        super.init(coder: aDecoder)
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以在Interface Builder中的Attributes Inspector顶部设置可检查属性:

具有可检查属性的Inspector属性

  • 显然这在 Xcode 10/Swift 4.2 中不再起作用:`无法在(MyApp.ViewController)上设置(url)用户定义的检查属性:[<MyApp.ViewController 0x7f813620a591> setValue:forUndefinedKey:]:这个类不是键值编码符合键 url。` (3认同)
  • 我们是否要对 IBDesignables 和 IBInspectable 的 bug 闭嘴?并不是说这是一个坏主意,只是想问问 (2认同)