Delegate - How to Use?

2019-01-28 23:55发布

问题:

I think I understand the logic behind a delegate. I got more the problem to use it. How many steps are involved? Do I have to use existing delegates? Or can I use my one ones?

In my example I got the AppDelegate that created many views (Objects / View Controllers) of the same type. Each view should somehow call a method on the AppDelegate to close itself. This would happen when a button within the view is touched. The method call would include the reference of the view (self).

So far I know from other languages responders, event listeners and so on. They are so simple to use.

Can anybody help me. I just found massive examples with a lot of code in the web. It can't be that hard to just call a parent in Objective C.

回答1:

I think you should use for this the NSNotificationCenter

in you AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
...
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(buttonPushed:) name:@"ButtonPushedNotification" object:nil];
}

- (void)applicationWillTerminate:(UIApplication *)application
{
...
...
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

this is the selector it will be called when the notification happens (we are still in the AppDelegate.m)

- (void)buttonPushed:(NSNotification *)notification {
NSLog(@"the button pushed...");
}

and in the ViewController.m when the button pushed (inside the method), you should post a notification like this:

{
...
[[NSNotificationCenter defaultCenter] postNotificationName:@"ButtonPushedNotification" object:nil];
...
}


回答2:

You can create your own:

In MyView1.h:

@class MyView1;

@protocol MyView1Delegate <NSObject>

- (void)closeMyView1:(MyView1 *)myView1;

@end

@interface MyView1 : NSObject
{
    id<MyView1Delegate> _delegate;
}

@property (assign, nonatomic, readwrite) id<MyView1Delegate> delegate;

...

@end

In MyView1.m:

@interface MyView1

@synthesize delegate = _delegate;

...

// The method that tells the delegate to close me
- (void)closeMe
{
    ....
    if ([_delegate respondsToSelector:@selector(closeMyView1:)])
    {
        [_delegate closeMyView1:self];
    }
}

@end

In AppDelegate.h:

#import "MyView1.h"

@interface AppDelegate <MyView1Delegate>
{
    MyView1 *_myView1;
}

...

@end

In AppDelegate.m:

- (void)someCreateViewMethod
{
    _myView1 = [[MyView1 alloc] initWithFrame:NSMakeRect(0, 0, 100, 200)];
    [_myView1 setDelegate:self];
    ...
}


回答3:

An easy way to get what you want is to just start with one view. Then, have each other view be presented modally. When the button in the view is pressed do

[self dismissModalViewControllerAnimated:YES];

And here's something I made a while ago when I was starting iPhone development that might help you with delegates

Delegates

//In parent .m file:
//assign the delegate
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if([segue.identifier isEqualToString:@"segueName"])
    {
        childController *foo = segue.destinationViewController;
        foo.delegate = self;
    }

}

//implement protocol method(s):
- (void) methodName:(dataType*) dataName
{
    //An example of what you could do if your data was an NSDate
    buttonLabel.titleLabel.text = [[date description] substringToIndex:10];
}

//In parent .h file:
//import child header
#import "ChildName.h"

//indicate conformity with protocol
@interface ParentName : UIViewController <ChildNameDelegate>

//In child .h file
//declare protocol
@protocol ChildNameDelegate
- (void) methodName:(dataType*) dataName;
@end

//declare delegate
@property (unsafe_unretained, nonatomic) id<ChildNameDelegate> delegate;


//In child .m file
//synthesize delegate
@synthesize delegate; 

//use method
- (IBAction)actionName:(id)sender 
{
    [delegate methodName:assignedData];
}