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_DESIGNABLEIBInspectable 以适当的 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:如何实现用户定义的运行时属性的主要内容,如果未能解决你的问题,请参考以下文章

Swift | 属性包装器

如何在 swift 中使用 UserDefaults 实现登录/注销导航?

iOS Swift4如何保护接口中定义的计算属性不被赋值?

Swift - 如何实现登录/会话(无代码)

Swift 之自定义 UIAlertController

C# wpf 如何实现自定义控件,布局时,大小发生变化,内部绘制的曲线跟随变化?