UISplitViewController Подробное представление не изменяет размеры при вращении - PullRequest
3 голосов
/ 12 марта 2012

Я надеюсь, что смогу правильно описать эту ситуацию.Это легко увидеть на экране, когда это происходит, но трудно объяснить словами, но я сделаю все возможное.

У меня есть UISplitViewController с фиксированным главным представлением (UITableView) и один из двух компонентов.просмотров, в зависимости от того, к какой ячейке прикоснулся мастер.Каждый из подробных представлений также является UITableView.Я использовал преобразование Тодда Бейтса из образца Apple MultipleDetailViews для использования раскадровок в качестве основы для моего кода ( Приключения в UISplitViewController ).

Я использую раскадровки, так что вот где объясняющая часть получаетсложно.Мастер и первый отображаемый детальный навигационный контроллер отображаются в раскадровке как Отношения с UISplitViewController.Второй подробный навигационный контроллер просто сидит на раскадровке без соединений.

Вот проблема.Деталь № 1 активна в ландшафтном режиме, а Деталь № 2 активируется нажатием на строку в мастере.IPad поворачивается в портретный режим, что приводит к корректному изменению размера детали 2 для портретного режима.Деталь № 1 устанавливается как активная, нажав строку в мастере.Деталь # 1 имеет тот же размер, какой был, когда она последний раз отображалась в ландшафтном режиме, она не заполняет экран так, как должна.

У меня вопрос, могу ли я сказать, что контроллер Detail не работает в данный момент?отображается для изменения размера при изменении ориентации?Или, может быть, лучше задать вопрос: как я могу изменить размер только что отображенного подробного представления, чтобы заполнить часть детализации UISplitView?

Надеюсь, я описал это достаточно подробно, чтобы кто-то помог.

Методы UISplitViewControllerDelegate реализованы в классе Manager, который должен перенаправлять эти вызовы в контроллеры представления Detail.Вот реализация этого метода:

#pragma mark - UISplitViewControllerDelegate

/* forward the message to the current detail view
 * all detail views must implement UISplitViewControllerDelegate
 */
-(void)splitViewController:(UISplitViewController *)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)pc
{
    self.masterBarButtonItem = barButtonItem;
    self.masterPopoverController = pc;

    barButtonItem.title = NSLocalizedString(@"Games", @"Games");

    [self.currentDetailController.navigationItem setLeftBarButtonItem:self.masterBarButtonItem animated:YES];
}

/* forward the message to the current detail view
 * all detail views must implement UISplitViewControllerDelegate
 */
-(void)splitViewController:(UISplitViewController *)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
    self.masterBarButtonItem = nil;
    self.masterPopoverController = nil;

    [self.currentDetailController.navigationItem setLeftBarButtonItem:nil animated:YES];
}

И я реализовал следующее в каждом из контроллеров детального представления:

#pragma mark - Split view

- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController
{
    barButtonItem.title = NSLocalizedString(@"Games", @"Games");
    [self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES];
    self.masterPopoverController = popoverController;
}

- (void)splitViewController:(UISplitViewController *)splitController willShowViewController:(UIViewController *)viewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
    // Called when the view is shown again in the split view, invalidating the button and popover controller.
    [self.navigationItem setLeftBarButtonItem:nil animated:YES];
    self.masterPopoverController = nil;
}

Проблема в том, что ни один из контроллеров детального представления не являетсяполучать эти сообщения.Я все равно не вижу, как они запускаются ...

Я не вижу, как пересылка didRotateFromInterfaceOrientation: приведет к тому, что контроллер Detail, который не отображается, не изменяет свой размер.Из документации Apple:

Когда ориентация устройства на базе iOS меняется, система отправляет уведомление UIDeviceOrientationDidChangeNotification, чтобы сообщить всем заинтересованным сторонам о том, что изменение произошло.По умолчанию среда UIKit перехватывает это уведомление и использует его для автоматического обновления ориентации интерфейса.Это означает, что, за небольшим исключением, вам вообще не нужно обрабатывать это уведомление.Вместо этого все, что вам нужно сделать, это реализовать соответствующие методы в ваших классах контроллера представления для реагирования на изменения ориентации.

Объект окна выполняет большую часть работы, связанной с изменением текущей ориентации.Однако он работает совместно с корневым контроллером представления, чтобы определить, должно ли вообще произойти изменение ориентации и, если да, то какие дополнительные методы следует вызвать, чтобы ответить на изменение.Если этот контроллер является контейнером, он может полагаться на ребенка, чтобы решить, должна ли ориентация происходить.

Когда происходит вращение, методы контроллера представления вызываются на различных этапах вращения, чтобы дать контроллеру представления возможность выполнять дополнительные задачи. Вы можете использовать эти методы, чтобы скрыть или отобразить представления, изменить положение или изменить размеры представлений, или уведомить другие части вашего приложения об изменении ориентации. Поскольку ваши пользовательские методы вызываются во время операции поворота, вам следует избегать выполнения там длительных операций. Вам также следует избегать замены всей иерархии представлений новым набором представлений. Существуют более эффективные способы предоставления уникальных видов для различных ориентаций, например, представление нового контроллера вида (как описано в разделе «Создание альтернативного интерфейса ландшафта»).

Ответы [ 2 ]

1 голос
/ 18 марта 2012

Я решил свою проблему.В коде, который заменяет подробные представления, я установил для вида, который должен отображаться, тот же размер, что и для только что отображенного представления.Мне еще предстоит пройти дополнительное тестирование, но это решение выглядит победителем.

1 голос
/ 13 марта 2012

Подобно методам splitViewController, вы должны перенаправить следующий вызов:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
    [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];

    // Forward to detail view controller here:

}

в контроллер подробного представления, который НЕ видим (т.е. НЕ self.currentDetailController, но другой).

...