IsBeingDismissed не установлен в viewWillDisappear:

У меня есть код для очистки в моем viewWillDisappear:, который я хочу использовать только тогда, когда представление возвращается к родительскому контроллеру представления.

- (void)viewWillDisappear:(BOOL)animated
{
    if ([self isMovingFromParentViewController] || [self isBeingDismissed]) {
        NSLog(@"isMovingFromParentViewController or isBeingDismissed");
        // clean up
    }
    [super viewWillDisappear:animated];
}

Вид может быть представлен двумя способами: он может быть нажат навигационным контроллером или представлен как контроллер модального представления (от одного и того же навигационного контроллера). Если он подтолкнул, затем выскочил (нажав кнопку "Назад" ), мой код очистки запускается. Если он был представлен как модальный контроллер, а затем отклонен, код не запускается.

Я отклоняюсь так:

[rootViewController dismissModalViewControllerAnimated:YES];

Мой вопрос: почему нет isBeingDismissed, когда я отклоняю свой контроллер представления?

Ответ 1

Ваша проблема в том, как вы отклоняете свое модальное представление. Как определяется rootViewController?

Когда я вызываю [self dismissModalViewControllerAnimated:YES], тогда [self isBeingDismissed] имеет значение true.

Когда я вызываю [parentViewController dismissModalViewControllerAnimated:YES], тогда [self isBeingDismissed] оценивается как true, в котором parentViewController является UIViewController, который представил модальный вид (примечание: не UINavigationController).

Ответ 2

Если это первый контроллер представления в модульном навигационном контроллере, который отклоняется, вызов self.isBeingDimissed() from viewWillDisappear: возвращает false.

Однако, поскольку весь контроллер навигации отклоняется, фактически работает self.navigationController?.isBeingDismissed(), который возвращает true.

Ответ 3

Как отметил @Yuval Tal, этот флаг не работает, когда вы отклоняете контроллер, встроенный в контроллер навигации. Здесь расширение, которое я использую:

extension UIViewController 
{
    var isAboutToClose: Bool {
        return self.isBeingDismissed ||      
               self.isMovingFromParentViewController ||          
               self.navigationController?.isBeingDismissed ?? false
    }
}

Он может быть легко расширен, если вы найдете другой случай, когда стандартный .isBeingDismissed не будет работать. И если вы найдете, дайте мне знать в комментариях.

Ответ 4

        viewController.isBeingPresented == NO;
        [rootVC presentViewController:viewController animated:NO completion:^{
            viewController.isBeingPresented == NO;
            viewController.isBeingDismissed == NO;
            [viewController dismissViewControllerAnimated:NO completion:^{
                viewController.isBeingDismissed == NO;
            }];
            viewController.isBeingDismissed == NO;    // is not work
        }];
        viewController.isBeingPresented == YES;     // is work
        viewController.isBeingPresented == NO;
        [rootVC presentViewController:viewController animated:NO completion:^{
            viewController.isBeingPresented == NO;
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                viewController.isBeingDismissed == NO;
                [viewController dismissViewControllerAnimated:NO completion:^{
                    viewController.isBeingDismissed == NO;
                }];
                viewController.isBeingDismissed == YES;    // is work
            });
        }];
        viewController.isBeingPresented == YES;     // is work

Ответ 5

Если вы случайно попытались использовать isBeingDismissed на немодуально представленном контроллере представления, вы всегда можете проверить свойство topViewController вашего navigationController, например:

if navigationController?.topViewController != self {
    return
}