4

我不知道如何制作一个函数,它会向父对象提供信息,它已经做了一些事情,所以我需要你的帮助。例如我想做的:

  1. ViewController类实例化类BottomView并将其添加为子视图。
  2. 调用BottomView类的实例来启动动画。
  3. 动画结束后,我想给ViewController类一个动画已经结束的标志,它可以BottomView从自身释放/删除一个实例。

我需要类似回调的东西。你能帮忙吗?

4

5 回答 5

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];
于 2013-04-10T14:00:39.437 回答
6

1.你可以用积木来做!

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

2. 或者你可以用 target-action 来做。

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

3. 或者你可以在你的viewController中定义代理@protocol并实现方法, 并在BottomView中添加代理属性。@property (assign) id 委托人;

如果你在底部视图中制作一些动画,你可以使用 UIView方法

animateWithDuration:delay:options:animations:completion:

使用块作为回调

[UIView animateWithDuration:1.0f animations:^{

    }];

更新:

在按钮视图.h

@class BottomView;

@protocol BottomViewDelegate <NSObject>

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

@end


@interface BottomView : UIView

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

.....
@end 

在按钮视图.m

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

在动画complit之后你应该调用[self notifyDelegateAboutAnimationDone];

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

在 MyViewController.h

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

和 feviewDidLoad你应该设置bottomView.delegate = self;

于 2013-04-10T13:48:15.910 回答
1

如果你特别想在动画发生后运行一个函数,你可以使用这个:

[UIView animateWithDuration:0.5 animations:^{
    //do animations
} completion:^(BOOL finished){
    //do something once completed
}];
于 2013-04-10T13:45:36.580 回答
1

由于您正在使用动画,因此更具体的处理方法是使用动画代理。您可以将动画的委托设置为视图控制器,以便在动画结束后在您的视图控制器中调用下面的方法。

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

要在您提到的第二步中做到这一点,您应该将 viewcontroller 作为额外参数传递,以便您可以在其中设置动画委托。

于 2013-04-10T13:47:06.937 回答
0

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

视图控制器.h

#import <UIKit/UIKit.h>
#import "BottomPanelView.h"

@interface ViewController : UIViewController <BottomPanelViewDelegate>

@property (nonatomic, assign) BottomPanelView* bottomPanelView;

@end

视图控制器.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 指针读取不会使应用程序崩溃?

于 2013-04-10T20:51:18.807 回答