3

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?

Jan
  • 1,827
  • 2
  • 16
  • 29
  • You don't need to use a key path to access a property on an object instance. Just `print(demo.button.isSelected)` – Paulw11 Jul 08 '19 at 07:58
  • This is just a radical simplified example. I'm trying to use it in the context of KVO but this is not needed within the example. – Jan Jul 08 '19 at 08:04
  • Ok. The answer is kind of the same though - you use keypath with an object, not with an instance. You just use the property with the instance. You can also use the object key path with addObserver, specifying the instance on which you want to observe the keypath – Paulw11 Jul 08 '19 at 08:11

1 Answers1

3

#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.

Paulw11
  • 108,386
  • 14
  • 159
  • 186