Сайзклассы

В iOS для характеристики доступного на экране места введено понятие сайзклассов. Каждому устройству и положению дисплея задано по два сайзкласса: вертикальный и горизонтальный, чьи значения определяют размеры (обычный или компактный) соответствующих сторон. Device size classes overview

Можно заметить, что на Айпадах сайзклассы всегда одинаковые, исключением является режим многозадачности, в нем каждое окно будет иметь свои значения в зависимости от занимаемой доли экрана. iPad multitasking size classes overview

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

Для примера рассмотрим ситуацию — есть один общий для всех устройств интерфейс с привязкой объектов к сайзклассам, занимающей в портретном режиме больше вертикаль, а в альбомном горизонталь. Но как мы знаем, на Айпадах сайзклассы не меняются при повороте, остается выходить из ситуации программными путями.

На текущий момент в iOS SDK для этих целей существует один способ — метод setOverrideTraitCollection класса UIViewController. Через него можно переопределять различные характеристики дочерних контроллеров. Последнее означает, что придется создавать контроллер-контейнер, в который помещать основной. Возвращаясь к нашему примеру, алгоритм изменения сайзклассов при повороте Айпада может выглядеть следующим образом:

import UIKit

class ContainerViewController: UIViewController {
    weak var viewController: ViewController!

    override func viewDidLoad() {
        super.viewDidLoad()
        viewController = childViewControllers[0] as! ViewController
    }

    // Catch iPad display resizing and change size classes for main view controller
    override func viewWillTransitionToSize(size: CGSize,
          withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
        
        if traitCollection.userInterfaceIdiom == .Pad {
            let oldTraitCollection = viewController.traitCollection
            let newTraitCollection: UITraitCollection
            
            if size.width > size.height {
                // Landscape orientation
                newTraitCollection = UITraitCollection(traitsFromCollections:
                                       [oldTraitCollection,
                                        UITraitCollection(horizontalSizeClass: .Regular),
                                        UITraitCollection(verticalSizeClass: .Compact)])
            } else {
                // Portrait orientation
                newTraitCollection = UITraitCollection(traitsFromCollections:
                                       [oldTraitCollection,
                                        UITraitCollection(horizontalSizeClass: .Compact),
                                        UITraitCollection(verticalSizeClass: .Regular)])
            }
            
            setOverrideTraitCollection(newTraitCollection, 
                                       forChildViewController: viewController)
        }
    }
}

Готовый тестовый проект доступен по ссылке: ManualSizeClassesChange.zip.