2

インタースティシャル広告を表示するかどうかを Web サービスに照会するビュー コントローラーがあります。その場合、別のビュー コントローラーがインスタンス化され、presentViewController:animated:completion: を使用して提示されます。この回答docsによると、表示されたView Controllerを閉じるときに 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];
}
4

2 に答える 2

5

あなたがリンクした答えは、viewDidAppearではなく、viewDidDisappearの動作に関するものです。リンクしたドキュメントのメモには、ポップオーバーで表示された子ビュー コントローラーが閉じられたときに、表示中のビュー コントローラーで viewDidAppear が呼び出されないことが示されています。

あなたの場合、ポップオーバーなしで子View Controllerを提示しているので、子View Controllerがあなたの場合は却下されました。

子View Controllerが表示されているときに、親View Controllerで呼び出された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");
            }];
        });
    }];
});

そして、親クラスと子クラスの両方で、さまざまな外観関連のコールバックへの呼び出しをログに記録します。これは私が見るシーケンスです:

親View ControllerをルートView Controllerにする:

Parent viewWillAppear:
Parent viewDidAppear:

子ビュー コントローラーの表示:

Parent viewWillDisappear:
Child viewWillAppear:
Child viewDidAppear:
Parent viewDidDisappear:
Child presented

子ビュー コントローラーを閉じる:

Child viewWillDisappear:
Parent viewWillAppear:
Parent viewDidAppear:
Child viewDidDisappear:
Child dismissed

したがって、これは私には内部的に一貫しているようです---子View Controllerが表示されると親は消失呼び出しを取得し、子View Controllerが閉じられると外観呼び出しを取得します。これは、子ビュー コントローラーにポップオーバーを表示していないため、viewWillAppear の文書化された動作と一貫性があります。

子ビュー コントローラーが表示されているときに、viewWill/DidDisappear 呼び出しを受け取らない理由がわかりません。

于 2013-05-26T18:39:42.640 に答える
3

私は同じ行動を経験しました。このviewDidAppear:メソッドは、表示されたビュー コントローラーを閉じるときに呼び出されます。ただし、方法があります。コントローラー内にブール変数を作成し、 in に設定してNOinviewDidLoadにチェックし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
于 2013-05-26T18:42:08.560 に答える