我有一个视图控制器,用于查询网络服务是否应显示插页式广告。如果是这样,则使用presentViewController实例化并呈现另一个视图控制器:animated:completion:。根据{{3}}和this answer,我假设viewDidAppear:在解除显示的视图控制器(它自己做)时不会被调用。从概念上讲,无论如何,呈现视图控制器的视图永远不会从视图层次结构中删除,因此永远不需要“重新出现”。我显然错了。那么发生了什么?为什么我所看到的与文档所说的不同?
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[[AdService sharedAdService] adForSlotName:@"Main Interstitial" completionBlock:^(Ad *adForSlotName) {
if(adForSlotName)
{
InterstitialAdViewController_iPhone *interstitialAdViewController = [[InterstitialAdViewController_iPhone alloc] init];
interstitialAdViewController.ad = adForSlotName;
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_async(mainQueue, ^{
[self presentViewController:interstitialAdViewController animated:YES completion:^{}];
});
[interstitialAdViewController release];
}
}];
}
- (void)viewWillDisappear:(BOOL)animated
{
[[AdService sharedAdService] clearAdForSlotName:@"Main Interstitial"];
[super viewWillDisappear:animated];
}
答案 0 :(得分:5)
您链接的答案是关于viewDidDisappear的行为,而不是viewDidAppear。您链接的文档中的注释表示,当呈现带有弹出框的子视图控制器时,将不会在呈现视图控制器上调用viewDidAppear。
在你的情况下,你正在呈现没有弹出窗口的子视图控制器,所以我阅读了doc的说明(在“证明规则”的方式的例外情况下)说当应该在孩子的时候在呈现视图控制器上调用viewDidAppear查看控制器在您的情况下被解雇。
我认为在呈现子视图控制器时,您应该看到在父视图控制器上调用viewDidDisappear。我在最小的测试应用程序中尝试了这一点,使用此代码呈现子视图控制器:
Parent *parent = [[Parent alloc] initWithNibName:nil bundle:nil];
[self.window setRootViewController:parent];
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
Child *child = [[Child alloc] initWithNibName:nil bundle:nil];
[parent presentViewController:child animated:YES completion:^{
NSLog(@"Child presented");
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[parent dismissViewControllerAnimated:YES completion:^{
NSLog(@"Child dismissed");
}];
});
}];
});
并且,将调用记录到Parent和Child类中的各种与外观相关的回调。这是我看到的序列:
使父视图控制器成为根视图控制器:
Parent viewWillAppear:
Parent viewDidAppear:
呈现子视图控制器:
Parent viewWillDisappear:
Child viewWillAppear:
Child viewDidAppear:
Parent viewDidDisappear:
Child presented
解雇子视图控制器:
Child viewWillDisappear:
Parent viewWillAppear:
Parent viewDidAppear:
Child viewDidDisappear:
Child dismissed
所以这对我来说似乎内部一致 - 当显示子视图控制器时,父级获取消失调用,当子视图控制器被解除时,父级调用。这仍然与viewWillAppear记录的行为一致,因为我没有使用popover呈现子视图控制器。
我担心我不知道为什么在你的子视图控制器出现时你没有得到viewWill / DidDisappear调用。
答案 1 :(得分:3)
我经历过同样的行为。在解除显示的视图控制器时调用viewDidAppear:
方法。但是,有一条出路。在控制器中创建一个布尔变量,将其设置为NO
中的viewDidLoad
并在viewDidAppear:
中进行检查。然后将其设置为YES
。像这样:
#import "MyViewController.h"
@implementation MyViewController {
BOOL alreadyShown;
}
- (void)viewDidLoad
{
[super viewDidLoad];
alreadyShown = NO;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (!alreadyShown) {
alreadyShown = YES;
//do your stuff
}
}
@end