简体   繁体   中英

UISlider delegate/binding to another object?

I am not a master of Objective-C and I have some problem with something simple to do in Javascript (create and bind a listener)... Just cant figure out how to do it in Objective-C.

So I have an UISlider. Whenever the user starts dragging it, I want to fire X function from an object (in this case a MKAnnotation, but any NSObject, Controller, etc need to be able to listen).

Is a delegate the right thing to use for this? I tried this without success :.

In my ViewController.h

@protocol TimeSliderDelegate <NSObject>
- (void)sliderValueChanged:sender;
@end

@interface ViewController : UIViewController<MKMapViewDelegate>{
    IBOutlet UISlider *timeSlider;
    IBOutlet MKMapView *mapView;
    id <TimeSliderDelegate> delegate;
}

@property (retain) id delegate;

Then, in my ViewController.m, I bound my valueChanged from my UISlider to this (tried with [self delegate] and [sender delegate] without result..) :

- (IBAction)timeSliderValueChanged:(id)sender {
    [delegate sliderValueChanged:sender];
}

It crashes here, saying cant find selector sliderValueChanged for delegate instance ... I'll still elaborate the rest of my code.


My test object is an MKAnnotation that I add in my MKMapView inside my ViewController, nothing fancy here I just add it like this.

Annotation *annotation = [[Annotation alloc] init];

CLLocationDegrees lat = 0;
CLLocationDegrees lng = 0;
[(Annotation*) annotation setCoordinate:CLLocationCoordinate2DMake(lat, lng)];
[mapView addAnnotation:annotation];

Then in my Annotation.h, I import my viewController and set it as a TimeSliderDelegate and implementing sliderValueChanged.

#import "ViewController.h"
@protocol TimeSliderDelegate;

@interface Annotation : MKAnnotation<TimeSliderDelegate>
- (void)sliderValueChanged:(id)sender;

Finally, this was my code in Annotation.m. Never fired.

- (void)sliderValueChanged:(id)sender{
    NSLog(@"state changed");
}

Still trying to figure out how I can get it to fire sliderValueChanged in my Annotation but not totally sure if Im on the track.

If anyone more experienced can lead me, that would be greatly appreciated :).

It looks like you haven't told the mainViewController that Annotation is the delegate. My guess is that you will have to include something like the following in your Annotation.m.

[self.parentViewController setDelegate:self];

Also, when calling delegates, you should check if they exist first in your mainViewController.m.

- (IBAction)timeSliderValueChanged:(id)sender {
    if ( [delegate respondsToSelector:@selector(sliderValueChanged:) )
        [delegate sliderValueChanged:sender];
}

I hope that at least gets you pointed in the right direction.

In general your delegate approach is correct. But probably you want to listen with many objects on the same value change (of the slider). So it is probably more convinient to just send a global notification. Have a look at:

NSNotificationCenter and NSNotification .

But if you want to stick to your delegate approach. I cannot see a real error in the code you provided. Your protocol definition is not perfect here. You forgot the type (id) for your parameter. But thats not the problem i guess. Also your property is not typed as id <TimeSliderDelegate> . Did you forgot to synthesize the property?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM