О, чувак, это вызывало у меня головную боль в течение нескольких дней, и я не мог понять, как это сделать. Хуже всего было то, что создание нового проекта Xcode iOS с шаблоном master-detail работало просто отлично. К счастью, в конце концов, этот маленький факт помог мне найти решение.
Я нашел несколько сообщений, которые предполагают, что решение заключается в реализации нового primaryViewControllerForCollapsingSplitViewController:
метода UISplitViewControllerDelegate
. Я пытался это безрезультатно. То, что Apple делает в шаблоне master-detail, который, кажется, работает, реализует новый (глубоко вздохнув, чтобы сказать все это) splitViewController:collapseSecondaryViewController:ontoPrimaryViewController:
метод делегата (снова включен UISplitViewControllerDelegate
). Согласно документам , этот метод:
Просит делегата настроить основной контроллер вида и включить дополнительный контроллер вида в свернутый интерфейс.
Обязательно ознакомьтесь с дискуссионной частью этого метода для более подробной информации.
Apple это обрабатывает так:
- (BOOL)splitViewController:(UISplitViewController *)splitViewController
collapseSecondaryViewController:(UIViewController *)secondaryViewController
ontoPrimaryViewController:(UIViewController *)primaryViewController {
if ([secondaryViewController isKindOfClass:[UINavigationController class]]
&& [[(UINavigationController *)secondaryViewController topViewController] isKindOfClass:[DetailViewController class]]
&& ([(DetailViewController *)[(UINavigationController *)secondaryViewController topViewController] detailItem] == nil)) {
// Return YES to indicate that we have handled the collapse by doing nothing; the secondary controller will be discarded.
return YES;
} else {
return NO;
}
}
Эта реализация в основном делает следующее:
- Если
secondaryViewController
это то, что мы ожидаем (а UINavigationController
), и оно показывает то, что мы ожидаем (а DetailViewController
- ваш контроллер представления), но не имеет модели ( detailItem
), тогда " Return YES to indicate that we have handled the collapse by doing nothing; the secondary controller will be discarded.
"
- В противном случае вернитесь «
NO
чтобы позволить контроллеру разделенного вида попробовать и включить содержимое контроллера вторичного представления в свернутый интерфейс»
Результаты для iPhone в портретной ориентации следующие (начиная с портрета или с поворота на портрет - или, точнее, класса компактных размеров):
- Если ваш взгляд верен
- и есть модель, показать детальный вид контроллера
- но не имеет модели, покажите главный контроллер вида
- Если ваше мнение не верно
- показать главный контроллер вида
Ясно, как грязь.
UISplitViewController
и всегда возвращаюсьYES
из этого метода, затем просто меняю класс разделения представления в раскадровке, так как я всегда хочу показать мастер на iPhone в портретной ориентации. :)UISplitViewController
но обнаружил, что это не работает:splitViewController:collapseSecondaryViewController:ontoPrimaryViewController:
никогда не звонили Вместо этого я скопировал шаблон Apple и поместил его в AppDelagate. Это потребовало внесения некоторых изменений в создание UISplitViewController,application didFinishLaunchingWithOptions:
в котором я также скопировал шаблон Apple.splitViewController:collapseSecondaryViewController:ontoPrimaryViewController:
так и не получил. Похоже, что делегат корректно устанавливаетapplicationDidFinishLaunchingWithOptions:
метод делегата моего приложения . Кто-нибудь еще видел эту проблему и НЕ работал это решение?Вот принятый ответ в Swift. Просто создайте этот подкласс и назначьте его вашему splitViewController в вашей раскадровке.
источник
func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool {
Swift версия Mark S 'правильный ответ
В соответствии с шаблоном Apple Master-Detail.
осветление
(То, что сказал Марк С., немного сбивало с толку)
Этот метод делегата вызывается
splitViewController: collapseSecondaryViewController: ontoPrimaryViewController:
, потому что это то, что он делает. При переходе к более компактному размеру ширины (например, при повороте телефона из альбомного в портретный режим) необходимо разделить контроллер разделенного вида только на один из них.Эта функция возвращает логическое значение, чтобы решить, следует ли свернуть деталь и показать мастер или нет.
Таким образом, в нашем случае мы решили, основываясь на том, была ли выбрана деталь или нет. Как мы узнаем, выбрана ли наша деталь? Если мы следуем шаблону Apple Master-Detail, контроллер подробного представления должен иметь необязательную переменную, содержащую подробную информацию, поэтому, если она равна nil (.None), ничего еще не выбрано, и мы должны показать Master, чтобы пользователь мог что-то выбрать.
Вот и все.
источник
Apple's Master-Detail template
, он не предназначен, чтобы быть большим или кратким, просто фактическим. :)Из документации , вы должны использовать делегат рассказать
UISplitViewController
не включить подробный вид в «разрушились интерфейс» (то есть «режим портрета» в вашем случае). В Swift 4 метод делегата для реализации был переименован:источник
.m:
источник
Мое приложение было написано на Swift 2.x и могло хорошо работать. После преобразования его в Swift 3.0 (с использованием конвертера XCode) он начинает показывать сначала детали, а не мастер в портретном режиме. Проблема в том, что имя функции splitViewController не изменено, чтобы соответствовать новой функции UISplitViewControllerDelegate.
После изменения имени этой функции вручную мое приложение теперь может работать правильно:
источник
self.delegate = self
наviewDidLoad
метод.Если у вас нет значений по умолчанию для отображения в подробном представлении контроллера, вы можете просто удалить переход по умолчанию между SplitViewController и вашим подробным UIViewController в раскадровке. Это сделает его всегда первым в Master View Controller.
Побочным эффектом этого является то, что вместо просмотра двух представлений в альбомной ориентации вы увидите одно представление в полном размере в SplitViewController до тех пор, пока не будет запущена функция Show Detail Segue в главном контроллере представления.
источник
Для всех людей, которые не смогли найти раздел пятницы cs193p:
В Swift 3.1.1 создание подкласса UISplitViewController и реализация одного из его методов делегатов работали для меня как обаяние:
Моя раскадровка
источник
public func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool
На мой взгляд, вы должны решить эту проблему более общим. Вы можете создать подкласс UISplitViewController и реализовать протокол во встроенных контроллерах представления.
Пример реализации в UITableViewController:
Надеюсь, поможет. Таким образом, вы можете повторно использовать этот класс и просто нужно реализовать протокол.
источник
Просто удалите DetailViewController из контроллеров SplitView, когда вам нужно запустить его с Master.
источник
Это сработало для меня на iOS-11 и Swift 4:
источник
Функция переименована в новых версиях Swift, поэтому этот код работает на Swift 4:
источник
Xamarin / C # Решение
источник
Просто установите
preferredDisplayMode
свойствоUISplitViewController
в.allVisible
источник