UISplitViewController Не удается изменить главный контроллер представления? - PullRequest
6 голосов
/ 04 мая 2010

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

Я использую следующее:

mySplitViewController.viewControllers = [NSArray arrayWithObjects: newMasterController, detailController, nil];

Это корректно меняет главный view-контроллер, как и следовало ожидать в ландшафтном режиме. Однако не , похоже, меняет контроллер вида, используемый для поповера в портретном режиме.

Я заметил, что элемент barbutton для показа этого главного контроллера вида просто вызывает showMasterInPopover: на контроллере splitview, и поэтому может ожидать, что он будет работать и в портретном режиме, но это не так.

На самом деле, я могу установить главный контроллер вида, см. новый viewController правильно в альбомном режиме, повернуть назад в портретное положение, и контроллер представления, используемый в поповере, равен все еще старый.

Это ошибка?

Ответы [ 2 ]

2 голосов
/ 23 декабря 2011

В случае, если кто-то ищет решение этой проблемы (или разговоров), у меня была похожая проблема, и я решил ее здесь: Изменение основного вида в режиме разделенного просмотра не обновляет поповер в портретной ориентации.

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

1 голос
/ 19 ноября 2010

ОБНОВЛЕНО: пожалуйста, прочтите окончательное обновление внизу! Оригинальный ответ + обновление ниже может быть бесполезным!

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

Проблема в том, что когда вы заменяете контроллер основного представления в режиме разделенного просмотра, код внутри UISplitViewController не обновляет свойство contentViewController его контроллера поповера. В результате контроллер поповера все еще имеет дескриптор контроллера устаревшего представления, что приводит к появлению старых пользовательских интерфейсов или даже к сбоям памяти в портретном режиме.

Вот наш обходной путь.

Я предполагаю, что у вас есть соответствующий класс UISplitViewControllerDelegate, который хранит popoverController как свойство класса (см. Стандартный пример кода для UISplitViewController).

В точке, в которой вы устанавливаете новый контроллер основного вида, вам также необходимо обновить contentViewController следующим образом:

mySplitViewController.viewControllers
    = [NSArray arrayWithObjects:newMasterController, detailController, nil];

// in the cases where the uisplitview has already shown a popovercontroller,
// we force the popovercontroller to update its content view controller. 
// This ensures any old content view in popover actually gets released by 
// the popovercontroller.
if (popoverController) {
    [popoverController setContentViewController:theMasterViewController 
                                animated:NO];       
}

Вы также должны установить contentViewController всплывающего окна, когда ваш UISplitViewControllerDelegate будет информирован о том, что контроллер поповера собирается представить контроллер представления:

- (void)splitViewController:(UISplitViewController*)svc 
        popoverController:(UIPopoverController*)pc 
        willPresentViewController:(UIViewController *)aViewController 
{
    // set the popoverController property - as per Apple's sample code
    self.popoverController = pc;

    // THE LINE BELOW IS THE NEW LINE!
    [popoverController setContentViewController:aViewController animated:NO];

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

UPDATE

Приведенная выше схема с настройкой просмотра контента, в конце концов, не работает. Например, если вы задали представление содержимого как контроллер uinavigation, позже вы получите корневое представление внутри контроллера nav вместо самого контроллера nav. Насколько я могу судить, UISplitViewController просто не обрабатывает изменение основного вида любым работоспособным способом.

Обходной путь, который у меня есть в настоящее время, состоит в том, чтобы установить UINavigationController в качестве основного представления и изменить корневой контроллер представления этого контроллера навигации. Так что я каким-то образом могу изменить главный вид «у задней двери».

ОБНОВЛЕНИЕ 2

Я сдаюсь. Подход в первом обновлении выше также несовершенен; У меня проблемы с вращением до сих пор. По сути, кажется, что если вы используете UISplitViewController, вам не следует пытаться менять контроллер основного представления (даже если вы переключаете главное представление, когда основное представление, например, как всплывающее окно, снова скрыто). Работа с содержимым UINavigationController в главном представлении (, в то время как в главном представлении отображается ) выглядит так, как будто все будет в порядке, но все, кроме этого, приводит к проблеме после проблемы.

Техническое примечание. Я полагаю, что проблемы связаны с очевидной слабостью в обработке пользовательского интерфейса Apple: а именно, код Apple будет вызывать выпуск на UIViews и контроллере, когда он будет скрыт или удален из представления, но будет позже, если будет показан содержащий контроллер представления снова отправьте отложенные сообщения, такие как viewDidDisappear, на освобожденные представления / контроллеры (которые на тот момент могли быть освобождены).

...