ios 如何制作iOS回调函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15927498/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to make iOS callback functions?
提问by piotr_ch
I can't figure out how to make a function, that will give information to the parent object, that has done something, so I need your help. Example what I want to make:
我不知道如何创建一个函数,它会向父对象提供信息,它做了一些事情,所以我需要你的帮助。例如我想做什么:
ViewController
class instantiate classBottomView
and adds it as it's subview.- Make a call on instance of
BottomView
class to start animate something. - After the animation ends, I want to give a sign that the animation has ended to the
ViewController
class, that it could release/remove an instanceBottomView
from itself.
ViewController
class 实例化类BottomView
并将其添加为子视图。- 调用
BottomView
类的实例来开始动画。 - 动画结束后,我想向
ViewController
类表明动画已经结束,它可以BottomView
从自身释放/删除一个实例。
I need something like a callback. Could you help please?
我需要类似回调的东西。你能帮忙吗?
回答by Paul.s
You could 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 you would use like
你会使用哪个
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];
回答by BergP
1.You can do it with blocks!
1.你可以用积木来做!
You can pass some block to BottomView.
您可以将一些块传递给BottomView。
2. Or you can do it with target-action.
2. 或者你可以用 target-action 来做。
you can pass to BottomView selector @selector(myMethod:)
as action,
and pointer to the view controller as target. And after animation ends
use performeSelector:
method.
您可以将底部视图选择器@selector(myMethod:)
作为动作传递给底部视图选择器,并将指向视图控制器的指针作为目标传递。并在动画结束后使用performeSelector:
方法。
3. Or you can define delegate @protocol and implement methods in your viewController,and add delegate property in BottomView. @property (assign) id delegate;
3. 或者你可以在你的viewController中定义delegate@protocol并实现方法,并在BottomView中添加delegate属性。@property (assign) id 委托;
If you make some animations in your BottomView, you can useUIViewmethod
如果你在你的BottomView中制作了一些动画,你可以使用UIView方法
animateWithDuration:delay:options:animations:completion:
that uses blocks as callbacks
使用块作为回调
[UIView animateWithDuration:1.0f animations:^{
}];
update:
更新:
in ButtomView.h
在 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
在 ButtomView.m 中
- (void)notifyDelegateAboutAnimationDone {
if ([self.delegate respondsToSelector:@selector(bottomViewAnimationDone:)]) {
[self.delegate bottomViewAnimationDone:self];
}
}
and after animation complit you should call [self notifyDelegateAboutAnimationDone];
在动画完成后你应该打电话 [self notifyDelegateAboutAnimationDone];
you should set you ViewController class to confirm to protocol BottomViewDelegate
你应该设置你的 ViewController 类来确认协议 BottomViewDelegate
in MyViewController.h
在 MyViewController.h
@interface MyViewController : UIViewController <BottomViewDelegate>
...
@end
and f.e. in viewDidLoad
you should set bottomView.delegate = self;
和 feviewDidLoad
你应该设置bottomView.delegate = self;
回答by Fonix
if you specifically want to just run a function after an animation has occurred you could get away with just using this:
如果你特别想在动画发生后运行一个函数,你可以只使用这个:
[UIView animateWithDuration:0.5 animations:^{
//do animations
} completion:^(BOOL finished){
//do something once completed
}];
回答by guenis
Since you are using animations, 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 ends below method will be called in your viewcontroller.
由于您使用的是动画,因此更具体的处理方式是使用动画委托。您可以将动画的委托设置为视图控制器,以便在动画结束后在您的视图控制器中调用下面的方法。
-(void) animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
To do that in the 2nd step you mentioned you should pass viewcontroller as an extra parameter so there in you can set the animation delegate.
要在您提到的第二步中执行此操作,您应该将 viewcontroller 作为额外参数传递,以便您可以在其中设置动画委托。
回答by piotr_ch
Many thanks for all of you. I have tried two ways, by selector and by a delegate. It's cool and I suppose, that I understand those mechanisms. I have found one odd thing:
非常感谢你们所有人。我尝试了两种方法,通过选择器和通过委托。这很酷,我想,我了解这些机制。我发现了一件奇怪的事情:
ViewController.h
视图控制器.h
#import <UIKit/UIKit.h>
#import "BottomPanelView.h"
@interface ViewController : UIViewController <BottomPanelViewDelegate>
@property (nonatomic, assign) BottomPanelView* bottomPanelView;
@end
ViewController.m
视图控制器.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 comments in code above. Please, tell me especially why reading from nil pointer doesn't crashes the application?
我的问题在上面代码的注释中。请特别告诉我为什么从 nil 指针读取不会使应用程序崩溃?