2013-04-10 4 views
4

Я не могу понять, как сделать функцию, которая даст информацию родительскому объекту, что-то сделало, поэтому мне нужна ваша помощь. Пример того, что я хочу сделать:Как сделать функции обратного вызова iOS?

  1. ViewController класса Instantiate класс BottomView и добавляет его, как это подтаблица.
  2. Позвоните по номеру BottomView класс, чтобы начать что-то оживить.
  3. После окончания анимации я хочу дать знак, что анимация закончилась классом ViewController, чтобы он мог освободить/удалить экземпляр BottomView от себя.

Мне нужно что-то вроде обратного вызова. Не могли бы вы помочь?

+1

проверьте это http://stackoverflow.com/questions/1015608/how-to-perform-callbacks-in-objective-c – tkanzakic

+0

Просто разъясните понятия о делетете/делегировании (http://developer.apple. com/library/ios/# documentation/Общие/Концептуальные/CocoaEncyclopedia/DelegatesandDataSources/DelegatesandDataSources.html) –

+0

Как начать анимацию? –

ответ

6

1.Вы можете сделать это с помощью блоков!

Вы можете передать некоторый блок в BottomView.

2. Или вы можете сделать это с помощью целевого действия.

вы можете перейти на селектор BottomView @selector(myMethod:) как действие, и указатель на контроллер вида в качестве цели. И после окончания анимации используйте метод performeSelector:.

3. Или вы можете определить делегат @protocol и реализовать методы в вашем ViewController, и добавить делегат недвижимости в BottomView. @property (назначить) id делегата;

Если вы сделать некоторые анимации в вашем 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.м

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

и после анимации Complit вы должны вызвать [self notifyDelegateAboutAnimationDone];

вы должны установить вам ViewController класс для подтверждения протокола BottomViewDelegate

в MyViewController.h

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

и F.E. в viewDidLoad вы должны установить bottomView.delegate = self;

+0

Я думал об этом с вариантом 3., о котором вы упоминали. У меня есть проблема с пониманием без простого примера, как это работает. Как определить протокол и где он должен быть сделан? Мне нужен простой пример для моей проблемы, чтобы он хорошо понимал. Я не хочу идти на какой-то ярлык, но я действительно не нашел для меня хорошего учебника, поэтому мой вопрос здесь;) – PiotrCh

+0

см. Мое новое редактирование (дайте мне минуту) – BergP

+0

@CrazyBucket, вопрос: изм. – BergP

1

если вы специально хотите просто запустить функцию после анимации произошла вы могли уйти только с помощью этого:

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

Поскольку вы используете анимации, более конкретный способ справиться с этим заключается в использовании анимационных делегатов. Вы можете установить делегат вашей анимации в viewcontroller, чтобы после окончания анимации ниже метод будет вызываться в вашем диспетчере просмотра.

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

Чтобы сделать это, во 2-м шаге вы упомянули, вы должны пройти ViewController в качестве дополнительного параметра, так что в можно установить анимацию делегата.

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

Очень крутое решение Paul. Это очень помогло мне в критический момент. Спасибо!!! –

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-указателя не приводит к сбою приложения?

+0

попробуйте удалить представление, используя цикл for для ex: for (UIView * theView в [self.view subviews]) {[theView removeFromSuperview]}. Он удалит все подвью. – Jaiswal

Смежные вопросы