UISplitViewController willHideViewController / willShowViewController не вызывается после принудительного скрытия подробного вида - PullRequest
2 голосов
/ 23 февраля 2012

У меня есть приложение для iPad, которое использует UISplitViewController в качестве корневого контроллера, я настроил делегата и использую UINavigationController для DetailView, и, похоже, он работает нормально.

Я хочу, чтобы MasterViewContoller всегда был скрыт (при всех поворотах), когда в разделе DetailView отображается конкретный контроллер вида.Я могу сделать это с помощью метода shouldHideViewController в делегате UISplitViewController.

Однако, если я это сделаю, то при изменении ViewController в секции DetailView на другой отображается MasterView, но в делегате не вызывается ни willHideViewController / willShowViewController.

Если я поверну устройство и поверну назад, они будут вызваны, и он будет работать, как и ожидалось, но они не будут вызваны, пока устройство не будет повернуто и повернуто обратно в исходную ориентацию.

Этоприводит к тому, что поповерная кнопка не отображается при первом повороте после отображения MasterView.

- (void)splitViewController:(UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItem forPopoverController:(UIPopoverController*)pc {

// Keep references to the popover controller and the popover button, and tell the detail view controller to show the button.
barButtonItem.title = @"Survey Sections";
self.popoverController = pc;
self.rootPopoverButtonItem = barButtonItem;

UIViewController <SubstitutableDetailViewController> *detailViewController = [self.splitViewController.viewControllers objectAtIndex:1];

if ([detailViewController isKindOfClass:[UINavigationController class]]) {
    UINavigationController *detailNavController = (UINavigationController *)detailViewController;
    [[detailNavController.viewControllers objectAtIndex:0] showRootPopoverButtonItem:rootPopoverButtonItem];
}

}

- (void)splitViewController:(UISplitViewController*)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem {

// Nil out references to the popover controller and the popover button, and tell the detail view controller to hide the button.
UIViewController <SubstitutableDetailViewController> *detailViewController = [self.splitViewController.viewControllers objectAtIndex:1];

if ([detailViewController isKindOfClass:[UINavigationController class]]) {
    UINavigationController *detailNavController = (UINavigationController *)detailViewController;
    [[detailNavController.viewControllers objectAtIndex:0] invalidateRootPopoverButtonItem:rootPopoverButtonItem];
}

self.popoverController = nil;
self.rootPopoverButtonItem = nil;

}

- (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation {

UIViewController *detailViewController = [svc.viewControllers objectAtIndex:1];

if ([detailViewController isMemberOfClass:[MySurveysViewController class]]) {
    return YES;
}else {

    if (UIInterfaceOrientationIsLandscape(orientation)) {
        return NO;
    }else {
        return YES;
    }

}

}

1 Ответ

1 голос
/ 17 октября 2012

У меня была очень похожая проблема, я использовал пример кода Apple с делегатом SubstitutableDetailViewController в сочетании с ротацией.

Я сохранил BOOL, когда ориентация была альбомной, обновив его на willRotateToInterfaceOrientation с помощью этого кода:

isLandscape = UIInterfaceOrientationIsLandscape(self.interfaceOrientation);

Вкл viewWillAppear Я проверил, является ли текущая ориентация альбомной, и если она не соответствует сохраненному значению, вызвал этот метод:

-(void)adjustLayoutForOrientation{
    if (isLandscape) {
        [self invalidateRootPopoverButtonItem:  self.navigationController.navigationItem.leftBarButtonItem];
}else{
        LeftViewController *lvc = (LeftViewController *)[self.splitViewController delegate];
        [self showRootPopoverButtonItem:  lvc.rootPopoverButtonItem ];
    }
}

Очевидно, что я использую код делегирования, предоставленный Apple, но для полноты эти методыони могут быть легко реализованы:

#pragma mark -
#pragma mark Managing the popover

- (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem {
    // Add the popover button to the left navigation item.
    [self.navigationController.navigationBar.topItem setLeftBarButtonItem:barButtonItem animated:NO];
}


- (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem {
    // Remove the popover button.
    [self.navigationController.navigationBar.topItem setLeftBarButtonItem:nil animated:NO];
}

Главный контроллер вида (левая сторона) поддерживает ссылку на rootPopoverButtonItem, что делает эту работу.

EDIT : обратите внимание, что я также вызываю свой метод adjustLayoutForOrientation для viewDidLoad и willRotateToInterfaceOrientation ... Лучшим способом может быть регистрация в Центре уведомлений, но я не был уверен, получат ли контроллеры фонового / невидимого представленияэти уведомления ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...