XCode: как изменить расположение видов между альбомным и портретным режимами



В портретном режиме у меня есть четыре вида поверх друг друга сверху донизу контроллера вида (см. изображение).



посмотреть портрет



Затем я хочу изменить положение видов относительно друг друга, когда устройство переходит в альбомную ориентацию (см. Рисунок 2).пейзажный вид



Я хочу, чтобы вид 4 двигался рядом с видами 2 и 3, и все они сидят ниже вида 1.



Некоторые условия компоновки:




  • Вид 1 прикреплен к верхней части контроллер вида как в альбомной, так и в портретной ориентации.

  • Вид 4 прикрепляется к левому, правому и нижнему полям контроллера вида в портретном режиме.
  • виды 2, 3 и 4 центрируются горизонтально в пределах портретного вида.


Каков наилучший метод достижения различных макетов?



Было бы самым элегантным решением сделать ссылку на ограничения в коде контроллеров вида и активировать и деактивировать их в viewWillTransition? Или есть есть способ использовать vary for traits для достижения этой цели (я могу представить, что виды 2, 3 и 4, центрированные по горизонтали, сделают это труднодостижимым, а также добавят новые ограничения для вида 4 в ландшафтном режиме)?

616   2  

2 ответов:

Мы привыкли устанавливать различные наборы ограничений и активировать/деактивировать их на основе изменения ориентации. Но в наше время можно использовать размерные классы и "варьировать по признакам".

Например, я начинаю с простого представления и выбираю класс компактной ширины, а затем выбираю "варьировать по признакам":

Введите описание изображения здесь

Я затем добавить соответствующие ограничения и нажмите на кнопку "сделать изменения":

Введите описание изображения здесь

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

Введите описание изображения здесь

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

Введите описание изображения здесь

Дополнительную информацию смотрите в видеороликах WWDC 2016 об адаптивных макетах:

Я использую массивы ограничений и активирую / деактивирую в соответствии с ориентацией.

var p = [NSLayoutConstraint]()
var l = [NSLayoutConstraint]()
var initialOrientation = true
var isInPortrait = false

override func viewDidLoad() {
    super.viewDidLoad()
    // add any subviews here
    view.turnOffAutoResizing()        
    // add constraints here....
    //    common constraints you can set their isActive = true
    //    otherwise, add in to portrait(p) and landscape(l) arrays
}

override func viewWillLayoutSubviews() {
    super.viewDidLayoutSubviews()
    if initialOrientation {
        initialOrientation = false
        if view.frame.width > view.frame.height {
            isInPortrait = false
        } else {
            isInPortrait = true
        }
        view.setOrientation(p, l)
    } else {
        if view.orientationHasChanged(&isInPortrait) {
            view.setOrientation(p, l)
        }
    }
}
extension UIView {
    public func turnOffAutoResizing() {
        self.translatesAutoresizingMaskIntoConstraints = false
        for view in self.subviews as [UIView] {
           view.translatesAutoresizingMaskIntoConstraints = false
        }
    }
    public func orientationHasChanged(_ isInPortrait:inout Bool) -> Bool {
        if self.frame.width > self.frame.height {
            if isInPortrait {
                isInPortrait = false
                return true
            }
        } else {
            if !isInPortrait {
                isInPortrait = true
                return true
            }
        }
        return false
    }
    public func setOrientation(_ p:[NSLayoutConstraint], _ l:[NSLayoutConstraint]) {
        NSLayoutConstraint.deactivate(l)
        NSLayoutConstraint.deactivate(p)
        if self.bounds.width > self.bounds.height {
            NSLayoutConstraint.activate(l)
        } else {
            NSLayoutConstraint.activate(p)
        }
    }
}

Мои потребности различать портрет или ландшафт требуют использования чего-то иного, чем классы размеров, поскольку мое приложение универсально, а iPad (если не использовать split или slide out view) - это Всегда нормальный размер. Кроме того, вы можете использовать viewWillTransistion(toSize:) или viewDidLoadSubviews() вместо "viewWillLoadSubviews ()" - но всегда тестируйте, так как они могут выполняться несколько раз при изменении ориентации!

Comments

    Ничего не найдено.