Разные классы размера для портретных и ландшафтных режимов iPad с ограничениями
Я нашел этот вопрос, и я попытался реализовать решение, которое было предоставлено. Однако я столкнулся с проблемой.
У моего контроллера начального представления есть два вида контейнеров, у которых есть свой собственный контроллер вида. Я создал контроллер корневого представления, который назначен контроллеру начального представления. Код в этом классе выглядит следующим образом.
class RootViewController: UIViewController {
var willTransitionToPortrait: Bool!
var traitCollection_CompactRegular: UITraitCollection!
var traitCollection_AnyAny: UITraitCollection!
override func viewDidLoad() {
super.viewDidLoad()
setupReferenceSizeClasses()
// Do any additional setup after loading the view.
}
override func viewWillAppear(animated: Bool) {
willTransitionToPortrait = self.view.frame.size.height > self.view.frame.size.width
}
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
willTransitionToPortrait = size.height > size.width
}
func setupReferenceSizeClasses(){
let traitCollection_hCompact = UITraitCollection(horizontalSizeClass: .Compact)
let traitCollection_vRegular = UITraitCollection(verticalSizeClass: .Regular)
traitCollection_CompactRegular = UITraitCollection(traitsFromCollections: [traitCollection_hCompact, traitCollection_vRegular])
let traitCollection_hAny = UITraitCollection(horizontalSizeClass: .Unspecified)
let traitCollection_vAny = UITraitCollection(verticalSizeClass: .Unspecified)
traitCollection_AnyAny = UITraitCollection(traitsFromCollections: [traitCollection_hAny, traitCollection_vAny])
}
override func overrideTraitCollectionForChildViewController(childViewController: UIViewController) -> UITraitCollection? {
let traitCollectionForOverride = ((willTransitionToPortrait) != nil) ? traitCollection_CompactRegular : traitCollection_AnyAny
return traitCollectionForOverride;
}
Однако, когда я запускаю его, класс размера не будет отвечать так, как должен. Один из контроллеров просмотра контейнеров начнет действовать странно в ландшафтном и портретном режимах, как показано ниже.
![портретный режим]()
Когда я не назначу rootviewcontroller, это будет выглядеть так
![портретный режим]()
Пока он выглядит в портретном режиме
![портретный режим, как он должен выглядеть]()
Кто-нибудь знает, что здесь может быть неправильным? Почему он не меняет класс размера, как хотелось бы.
ИЗМЕНИТЬ
Как @Muhammad Yawar Ali спросили здесь скриншоты с позиции всех классов размера, которые я установил. У меня нет предупреждений или ошибок о любых ограничениях, поэтому эти скриншоты содержат обновленные представления.
![введите описание изображения здесь]()
Надеюсь, это показывает все, что нужно.
EDIT:
по какой-то причине я не могу поставить все скриншоты
Ответы
Ответ 1
На viewWillTransitionToSize
вам нужно вызвать также супер, чтобы передать событие следующему ответчику (ваш rootviewcontroller)...
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
willTransitionToPortrait = size.height > size.width
}
Ответ 2
Поймите, что это более двух лет, но...
Я просто столкнулся с тем, что, по моему мнению, является аналогичной проблемой. Что вы можете забыть, так это то, что "overrideTraitCollectionForChildViewController" переопределяет представления children, поэтому этот метод ничего не будет делать с контейнерами, так как они находятся в корне.
Я решил, что поместил два контейнера в UIStackView в Interface Builder и сделал свойство этого стека в коде, а затем обновил ось в зависимости от ориентации. Например, в Objective-C:
@property (слабый, неатомный) IBOutlet UIStackView * rootStack;
//...
- (UITraitCollection *) overrideTraitCollectionForChildViewController: (UIViewController *) childViewController
{ if (UI_USER_INTERFACE_IDIOM()!= UIUserInterfaceIdiomPad) { return [super overrideTraitCollectionForChildViewController: childViewController]; }
if (CGRectGetWidth (self.view.bounds) < CGRectGetHeight (self.view.bounds)) { self.rootStack.axis = UILayoutConstraintAxisVertical; return [UITraitCollection traitCollectionWithHorizontalSizeClass: UIUserInterfaceSizeClassCompact]; } else { self.rootStack.axis = UILayoutConstraintAxisHorizontal; return [UITraitCollection traitCollectionWithHorizontalSizeClass: UIUserInterfaceSizeClassRegular];
}
Код>
Если у вас есть какие-либо ограничения, которые отличаются между портретом и ландшафтом, вам также нужно будет скорректировать их в коде.
Я предполагаю, что вы также можете решить эту проблему, вставив контроллер представления с контейнерами в другой контроллер представления.
Ответ 3
Я клонировал ваш код из репозитория: https://github.com/MaikoHermans/sizeClasses.git
И редактируемый код помещает приведенный ниже код в ваш контроллер, он будет работать нормально и не повлияет на ваш дизайн в iPads. import UIKit
class RootViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func overrideTraitCollectionForChildViewController(childViewController: UIViewController) -> UITraitCollection? {
if view.bounds.width < view.bounds.height {
return UITraitCollection(horizontalSizeClass: .Unspecified)
} else {
return UITraitCollection(horizontalSizeClass: .Regular)
}
}
}
Вы можете попробовать с помощью этого кода, но есть проблема. Я считаю, что его неправильное обновление свойств для ipads и просмотр макета остается таким же, но выглядит хорошо. Я пробовал несколько способов, но не успел обновить свой ответ.