ivamago
ivamago

Reputation: 43

Some help about key value observing with Slider

I'm practicing with the Key Value Observing, but it's something I do not quite understand.

I have a slider (sldMoving) that, when moved, pretend that console displays "have changed." Although there are other ways to do it, I do well to learn.

In the - (void) viewDidLoad implement it well:

[super viewDidLoad];
[self.sldMoving addObserver:self forKeyPath:@"self.sldMoving.value" options:NSKeyValueObservingOptionNew context:NULL];

and in the observaValueKeyPath:

-(Void) observeValueForKeyPath: (NSString *) keyPath ofObject: (id) object change: (NSDictionary *) change context: (void *) context {
 
  if ([keyPath isEqualToString:@"self.sldMoving.value"]) {
      NSLog(@"I Have change");

Obviously this nonsense I have written does not work.

Error:

2012-08-25 20:17:07.611 Example[3947:c07] * Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ addObserver: forKeyPath:@"sldMoving.value" options:0x101 context:0x0] was sent to an object that is not KVC-compliant for the "sldMoving" property.' * First throw call stack: (0x136b022 0x1060cd6 0x1313a48 0x13139b9 0xadc84f 0xadeb0c 0xaddd3f 0xadc6fd 0x27ff 0x28aa1e 0x1e9401 0x1e9670 0x1e9836 0x1f072a 0x1c1596 0x1c2274 0x1d1183 0x1d1c38 0x1c5634 0x2177ef5 0x133f195 0x12a3ff2 0x12a28da 0x12a1d84 0x12a1c9b 0x1c1c65 0x1c3626 0x1efd 0x1e65) terminate called throwing an exception

How I can solve this?

Thank you.

(excuse me my bad english)

Upvotes: 4

Views: 2447

Answers (3)

Essam Fahmy
Essam Fahmy

Reputation: 2275

Swift 5

Assume that here is your slider property:

var sliderPlayer: UISlider! 

Add action to it to observe its value change as follows:

sliderPlayer.addTarget(self, action: #selector(sliderValueChanged(_:)), for: UIControl.Event.valueChanged)

Your method should be like that:

@objc func sliderValueChanged(_ sender: UISlider)
{
    print(sender.value)
}

Upvotes: 0

Jody Hagins
Jody Hagins

Reputation: 28419

I can understand wanting to learn, but you should probably do it on something other than a controller. In general, UIKit does not support KVO, unless explicitly documented.

If you want to monitor a control, you need to use the standard control action API.

However, to help you understand what is happening with your error...

You are trying this code...

[self.sldMoving addObserver:self forKeyPath:@"self.sldMoving.value" options:NSKeyValueObservingOptionNew context:NULL];

which loosely translates into something like this...

"Yo, sldMoving, I want you to add an observer object (self). Now that observer wants to watch what happens with this key path: self.sldMoving.value, specifically new changes."

So, the sldMoving object looks inside himself to see if that key path makes sense. However, it does not make sense, so it pukes that exception. Why does it not make sense? Well, there is no way to drill down into the path, because those names do not make sense to the UISlider.

Now, if you changed it to be this:

[self addObserver:self forKeyPath:@"sldMoving.value" options:NSKeyValueObservingOptionNew context:NULL];

you will at least get a successful registration. That one talks to the self object and wants it to observe sldMoving.value which it can do, because it have a KVO-compliant sldMoving (assuming that sldMoving is KVO-compliant, which I'm sure it is unless you added it some funky way other than the traditional ways), and it has a value.

Alternatively, you could also do this...

[self.sldMoving addObserver:self forKeyPath:@"value" options:NSKeyValueObservingOptionNew context:NULL];

Now, there are a bunch of gotchas to consider when using KVO, so you should really read the KVO programming guide: http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueObserving/Articles/KVOCompliance.html

Now, don't be surprised if you only see observed changes when you first click the slider, because you will miss all the other value changes...

Upvotes: 1

Brayden
Brayden

Reputation: 1795

Not quite sure why you're wanting to use observeValueForKeyPath but you can easily attach a change action to a slider with the code line below:

[self.sliderElement addTarget:self action:@selector(didChange:) forControlEvents:UIControlEventValueChanged];

Upvotes: 2

Related Questions