I'm trying to get a keypath to the selected property of an IBOutlet within a class. But get:
Type 'UIButton?' has no member 'isSelected'
directly accessing the UIButton.isSelected keypath works, but doesn't fulfill my usecase.
@objc class Demo: UIViewController{
@IBOutlet @objc dynamic weak var button: UIButton!
}
var demo = Demo()
print(#keyPath(UIButton.isSelected)) // no error
print(#keyPath(Demo.button.isSelected)) // error
print(#keyPath(demo.button.isSelected)) // error
what am I missing?
#keyPath
is just syntactic sugar that creates a string value, While ensuring that the keyPath
is valid for the object you specify; It helps to prevent crashes when using KVO, since it validates, at compile time, that your keyPath
is valid, rather than crashing at runtime if it isn't.
Accordingly, you don't specify a keyPath
on a particular instance, you specify it on the object type. This is why your first line works and the second two don't.
You specify the specific object instance on which you want to observe the keyPath
when you call addObserver
:
demo.addObserver(someObserver, forKeyPath: #keyPath(UIButton.isSelected), options: [], context: nil)
You could also say
demo.addObserver(someObserver, forKeyPath: "selected", options: [], context: nil)
with the same result
But if you accidentally typed "slected"
instead of "selected"
you wouldn't find out until your app crashed at runtime, while #keyPath(UIButton.isSlected)
will give you a compiler error straight away.