Xcode: how to change the layout between landscape and portrait modes

In portrait mode, I have four views from above each other from top to bottom of the view controller (see image).

portrait view

Then I want to change the position of the views relative to each other when the device goes into landscape mode (see image two). landscape

I want view 4 to move along with views 2 and 3, and they all sit under image 1.

Some layout conditions:

  • view 1 is attached to the top of the view controller in both landscape and portrait mode.
  • view 4 is attached to the left, right, and lower margins of the view controller in portrait mode.
  • Views 2, 3, and 4 are arranged horizontally in portrait mode.

What is the best method to achieve different layouts?

viewWillTransition? , ( , 2, 3 4, , , 4 )?

+4
2

/ . " ".

, , "Vary for traits":

enter image description here

" ":

enter image description here

" " ( "Vary for traits", , "Done differenting":

enter image description here

, , . , , :

enter image description here

. WWDC 2016 :

+9

/ .

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 ( -) . , viewWillTransistion(toSize:) viewDidLoadSubviews() 'viewWillLoadSubviews() `- , !

+1

Source: https://habr.com/ru/post/1670179/


All Articles