Kontrolery widoku kontenera-powiadom rodzica o akcji
Powiedzmy, że mam własny kontroler widoku kontenera (MainViewController), gdzie robię coś takiego:
- (void)viewDidLoad
{
[super viewDidLoad];
HomeViewController *homeVC = [[HomeViewController alloc] initWithNibName:@"HomeViewController" bundle:nil];
[self addChildViewController:homeVC];
[self.view addSubview:homeVC.view];
}
HomeViewController będzie miał przycisk, taki jak "go", który po naciśnięciu będzie musiał przejść do następnego kontrolera widoku. Muszę więc powiadomić Kontroler MainViewController o tej akcji. Jak najlepiej to zrobić?
Używam niestandardowego kontenera, ponieważ muszę wykonywać niestandardowe przejścia między kontrolerami widoku. Po naciśnięciu przycisku " go " niektóre z widoków na Kontroler HomeViewController będzie animował, podczas gdy widoki z nowego kontrolera będą animowane na swoim miejscu.
Oczywiście mógłbym dać HomeViewController właściwość typu MainViewController i wykonywać wywołania w ten sposób, ale mam nadzieję, że jest czystszy sposób z API container view controller.
3 answers
Możesz użyć delegata lub bloku;
Korzystanie z delegata
Utwórz protokół:
@protocol SomeProtocol <NSObject>
- (void)someAction;
@end
Wystarczy zadeklarować delegata w HomeViewController.H Jak to:
id<SomeProtocol> delegate;
A następnie w MainViewController ' s viewDidLoad ustaw to tak:
homeVC.delegate = self;
//some where in MainViewController implement the protocol method
-(void)someAction
{
//do something
}
Następnie po naciśnięciu przycisku w homeVC, po prostu zadzwoń:
if ([self.delegate respondsToSelector:@selector(someAction)]) {
[self.delegate someAction];
}
Użycie Bloku :
W HomeViewController.h deklaruje właściwość blokową:
typedef void (^ActionBlock)();
@property (nonatomic, copy) ActionBlock block;
Następnie w MainViewController ViewDidLoad:
homeVC.block = ^(){
//do something
};
Następnie po naciśnięciu przycisku w homeVC, po prostu zadzwoń:
self.block();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-09 15:23:40
Jest też inny sposób...
Każdy kontroler widoku posiada właściwość parentViewController
, dzięki czemu można to zrobić...
W MainViewController
zdefiniuj metodę dla akcji, którą chcesz wykonać...
- (void)someMethod:(BOOL)someParam;
Wtedy w HomeViewController
możesz to zrobić...
MainViewController* parent = (MainViewController*)[self parentViewController];
[parent someMethod:paramValue];
HTH:)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-24 16:43:05
To bardzo powszechny wzorzec. Rodzic będzie rzeczywistą instancją, która będzie obsługiwać akcję, podając protocol
i domyślne rozszerzenie .
W Swift 3:
Kontroler widoku nadrzędnego:
protocol SomeProtocol {
func foo()
}
extension ParentViewController: SomeProtocol {
func foo() {
// Parent handles it
}
}
Kontroler widoku potomnego:
@IBAction func tapGo(_ sender: Any) {
(parent as? SomeProtocol)?.foo()
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-16 08:24:11