Адаптивный UIPresentationController на основе размера представления
Я перехожу к презентациям на основе UIPresentationController
для своих контроллеров представлений, но столкнулся с некоторой путаницей с API.
У меня есть специальная презентация контроллера стиля в стиле боковой панели (похожая на демонстрационный код LookInside
WWDC 2014).
Этот кластер классов (UIPresentationController
, UIViewControllerTransitioningDelegate
и UIViewControllerAnimatedTransitioning
) представляет собой контроллер вида как боковую панель от края экрана на представлениях класса обычного размера и представляет тот же контроллер вида, что и полный экран на компактном размер класса.
Тестирование этого на цели Resizable iPad показывает правильное поведение: я устанавливаю класс горизонтального размера в "Compact", а мой контроллер просмотра переключается с боковой панели на полный экран.
Однако я хочу больше детализации. Я хотел бы использовать презентацию диспетчера представлений в стиле боковой панели на iPhone 6 и 6+, когда устройство находится в альбомной ориентации, и использовать полноэкранную презентацию стиля для всех iPhone в портретной ориентации.
Итак, в моем методе
- (void) viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
Я реализовал некоторую логику, чтобы определить, будет ли боковая панель занимать слишком много экрана, допустим, я использую следующее условие:
//If my sidebar is going to occupy more than half the new width of the view...
if( self.sidebarTransitionController.width > size.width / 2.0 )
{
//Override the presentation controller trait collection with Compact horizontal size class
sidebarPresentationController.overrideTraitCollection = [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];
}
else
{
//Otherwise override the trait collection with Regular
sidebarPresentationController.overrideTraitCollection = [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular];
}
Однако это ничего не делает. В документации для UIPresentationController.overrideTraitCollection
указано:
Используйте это свойство, чтобы указать какие-либо черты, которые вы хотите применить к представленным и представленным контроллерам представлений. Указанные вами черты переопределяют любые существующие в настоящее время свойства для контроллеров представления. Значение по умолчанию этого свойства равно nil.
Присвоение нового значения этому свойству заставляет контроллер представления перейти к новому набору признаков, что может привести к анимации к представленному интерфейсу.
Назначение нового значения контроллеру презентации не приводит к изменению моего отображаемого интерфейса. (Даже если я назначаю overrideTraitCollection
, когда UIPresentationController
создается из объекта UIViewControllerTransitioningDelegate
.)
Что мне не хватает? Возможно ли выполнить адаптивное представление с UIPresentationController
на более гранулированном уровне?
Ответы
Ответ 1
Возможно ли выполнить адаптивное представление с UIPresentationController
на более узком уровне?
Не легко.
Я предлагаю один из следующих вариантов:
-
Отказаться от контроля и принять ограниченную адаптивность UIKits: вы можете перейти на полноэкранную презентацию или представить другой контроллер представления для определенной коллекции признаков. Пойдите с этим, чтобы быстрее отправить ваше приложение.
-
Используйте презентации, но работайте с UIKit. Один из способов - переопределить viewWillTransitionToSize:withTransitionCoordinator:
и уволить, а затем повторно представить представленный контроллер представления, внести любые изменения, которые вы хотите, например, предоставить другой стиль презентации или контроллер представления. Это может дать хорошие результаты, не занимая слишком много времени.
-
Использовать сдерживание контроллера. Это самый низкий уровень, который вы можете использовать, придерживаясь лучших практик UIKit. Ваш главный контроллер представлений становится дочерним элементом контроллера представления контейнера, и вместо того, чтобы представлять, вы спрашиваете контейнер, чтобы показать другой контроллер представления. Пойдите с этим, если приложение должно быть обычным и изысканным, и вы можете потратить время, чтобы сделать его в порядке.
Ответ 2
Использование:
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller
traitCollection:(UITraitCollection *)traitCollection NS_AVAILABLE_IOS(8_3);
Он вызвал вращение, даже если класс размера не изменился, поэтому это хорошее место для адаптации к идиоме/ориентации. Помните, что iPhone 6 может работать в увеличенном режиме.
Ответ 3
Я столкнулся с той же проблемой. Возможно интерпретировать ориентацию устройства из классов размеров, хотя и не совсем однозначно, но следующее сработало для моих целей.
От Программирование iOS 9: погружение в глубину в представления, просмотр контроллеров и фреймворков, отличная книга, полная важных деталей вроде этого:
horizontalSizeClass
, verticalSizeClass
A UIUserInterfaceSizeClass
значение, либо .Regular
, либо .Compact
. Они называются классами размера. Классы размера в сочетании имеют следующие значения:
Оба вертикальных и горизонтальных класса размера .Regular
: мы работаем на iPad
Класс вертикального размера .Regular
, но класс горизонтального размера .Compact
: мы работаем на iPhone с приложением в портретной ориентации. (В качестве альтернативы мы можем работать на iPad в многозадачной конфигурации iPad сплит-скриншотом, см. Главу 9).
Оба класса по вертикали и горизонтали .Compact
: мы работаем на iPhone (кроме iPhone 6 плюс) с приложением в альбомной ориентации.
Класс вертикального размера .Compact
, а класс горизонтального размера .Regular
: мы работаем на iPhone 6 плюс в альбомной ориентации.
например. в контроллере просмотра:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ShowComposeView" {
segue.destinationViewController.presentationController!.delegate = self
segue.destinationViewController.modalPresentationStyle = .PageSheet
}
}
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
// If we do an adaptive presentation, and adapt from Page Sheet to Form Sheet,
// then on iPhone 6 we will get the nice rounded corners of the nav bar
// in both portrait and landscape. (From pg. 298 of Programming iOS 9)
// We want this behaviour on iPhone in Portrait orientation only.
if traitCollection.horizontalSizeClass == .Compact && traitCollection.verticalSizeClass == .Regular {
return .FormSheet
}
else {
return .PageSheet
}
}