Adaptive show detail segue преобразуется в модальный, а не нажимает на iPhone, когда главный контроллер просмотра является UITabBarController
В XCode 6, если вы создаете новый проект на основе шаблона приложения Master-Detail, вы получаете универсальную раскадровку, которая должна быть хорошей для всех устройств.
При выборе ячейки в главном представлении подробный вид обновляется через адаптивный "show detail" segue. На iPhone 4, 5, 6 или 6+ в портрете этот отступ примет форму толчка, как ожидалось. На iPad или iPhone 6+ в ландшафте это приведет к обновлению подробного представления, как ожидалось.
Теперь, если вы вставляете UITabBarController в качестве контроллера главного представления, который имеет вкладку к исходному контроллеру главного представления, адаптивный сегмент, который возникает при выборе ячейки в главном представлении, не ведет себя так, как ожидалось на iPhone. Вместо того, чтобы перейти к push-переходу, теперь вы получаете модальный переход. Как я могу это исправить? Кажется странным, что это не поддерживается по умолчанию.
Я нашел следующее сообщение полезным: iOS8 TabbarController внутри мастера UISplitviewController
Но при использовании предложенного метода я не получаю правильное поведение на iPhone 6 Plus, когда я поворачиваюсь к пейзажу после нажатия на портрет. Содержимое подробного представления появляется в главном представлении, что неудивительно, поскольку это то, что предлагает предлагаемое решение.
Спасибо!
Ответы
Ответ 1
Повторное просмотр видео с WWDC14 Я думаю, что нашел лучший ответ.
- Использовать пользовательский UISplitViewController (подкласс)
- Переопределить операцию showDetailViewController
- Используйте traitCollection для определения класса UISplitViewController
- Если горизонтальный класс является компактным, попросите диспетчер навигации вызвать showViewController
Вот код пользовательского UISplitViewController:
import UIKit
class CustomSplitViewController: UISplitViewController {
override func showDetailViewController(vc: UIViewController!, sender: AnyObject!) {
if (self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClass.Compact) {
if let tabBarController = self.viewControllers[0] as? UITabBarController {
if let navigationController = tabBarController.selectedViewController as? UINavigationController {
navigationController.showViewController(vc, sender: sender)
return
}
}
}
super.showDetailViewController(vc, sender: sender)
}
}
Не забудьте установить пользовательский класс в раскадровку.
Протестировано в симуляторе iPhone 6, iPhone 6+ и iPad Air и работает как ожидалось.
Ответ 2
К сожалению, выбранный ответ не сработал у меня. Однако в конечном итоге мне удалось решить проблему:
- Подкласс
UISplitViewController
и установите новый класс в Interface Builder.
-
Сопоставьте новый класс с UISplitViewControllerDelegate
:
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.delegate = self
}
-
Выполните следующие два метода:
func splitViewController(_ splitViewController: UISplitViewController,
collapseSecondary secondaryViewController:UIViewController,
onto primaryViewController:UIViewController) -> Bool {
return true
}
func splitViewController(_ splitViewController: UISplitViewController,
showDetail vc: UIViewController,
sender: Any?) -> Bool {
if splitViewController.isCollapsed {
guard let tabBarController = splitViewController.viewControllers.first as? UITabBarController else { return false }
guard let selectedNavigationViewController = tabBarController.selectedViewController as? UINavigationController else { return false }
// Push view controller
var detailViewController = vc
if let navController = vc as? UINavigationController, let topViewController = navController.topViewController {
detailViewController = topViewController
}
selectedNavigationViewController.pushViewController(detailViewController, animated: true)
return true
}
return false
}
Ответ 3
Когда docs находится в свернутом состоянии, он обрабатывает showDetail, вызывая show на главном контроллере представления, который в вашем случае является контроллером вкладок. Подкласс вашего контроллера вкладок, переопределить show и call show на дочернем контроллере навигации.