Brandon Bravos
Brandon Bravos

Reputation: 430

Swift: Constraints incorrect when device is started in landscape

I currently have an application where I programmatically set the constraints. The problem occurs when the app is started in landscape mode. When the app is started in landscape mode, the size of the UIViews width and height extend past the screen. However, when the app is started in portrait mode, the app is fine, and it keeps its constraints properly when rotating. This seems to only be a problem when opening the app in landscape. Here is my code and screen shots:

  func setUpGameBoard(){
    let width =  UIScreen.main.bounds.width
   let gameBoard = Gameboard(frame: .zero, mainVC: self)
    self.view.addSubview(gameBoard)
    gameBoard.translatesAutoresizingMaskIntoConstraints = false
    gameBoard.widthAnchor.constraint(equalToConstant: width).isActive = true
    gameBoard.heightAnchor.constraint(equalToConstant: width).isActive = true
    gameBoard.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    gameBoard.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true

        }

When app started in landscape

Here it is when started upright, there is no problems when rotating.

when app started in portrait

Upvotes: 0

Views: 1759

Answers (2)

Galo Torres Sevilla
Galo Torres Sevilla

Reputation: 1575

The problem here is that when you start your app in landscape the width of the screen is actually the height of portrait mode. So you can add a simple check to see if the launching orientation is either landscape or portrait and update the constraints accordingly:

if UIDevice.current.orientation.isLandscape {
    let height = self.view.frame.height
    gameBoard.widthAnchor.constraint(equalToConstant: height).isActive = true
    gameBoard.heightAnchor.constraint(equalToConstant: height).isActive = true
} else if UIDevice.current.orientation.isPortrait {
    let width = self.view.frame.width
    gameBoard.widthAnchor.constraint(equalToConstant: width).isActive = true
    gameBoard.heightAnchor.constraint(equalToConstant: width).isActive = true
}

Upvotes: 2

Andrew21111
Andrew21111

Reputation: 908

Basically, in landscape the width of the screen is way larger. This happens because in landscape the width ( that you use in portrait ) becomes the height.

This is a really good and useful resource by Apple to understand what they call Auto layout: Auto Layout Guide

Your problem is about Size Classes and they are an advanced Auto Layout system, you can know more about here Size Classes specific Auto Layout

This is a really good tutorial for Auto Layout by Ray Wenderlich: Auto Layout Tutorial

There are several ways to achieve your goal:

1. If you can set the constraints from storyboard, it's way easier to set different constraints based on portrait/landscape using Size Class, you will find lot of tutorial and resources, but I link you this one. It's in Italian, but I grant you this is complete about Size Classes and with google translate it will be easy understand.

2. You can use this code to check in what mode you are:

    if UIDevice.current.orientation == UIDeviceOrientation.landscapeLeft {

    } else if UIDevice.current.orientation == UIDeviceOrientation.landscapeRight {

    } else if UIDevice.current.orientation == UIDeviceOrientation.portrait {

    } else if UIDevice.current.orientation == UIDeviceOrientation.portraitUpsideDown {

    } 

3. you can "manually" check the width:

Es.

// I used a random value, but it should be around the width value in portrait
           if(width > 389){
              width = 389
            }

4. Using Size Classes programmatically is also a solution, but i'd never use it. However, this is a good tutorial on how to use them programmatically: Using Trait Collections for Auto Layout and Size Classes

Upvotes: 2

Related Questions