How to always position button 2/3 way down the screen

I am making an application to work on many various iPhone models in portrait mode. I would like to have a button (with fixed height) always be afixed at a position 2/3 way down the screen display area no matter what iPhone model is used. I understand I can do this by pinning two views in the storyboard and then setting Equal heights with 1:3 and 2:3 ratios, however, is there a way to do this without introducing two views into the storyabord for this purpose?

Accepted Reply

Yes, do it programmatically.


Create a constraint relative to top of safe area.

Create an IBOutlet for the constraint (control-drag from constraint to ViewController) : topConstraint

In viewWillLayoutSubviews, compute the correct value and set it:


// To get screensize:
func getScreenSize() -> (height: CGFloat, width: CGFloat, topPadding: CGFloat, bottomPadding: CGFloat) {
   
    // Get the screen width and height.
    let screenWidth = UIScreen.main.bounds.size.width
    var screenHeight = UIScreen.main.bounds.size.height
    var topPadding = CGFloat(0)
    var bottomPadding = CGFloat(0)
    if #available(iOS 11.0, *) {
        if let window = UIApplication.shared.keyWindow {
            topPadding = window.safeAreaInsets.top
            bottomPadding = window.safeAreaInsets.bottom
            if (topPadding > 0 && bottomPadding > 0) {
                screenHeight -= topPadding 
            }  
        }
    }
    return (screenHeight, screenWidth, topPadding, bottomPadding)
}



    override func viewWillLayoutSubviews() {
 
        super.viewWillLayoutSubviews()

        let screenHeight = getScreenSize().height
        topConstraint.constant = 2 * screenHeight / 3 // 2/3 from top ; for 1/3 from top topConstraint.constant = screenHeight / 3
}

Replies

Yes, do it programmatically.


Create a constraint relative to top of safe area.

Create an IBOutlet for the constraint (control-drag from constraint to ViewController) : topConstraint

In viewWillLayoutSubviews, compute the correct value and set it:


// To get screensize:
func getScreenSize() -> (height: CGFloat, width: CGFloat, topPadding: CGFloat, bottomPadding: CGFloat) {
   
    // Get the screen width and height.
    let screenWidth = UIScreen.main.bounds.size.width
    var screenHeight = UIScreen.main.bounds.size.height
    var topPadding = CGFloat(0)
    var bottomPadding = CGFloat(0)
    if #available(iOS 11.0, *) {
        if let window = UIApplication.shared.keyWindow {
            topPadding = window.safeAreaInsets.top
            bottomPadding = window.safeAreaInsets.bottom
            if (topPadding > 0 && bottomPadding > 0) {
                screenHeight -= topPadding 
            }  
        }
    }
    return (screenHeight, screenWidth, topPadding, bottomPadding)
}



    override func viewWillLayoutSubviews() {
 
        super.viewWillLayoutSubviews()

        let screenHeight = getScreenSize().height
        topConstraint.constant = 2 * screenHeight / 3 // 2/3 from top ; for 1/3 from top topConstraint.constant = screenHeight / 3
}

Thanks a lot. This is really helpful