3

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

У меня есть UISplitViewController с фиксированным основным видом (UITableView) и одним из двух подробных представлений, в зависимости от того, какая ячейка затронута в Мастере. Каждый из представлений Detail также является UITableView. Я использовал преобразование Todd Bates из примера MultipleDetailViews от Apple с использованием раскадровки в качестве основы для моего кода (Adventures in UISplitViewController).

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

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

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

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

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

#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: приведет к тому, что контроллер детали не отобразится при изменении размера. Из документации Apple:

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

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

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

ответ

1

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

1

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

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

    // Forward to detail view controller here: 

} 

к контроллеру зрения детализации, которая не видна (т.е. НЕ self.currentDetailController, но другой).

+0

Я проголосовал за вас за ответ. Я постараюсь, чтобы это работало, и если это сработает, я буду отмечать это как ответ. Благодаря! – Moebius

+0

Спасибо! Если у вас возникнут проблемы, отправьте код, который у вас есть, и я буду рад помочь. – lnafziger

+0

Я понял, когда посмотрел на код только сейчас, когда я должен был реализовать UISplitViewControllerDelegate в каждом из контроллеров Detail view. Я пошел дальше и сделал это, но методы протокола в представлениях Detail не вызываются. Я не могу опубликовать весь код, но есть класс Detail Manager, который также реализует методы делегата. Я отправлю это в исходное сообщение. – Moebius