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

19
所以我正在实现一个自定义的"选择器"工具栏,类似于iOS中单选按钮集(UISegmentedControl)。只是一个水平条分为几个选项。
为此,我创建了一个名为SegmentedControlUIControl子类,并实现了自定义绘制。但是,对于这种视图,我需要设置可用选项的选项。我可以从控制器的viewDidLoad()中访问视图并在那里设置它们,但我喜欢使用接口生成器进行这种操作。
所以我发现了这个神奇的东西叫做“用户定义的运行时属性”。我创建了一个带有键buttonValuesString属性,并设置了一个值(这是一个简单的男/女选择器,所以我选择了“Male|Female”)。我发现您可以使用函数self.valueForKey()并传入键来访问这些值。我编写了一个解析器将该字符串转换为数组,然后添加了功能,使drawRect()函数使用该数组设置按钮。
当我运行应用程序时,出现了关于“键值编码合规性”的错误。
所以我查找了一下,发现该类必须具有支持变量来存储属性。好吧,我添加了一个名为buttonValues的实例变量,并将其初始化为""。现在应用程序正常运行,但值从self.valueForKey()函数中为空。我查找了有关如何设置用户定义的运行时属性的教程,但它们没有提供足够的详细信息。他们谈论Key Value Coding-compliance就好像这是我应该知道的东西。
我想确切地知道我必须做什么才能使其正常工作,以及每个步骤的详细信息。
1个回答

28

为了您的目的,您可以使用用户定义的运行时属性或将您的类和属性公开为可在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)")
    }
}

然后在你的storyboard中,将视图的viewLabel属性设置为"Hello",像这样:

Xcode panel showing user-defined runtime attributes

编译并运行后,控制台将显示属性已被正确设置:

init with coder, viewLabel = nil
didSet viewLabel, viewLabel = Hello

@IBDesignable & @IBInspectable

使用@IBDesignable属性对自定义视图进行标记,在 Interface Builder 中会有更好的界面显示,同时在每个属性上设置@IBInspectable属性。以下是相同的类:

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

    init(coder aDecoder: NSCoder!)  {
        super.init(coder: aDecoder)
    }
}

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

带有可检查属性的Attributes Inspector


1
你不应该使用用户定义的运行时属性。使用 IB_DESIGNABLEIBInspectable 来公开具有适当 UI 的属性。更多信息请参见此处 - Zev Eisenberg
1
所以,IBDesignable和IBInspectable非常棒。你不仅可以像上面展示的那样编辑类属性,还可以在IB中预渲染自定义视图(包括自定义绘图),而无需运行应用程序。请参见此链接 - jchitel
1
嗨Nate,你的回答真的帮了我很多,但还有一个问题。当我只使用didst调用运行时属性时,它仍然得到nil值,之后才是实际的值,所以我的Xcode在真正的值出现之前一直获取空指针。 - Bhimbim
3
显然,在Xcode 10/Swift 4.2中不再起作用:在 (MyApp.ViewController) 上无法设置 (url) 用户定义的检查属性: [<MyApp.ViewController 0x7f813620a591> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key url. - taber
2
我们是不是要闭嘴,不再谈论IBDesignables和IBInspectable有多么容易出错?并不是说这是个坏主意,只是在问一下。 - noripcord
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接