Подтвердить что ты не робот

Как я могу обнаружить увольнение контроллера модального представления в контроллере родительского представления?

Возможный дубликат:
Функция вызова в базовом ViewController, когда диспетчер Modal View отклонен

Я пробовал почти все. Вот что я пробовал:

-(void)viewWillAppear:(BOOL)animated
{

NSLog(@"Test");

}

-(void)viewDidAppear:(BOOL)animated
{

NSLog(@"Test");

}

-(void)viewDidLoad
{

NSLog(@"Test");

}

Почему никто из них не работает в моем родительском контроллере просмотра, когда диспетчер модального просмотра отклонен? Как я могу заставить это работать?

4b9b3361

Ответ 1

Этот ответ был переписан/расширен, чтобы объяснить 3 наиболее важных подхода (@galambalazs)

1. Блоки

Самый простой способ - использовать обратный вызов block. Это хорошо, если у вас есть только один слушатель (родительский контроллер представления), заинтересованный в увольнении. Вы даже можете передать некоторые данные с событием.

В MainViewController.m

SecondViewController* svc = [[SecondViewController alloc] init];
svc.didDismiss = ^(NSString *data) {
    // this method gets called in MainVC when your SecondVC is dismissed
    NSLog(@"Dismissed SecondViewController");
};
[self presentViewController:svc animated:YES completion:nil];

В SecondViewController.h

@interface MainViewController : UIViewController
    @property (nonatomic, copy) void (^didDismiss)(NSString *data);
    // ... other properties
@end

В SecondViewController.m

- (IBAction)close:(id)sender 
{
    [self dismissViewControllerAnimated:YES completion:nil];

    if (self.didDismiss) 
        self.didDismiss(@"some extra data");
}

2. Делегация

Delegation является рекомендуемым шаблоном Apple:

Отклонение контроллера представления данных

Если представленный контроллер представления должен вернуть данные в контроллер представления представления, используйте delegation шаблон дизайна, чтобы облегчить передачу. Делегирование упрощает повторное использование контроллеров представлений в разных частях приложения. При делегировании представленный контроллер представления хранит ссылку на объект-делегат, который реализует методы из формального protocol. По мере того, как он собирает результаты, представленный диспетчер представлений вызывает эти методы для своего делегата. В типичной реализации контроллер представления представления делает себя делегатом своего представленного контроллера представления.

MainViewController

В MainViewController.h

@interface MainViewController : UIViewController <SecondViewControllerDelegate>
    - (void)didDismissViewController:(UIViewController*)vc;
    // ... properties
@end

Где-то в MainViewController.m(представлен)

SecondViewController* svc = [[SecondViewController alloc] init];
svc.delegate = self;
[self presentViewController:svc animated:YES completion:nil];

Где-то еще в MainViewController.m(рассказывается об увольнении)

- (void)didDismissViewController:(UIViewController*)vc
{
    // this method gets called in MainVC when your SecondVC is dismissed
    NSLog(@"Dismissed SecondViewController");
}

SecondViewController

В SecondViewController.h

@protocol SecondViewControllerDelegate <NSObject>
- (void)didDismissViewController:(UIViewController*)vc;
@end

@interface SecondViewController : UIViewController
@property (nonatomic, weak) id<SecondViewControllerDelegate> delegate;
// ... other properties
@end

Где-то в SecondViewController.m

[self.delegate myActionFromViewController:self];
[self dismissViewControllerAnimated:YES completion:nil];

(примечание: протокол с методом didDismissViewController: метод может быть повторно использован во всем приложении)


3. Уведомления

Другое решение отправляет NSNotification. Это также действительный подход, это может быть проще, чем делегирование, если вы хотите только уведомить об увольнении, не передавая много данных. Но основной случай использования - это когда вы хотите несколько прослушивателей для события увольнения (кроме только родительского контроллера представления).

Но убедитесь, что всегда удаляйте себя из NSNotificationCentre после завершения! В противном случае вы рискуете столкнуться, вызвав уведомления, даже после того, как вы освободитесь. [примечание редактора]

В MainViewController.m

- (IBAction)showSecondViewController:(id)sender 
{
    SecondViewController *secondVC = [[SecondViewController alloc] init];
    [self presentViewController:secondVC animated:YES completion:nil];

    // Set self to listen for the message "SecondViewControllerDismissed"
    // and run a method when this message is detected
    [[NSNotificationCenter defaultCenter] 
     addObserver:self
     selector:@selector(didDismissSecondViewController)
     name:@"SecondViewControllerDismissed"
     object:nil];
}

- (void)dealloc
{
    // simply unsubscribe from *all* notifications upon being deallocated
    [[NSNotificationCenter defaultCenter] removeObserver:self];
} 

- (void)didDismissSecondViewController 
{
    // this method gets called in MainVC when your SecondVC is dismissed
    NSLog(@"Dismissed SecondViewController");
}

В SecondViewController.m

- (IBAction)close:(id)sender 
{
    [self dismissViewControllerAnimated:YES completion:nil];

    // This sends a message through the NSNotificationCenter 
    // to any listeners for "SecondViewControllerDismissed"
    [[NSNotificationCenter defaultCenter] 
     postNotificationName:@"SecondViewControllerDismissed" 
     object:nil userInfo:nil];
}

Надеюсь, это поможет!

Ответ 2

Модальное представление должно указывать родителям, чтобы его отклонить, тогда родитель узнает, потому что он несет ответственность за отклонение.

Пример этого можно увидеть, если вы создаете новый проект и выбираете шаблон Utility Application.