2

У меня есть контроллер вида, который запрашивает веб-службу относительно того, должно ли отображаться объявление внутристраничного объявления. Если это так, создается другой экземпляр контроллера представления и представлен с помощью currentViewController: анимированный: завершение :. Согласно this answer и docs, я бы предположил, что viewDidAppear: не будет вызываться при отклонении представленного контроллера представления (который он сам делает). Понятно, что во всяком случае представление представления контроллера представления никогда не удаляется из иерархии представлений и поэтому никогда не нужно «снова появляться». Я, очевидно, ошибаюсь. Так, что происходит? Почему то, что я вижу, отличается от того, что говорят документы?viewDidAppear: вызывается при использовании presentViewController: анимированный: завершение:

- (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

С какого вида получает видDidAppear в какой точке? Мне кажется непонятным в вашем вопросе. Я бы предположил, что viewDidAppear вызывается всякий раз, когда появляется представление. Появлением может быть что-то, что случается после представления представления, но также будет происходить по основному виду после того, как вид, ранее покрывающий его, будет удален (отклонен). – Till

+0

Извинения, viewDidAppear: на контроллере представления представления вызывается всякий раз, когда представленный диспетчер представлений отклоняется. – rob5408

+0

, что соответствовало бы моим ожиданиям, составленным во второй части моего первого комментария, и точно так, как должно быть. – Till

ответ

5

Ответ, на который вы ссылаетесь, касается поведения viewDidDisappear, а не viewDidAppear. В примечании в связанной документации говорится, что viewDidAppear не будет вызываться на контроллере представления представления, когда дочерний контроллер просмотра , представленный с popover, уволен.

В вашем случае вы представляете контроллер детского вида без popover, поэтому я читаю примечание документа (в способе «исключение, которое доказывает правило»), говоря, что 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 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, когда отображается ваш контроллер представления вашего ребенка.

+0

По правде говоря, моя проблема началась с viewWillDisappear: вызывается при представлении контроллера представления, но, возможно, это было скорее симптомом чего-то еще происходящего. Поэтому я сформулировал этот вопрос с точки зрения моего взглядаWillAppear. Возможно, я должен переписать весь вопрос. Благодарю. – rob5408

+0

Привет, Аарон, еще один комментарий. Мне кажется странным, что если ожидаемое поведение заключается в том, чтобы не вызывать viewDidDisappear при представлении контроллера вида, тогда исходный контроллер представления также НЕ должен вызывать viewWillAppear после отклонения представленного контроллера представления. Вы согласны? – rob5408

+0

Я согласен, что это кажется странным, и на самом деле, когда я экспериментировал с этим, я получил вызовы viewDidDisappear для представления контроллера детского представления (см. Мое редактирование). –

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 
+0

Спасибо Адаму, я собираюсь использовать этот подход, чтобы получить то, что я ищу. – rob5408

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