How to make iOS callback functions?

I cannot figure out how to create a function that will provide information to the parent object that did something, so I need your help. An example of what I want to do:

  • ViewController class is an instance of the BottomView class and adds it as a subtask.
  • Make a call to an instance of the BottomView class to start animating something.
  • After the animation ends, I want to give a sign that the animation has ended with the ViewController class ViewController that it can free / remove the BottomView instance from itself.

I need something like a callback. Could you help me?

+4
source share
5 answers

1. You can do this with blocks!

You can pass some block to BottomView.

2. Or you can do this with a targeted action.

you can go to the BottomView selector @selector @selector(myMethod:) as an action, and a pointer to the view controller as the target. And after the animation finishes, use the performeSelector: method.

3. Or you can define @protocol delegation and implement methods in your viewController, and add the delegate property to the BottomView. @property (assign) delegate id;

If you do some animations in your BottomView, you can use UIView

 animateWithDuration:delay:options:animations:completion: 

which uses blocks as callbacks

 [UIView animateWithDuration:1.0f animations:^{ }]; 

update:

in ButtomView.h

 @class BottomView; @protocol BottomViewDelegate <NSObject> - (void)bottomViewAnimationDone:(BottomView *) bottomView; @end @interface BottomView : UIView @property (nonatomic, assign) id <BottomViewDelegate> delegate; ..... @end 

in ButtomView.m

 - (void)notifyDelegateAboutAnimationDone { if ([self.delegate respondsToSelector:@selector(bottomViewAnimationDone:)]) { [self.delegate bottomViewAnimationDone:self]; } } 

and after the animation you need to call [self notifyDelegateAboutAnimationDone];

you must set the ViewController class to validate the BottomViewDelegate protocol

in MyViewController.h

  @interface MyViewController : UIViewController <BottomViewDelegate> ... @end 

and fe in viewDidLoad you should set bottomView.delegate = self;

+6
source

You can do something like this

 @interface BottomView : UIView @property (nonatomic, copy) void (^onCompletion)(void); - (void)start; @end @implementation BottomView - (void)start { [UIView animateWithDuration:0.25f animations:^{ // do some animation } completion:^(BOOL finished){ if (self.onCompletion) { self.onCompletion(); } }]; } @end 

Which would you use as

 BottomView *bottomView = [[BottomView alloc] initWithFrame:...]; bottomView.onCompletion = ^{ [bottomView removeFromSuperview]; NSLog(@"So something when animation is finished and view is remove"); }; [self.view addSubview:bottomView]; [bottomView start]; 
+12
source

if you specifically want to just run the function after the animation has occurred, you can leave just by using this:

 [UIView animateWithDuration:0.5 animations:^{ //do animations } completion:^(BOOL finished){ //do something once completed }]; 
+1
source

Since you use animation, a more specific way to handle it is to use animation delegates. You can set the delegate of your animation to the viewcontroller so that after the animation is completed below, the method is called in your view manager.

 -(void) animationDidStop:(CAAnimation *)anim finished:(BOOL)flag 

To do this in the second step that you mentioned, you must pass the viewcontroller as an additional parameter so that you can set the animation delegate there.

+1
source

Thanks so much for all of you. I tried two ways: a selector and a delegate. This is cool, and I believe that I understand these mechanisms. I found one strange thing:

ViewController.h

 #import <UIKit/UIKit.h> #import "BottomPanelView.h" @interface ViewController : UIViewController <BottomPanelViewDelegate> @property (nonatomic, assign) BottomPanelView* bottomPanelView; @end 

ViewController.m

 #import "ViewController.h" @interface ViewController () @end @implementation ViewController @synthesize bottomPanelView; - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. bottomPanelView = [[BottomPanelView alloc] initWithFrame:CGRectMake(0, 480, 320, 125)]; [bottomPanelView setDelegate:self]; [self.view addSubview: bottomPanelView]; [bottomPanelView start]; } //delegate function - (void)bottomViewAnimationDone:(BottomPanelView *)_bottomPanelView { NSLog(@"It Works!"); [bottomPanelView removeFromSuperview]; //1) Does it clears memory? [bottomPanelView release]; //2) Strange is that if I have released it and set pointer to nil and use it below in touchesBegan it doesn't crashes. Why? // but if I release it and don't set to nil, it will crash. Why reading from nil is okay and gives back 0 (myValue was set to 15)? bottomPanelView = nil; } -(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { NSLog(@"Touched!"); NSLog(@"Pointer: %p", bottomPanelView); NSUInteger val = [bottomPanelView myValue]; NSLog(@"myValue: %d", val); } 

My questions are in the comments in the code above. Please tell me why reading from a nil pointer does not cause the application to crash?

0
source

All Articles