user12418101
user12418101

Reputation:

use auto layout to space objects evenly apart

My code below is trying to be based of the photo below. PicLocate should take up 60 percent height of the view. Pic[0] and Pic1 should take up 10 percent height and should be have even width.All of the objects should be spaced of 10 - 15 gap between the views. Mainly it should look just like the photo

enter image description here

    import UIKit
class ViewController: UIViewController {
var picLocate = UIImageView()
var jessicaAlba:Float = 50
var topConstraint: NSLayoutConstraint!
var heightConstraint: NSLayoutConstraint!
var leadingConstraint: NSLayoutConstraint!
var trailingConstraint: NSLayoutConstraint!

let pic = (0..<3).map { _ in UIButton() }


override func viewDidLoad() {
    super.viewDidLoad()

    [picLocate,pic[0],pic[1]].forEach {
        $0.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview($0)
        $0.backgroundColor = .systemOrange
    }


    pic[0].topAnchor.constraint(equalTo: picLocate.bottomAnchor, constant: 10).isActive = true
    pic[0].leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10).isActive = true
    pic[0].trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -300).isActive = true
    pic[0].bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -300).isActive = true

    pic[1].topAnchor.constraint(equalTo: picLocate.bottomAnchor, constant: 10).isActive = true
    pic[1].leadingAnchor.constraint(equalTo: pic[0].trailingAnchor, constant: 10).isActive = true
    pic[1].trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10).isActive = true
    pic[1].bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -300).isActive = true



    pic[0].setTitle("Add Box", for: .normal)
    pic[1].setTitle("Save Photo", for: .normal)




    topConstraint = picLocate.topAnchor.constraint(equalTo: view.topAnchor, constant: CGFloat(jessicaAlba))
    topConstraint.isActive = true
    heightConstraint = picLocate.heightAnchor.constraint(equalTo: view.heightAnchor , multiplier: 0.6, constant: CGFloat(-jessicaAlba))
    heightConstraint.isActive = true

    leadingConstraint = picLocate.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: CGFloat(jessicaAlba))
    leadingConstraint.isActive = true
    trailingConstraint = picLocate.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: CGFloat(-jessicaAlba))
    trailingConstraint.isActive = true


}

}

Upvotes: 0

Views: 58

Answers (1)

DonMag
DonMag

Reputation: 77423

It can be very helpful to comment your constraints as you write them. Quite often, that makes you realize what you want to do...

To get your desired layout, you want to:

  • set picLocate height to 60% of the view height (with your current code, you are also subtracting 50-pts from that 60%)
  • set leading of the left pic (button) to leading of picLocate
  • set trailing of the right pic (button) to trailing of picLocate
  • set leading of right pic to trailing of left pic + 10-pts for spacing
  • then set right pic width equal to left pic width

Result:

enter image description here

and, in landscape orientation, it auto-adjusts to the desired percentages:

enter image description here

This is your code, with the changes I described. Take a look, and review the comments:

class ViewController: UIViewController {

    var picLocate = UIImageView()

    var jessicaAlba:CGFloat = 50

    var topConstraint: NSLayoutConstraint!
    var heightConstraint: NSLayoutConstraint!
    var leadingConstraint: NSLayoutConstraint!
    var trailingConstraint: NSLayoutConstraint!

    let pic = (0..<3).map { _ in UIButton() }

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .white

        [picLocate,pic[0],pic[1]].forEach {
            $0.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview($0)
            $0.backgroundColor = .systemOrange
        }

        // 50-pts (jessicaAlba) from top of view
        topConstraint = picLocate.topAnchor.constraint(equalTo: view.topAnchor, constant: jessicaAlba)

        // 60% of view height minus 50-pts == ((0.6 * view height) - 50)
        heightConstraint = picLocate.heightAnchor.constraint(equalTo: view.heightAnchor , multiplier: 0.6, constant: -jessicaAlba)

        // if you actually want 60% of view height, set constant to 0.0
        //heightConstraint = picLocate.heightAnchor.constraint(equalTo: view.heightAnchor , multiplier: 0.6, constant: 0.0)

        // 50-pts leading and trailing
        leadingConstraint = picLocate.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: jessicaAlba)
        trailingConstraint = picLocate.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -jessicaAlba)

        NSLayoutConstraint.activate([

            topConstraint,
            heightConstraint,
            leadingConstraint,
            trailingConstraint,

            // "left pic" top is 10-pts below "picLocate" bottom
            pic[0].topAnchor.constraint(equalTo: picLocate.bottomAnchor, constant: 10.0),

            // "left pic" leading equal to "picLocate" leading
            pic[0].leadingAnchor.constraint(equalTo: picLocate.leadingAnchor, constant: 0.0),

            // "left pic" height equal to 10% of view height
            pic[0].heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.10),

            // "right pic" top equal to "left pic" top
            pic[1].topAnchor.constraint(equalTo: pic[0].topAnchor),

            // "right pic" height equal to "left pic" height
            pic[1].heightAnchor.constraint(equalTo: pic[0].heightAnchor),

            // "right pic" trailing equal to "picLocate" trailing
            pic[1].trailingAnchor.constraint(equalTo: picLocate.trailingAnchor, constant: 0.0),

            // "right pic" leading equal to "left pic" trailing plust 10-pts
            pic[1].leadingAnchor.constraint(equalTo: pic[0].trailingAnchor, constant: 10.0),

            // "right pic" width equal to "left pic" width
            pic[1].widthAnchor.constraint(equalTo: pic[0].widthAnchor),

        ])

        pic[0].setTitle("Add Box", for: .normal)
        pic[1].setTitle("Save Photo", for: .normal)

    }
}

Upvotes: 1

Related Questions