8

Скажем, у меня есть контроллер представления пользовательского контейнера (MainViewController), где я сделать что-то вроде этого:Контейнер View контроллеры - уведомлять родителей действий

- (void)viewDidLoad 
{ 
    [super viewDidLoad];   

    HomeViewController *homeVC = [[HomeViewController alloc] initWithNibName:@"HomeViewController" bundle:nil]; 
    [self addChildViewController:homeVC]; 
    [self.view addSubview:homeVC.view]; 

} 

HomeViewController будет иметь кнопку, например, «идти», что при нажатии необходимо перейти к следующему контроллеру. Поэтому мне нужно уведомить MainViewController этого действия. Каков наилучший способ сделать это?

Я использую пользовательский контейнер, потому что мне нужно выполнить пользовательские переходы между контроллерами представления. Когда нажата кнопка «go», некоторые из видов на HomeViewController будут анимироваться, пока вид из нового контроллера просмотра не станет на месте.

Очевидно, что я мог бы дать HomeViewController свойство типа MainViewController и сделать вызовы таким образом, но я надеюсь, что есть более чистый путь с API-интерфейсом контроллера контейнера.

ответ

15

Вы можете использовать делегат или блок;

Использование делегата

Создание протокола:

@protocol SomeProtocol <NSObject> 
- (void)someAction; 
@end 

Просто объявить делегат в HomeViewController.h так:

id<SomeProtocol> delegate; 

, а затем в viewDidLoad MainViewController Установим это так :

homeVC.delegate = self; 
//some where in MainViewController implement the protocol method 
-(void)someAction 
{ 
    //do something 
} 

затем при нажатии на кнопку в homeVC, просто звоните:

if ([self.delegate respondsToSelector:@selector(someAction)]) { 
    [self.delegate someAction]; 
} 

Использование блока:

В HomeViewController.h объявить свойство блока:

typedef void (^ActionBlock)(); 

@property (nonatomic, copy) ActionBlock block; 

затем в MainViewController ViewDidLoad:

homeVC.block = ^(){ 
    //do something 
}; 

затем при нажатии на кнопку в homeVC, просто звоните:

self.block(); 
+0

нормально, так что нет ничего, что я могу использовать из Содержания API UIViewController? – soleil

+0

Не совсем уверен, что это сообщение может помочь [проверить это] (http://stackoverflow.com/questions/8379759/how-does-view-controller-containment-work-in-ios-5) –

+1

Я бы добавил +1 это 3 раза, если бы я мог. Мало того, что он отвечал на один и тот же вопрос для меня, но он развил мое понимание блоков в десять раз :) – Pedro

10

Там другой способ тоже ... Каждый контроллер имеет вид parentViewController свойство так, используя которые вы можете сделать это ...

в MainViewController определяют способ действия, которое вы хотите выполнить ...

- (void)someMethod:(BOOL)someParam; 

Тогда в HomeViewController вы может сделать ...

MainViewController* parent = (MainViewController*)[self parentViewController]; 
[parent someMethod:paramValue]; 

HTH :)

+2

Хороший быстрый и грязный путь здесь. Используйте выбранный ответ, если у вас есть немного времени для создания протокола. Спасибо педро! –

3

Это очень общий шаблон.Родитель будет фактическим экземпляром, который будет обрабатывать действие, предоставив и default extension.

В Swift 3:

Родитель контроллер вида:

protocol SomeProtocol { 
    func foo() 
} 

extension ParentViewController: SomeProtocol { 
    func foo() { 
     // Parent handles it 
    } 
} 

ребенка контроллер вида:

@IBAction func tapGo(_ sender: Any) { 
    (parent as? SomeProtocol)?.foo() 
} 
+0

Спасибо большое, это было именно то, что я искал :) – mic

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