如何制作iOS回调函数?

时间:2013-04-10 13:39:56

标签: ios objective-c callback

我无法弄清楚如何创建一个函数,它会向父对象提供已做某事的信息,所以我需要你的帮助。 示例我要做的:

  1. ViewController类实例化类BottomView并将其添加为子视图。
  2. BottomView类的实例上调用以启动动画。
  3. 动画结束后,我想给动画结束ViewController类的标志,它可以从自身发布/删除实例BottomView
  4. 我需要像回调一样的东西。 你能帮忙吗?

5 个答案:

答案 0 :(得分:12)

你可以做这样的事情

@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

你会使用

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];

答案 1 :(得分:6)

1.你可以用积木做到这一点!

您可以将一些块传递给BottomView。

<强> 2。或者你可以通过目标行动来做到这一点。

你可以传递给BottomView选择器@selector(myMethod:)作为动作, 和指向视图控制器的指针作为目标。动画结束后 使用performeSelector:方法。

第3。或者您可以在viewController中定义委托@protocol并实现方法, 并在BottomView中添加委托属性。 @property(assign)id delegate;

如果您在BottomView中制作了一些动画,则可以使用 UIView方法

animateWithDuration:delay:options:animations:completion:

使用块作为回调

[UIView animateWithDuration:1.0f animations:^{

    }];

<强>更新

在ButtomView.h中

@class BottomView;

@protocol BottomViewDelegate <NSObject>

- (void)bottomViewAnimationDone:(BottomView *) bottomView;

@end


@interface BottomView : UIView

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

.....
@end 

在ButtomView.m

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

在动画片编辑后你应该拨打[self notifyDelegateAboutAnimationDone];

您应该设置ViewController类以确认协议BottomViewDelegate

在MyViewController.h中

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

和f.e.在viewDidLoad中,您应该设置bottomView.delegate = self;

答案 2 :(得分:1)

如果您特意想在动画发生后立即运行一个函数,那么只需使用它就可以逃脱:

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

答案 3 :(得分:1)

由于您正在使用动画,因此处理它的更具体方法是使用动画委托。您可以将动画的委托设置为viewcontroller,以便在动画结束后,在viewcontroller中调用方法。

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

要在您提到的第二步中执行此操作,您应将viewcontroller作为额外参数传递,以便您可以设置动画委托。

答案 4 :(得分:0)

非常感谢你们所有人。我通过选择器和代表尝试了两种方法。 这很酷,我想,我理解这些机制。 我发现了一件奇怪的事情:

<强> 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);
}

我的问题在上面的代码中的评论中。 请特别告诉我为什么从nil指针读取不会使应用程序崩溃?