xcode Swift:如何实现用户定义的运行时属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24425324/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Swift: How to implement User Defined Runtime Attributes
提问by jchitel
So I am implementing a custom "chooser" toolbar, like the iOS equivalent of a radio button set (UISegmentedControl
). Just a horizontal bar divided into options.
所以我正在实现一个自定义的“选择器”工具栏,就像一个单选按钮集 ( UISegmentedControl
)的 iOS 等价物。只是一个分为选项的单杠。
To do this, I created a subclass of UIControl
called SegmentedControl
and implemented custom drawing. However, with such a view, I need the option to set what the available options are. I could have just accessed the view from the controller's viewDidLoad()
and set those there, but I like using the interface builder for that kind of stuff.
为此,我创建了一个UIControl
调用SegmentedControl
并实现自定义绘图的子类。但是,对于这样的视图,我需要设置可用选项的选项。我本可以从控制器访问视图viewDidLoad()
并将它们设置在那里,但我喜欢使用界面构建器来处理这种事情。
So I discovered this wonderful thing called "User Defined Runtime Attributes." I created a String
attribute with a key buttonValues
and set a value (this is a simple Male/Female chooser so I went with "Male|Female"). I found out that you can access these values using the function self.valueForKey()
and pass in the key. I made a parser to turn that string into an array and then added functionality for the drawRect()
function to use the array to set up the buttons.
于是我发现了这个奇妙的东西,叫做“用户定义的运行时属性”。我String
用一个键创建了一个属性buttonValues
并设置了一个值(这是一个简单的男/女选择器,所以我选择了“男|女”)。我发现您可以使用该函数访问这些值self.valueForKey()
并传入密钥。我制作了一个解析器将该字符串转换为一个数组,然后为该drawRect()
函数添加了使用该数组设置按钮的功能。
When I ran the app, I got an error about "Key Value Coding-compliance."
当我运行该应用程序时,我收到一条关于“键值编码合规性”的错误消息。
So I looked that up, and I found out that the class has to have backing variables to store the attributes. So fine, I added an instance variable called buttonValues
and initialized it to ""
. Now the app runs fine but the value comes out empty from the self.valueForKey()
function. I looked up tutorials on how to set up user defined runtime attributes but they don't go into enough detail. They talk about Key Value Coding-compliance like it's something I should just know.
所以我查了一下,我发现这个类必须有后备变量来存储属性。很好,我添加了一个名为的实例变量buttonValues
并将其初始化为""
. 现在应用程序运行良好,但该self.valueForKey()
函数的值是空的。我查阅了有关如何设置用户定义的运行时属性的教程,但它们没有提供足够的细节。他们谈论 Key Value Coding-compliance 就像我应该知道的一样。
I would like to know exactly what I must do for this to work properly, in gory detail.
我想确切地知道我必须做什么才能使其正常工作,具体细节。
回答by Nate Cook
For your purposes you can use either user-defined runtime attributes or expose your class and properties as editable in Interface Builder. Either way, you'll want to declare your properties as implicitly unwrapped Optional variables -- IBOutlets
are created the same way. If you need to make other changes once your properties have a value, give them didSet
property observers. The properties will be at their default value during initialization (or nil
if no default was set) and set when the view is added to a superview.
出于您的目的,您可以使用用户定义的运行时属性或将您的类和属性公开为可在 Interface Builder 中编辑。无论哪种方式,您都希望将您的属性声明为隐式解包的 Optional 变量——IBOutlets
以相同的方式创建。如果您的属性具有值后需要进行其他更改,请为它们提供didSet
属性观察者。这些属性将在初始化期间使用默认值(或者nil
如果没有设置默认值),并在将视图添加到超级视图时设置。
User Defined Runtime Attributes
用户定义的运行时属性
This works more or less like you've described above -- here's the simplest version:
这或多或少像你上面描述的那样工作——这是最简单的版本:
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)")
}
}
Then set the viewLabel
attribute to "Hello" on the view in your storyboard, like so:
然后viewLabel
在故事板的视图上将属性设置为“Hello”,如下所示:
When you build & run, the console will show that the property is being set correctly:
当您构建并运行时,控制台将显示属性设置正确:
init with coder, viewLabel = nil
didSet viewLabel, viewLabel = Hello
@IBDesignable & @IBInspectable
@IBDesignable & @IBInspectable
This gives your custom view a much nicer interface in IB -- set the @IBDesignable
attribute on your class and @IBInspectable
attributes on each property. Here's the same class:
这为您的自定义视图在 IB 中提供了一个更好的界面——@IBDesignable
在您的类上设置属性并@IBInspectable
在每个属性上设置属性。这是同一个类:
@IBDesignable class LabeledView : UIView {
@IBInspectable var viewLabel: String!
init(coder aDecoder: NSCoder!) {
super.init(coder: aDecoder)
}
}
Now you can set your inspectable properties at the top of the Attributes Inspector in Interface Builder:
现在,您可以在 Interface Builder 中的 Attributes Inspector 顶部设置可检查属性: