Установить программный режим AutoLayout Size Class?

С iOS 8 и Xcode 6, в раскадровки, мы теперь имеем сетку размера экрана, позволяющую выбрать класс размера. Где вы можете выбрать форматирование макета для разных размеров экрана.

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

Мой вопрос: можете ли вы сделать это программно? Я создаю свой NSLayoutConstraint как обычно, но мне нужно указать различные ограничения для разных размеров экрана.

Ответы

Ответ 1

iOS 8 вводит свойство active в NSLayoutConstraint. Это позволяет вам активировать или деактивировать ограничение. Существуют также способы активировать/деактивировать несколько ограничений.

+ (void)activateConstraints:(NSArray *)constraints
+ (void)deactivateConstraints:(NSArray *)constraints
  • Сохраняйте свои ограничения в массивах при их программном программировании.
  • Создайте массив для каждого из макетов, которые вам нужны.
  • Активировать/деактивировать любой набор ограничений, необходимых вам в willTransitionToTraitCollection

Ответ 2

Это немного запутанно и сложно найти в документации, потому что "класс размера" на самом деле не является "классом", как NSObject. Они действительно определены в enum/typedef: UIUserInterfaceSizeClass

Способ получения горизонтального и вертикального класса размера для представления - UITraitCollection

Методы класса/типа для UITraitCollection позволяют создавать их на основе определенной шкалы отображения (например, сетчатки или нет), из массива других коллекций признаков, с идиомой интерфейса (iPad/iPhone) или с конкретными горизонтальными и вертикальными варианты (компактные, обычные), но, честно говоря, я еще не уверен, как вы это используете...

В этом вопросе обсуждается обновление ограничений при изменении значения traitCollection с помощью willTransitionToTraitCollection(newCollection: UITraitCollection!, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator!)

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

Этот предыдущий вопрос довольно похож и ссылается на статью Apple об использовании Adaptive Layout. Также проверьте видео WWDC "Создание адаптивных приложений с помощью UIKit" .

Ответ 3

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

В моей ситуации я хотел изменить Master VC контроллера разделенного вида на iPad, чтобы выглядеть по-другому, чем тот, который есть на iPhone, однако по умолчанию оба они установлены на Compact width/Regular height. Поэтому я подклассифицировал главный навигационный контроллер и добавил код, чтобы установить основные черты на обычную ширину, когда это не iPhone.

Быстрый код:

class MasterNavigationController: UINavigationController {

    override func viewDidLoad() {
        super.viewDidLoad()
        if (self.traitCollection.userInterfaceIdiom != .Phone) {
            let newTraitCollection = UITraitCollection(horizontalSizeClass: .Regular)
            self.setOverrideTraitCollection(newTraitCollection, forChildViewController: self.topViewController)
        }
    }

} 

Надеюсь, это поможет кому-то найти подобное решение.