YogevSitton
YogevSitton

Reputation: 10108

Auto-Layout fit to parent via code in Swift

I have a view i'm creating via code and adding to another view as subview. The new superview can change it's frame over time and I want the newly created subview to change it's frame accordingly. How can I do that using Auto-Layout via code in Swift?

Upvotes: 8

Views: 4916

Answers (4)

CmoiJulien
CmoiJulien

Reputation: 697

You can also activate the constraints like that :

let view = UIView() // existing view

let subview = UIView()
subview.translatesAutoresizingMaskIntoConstraints = false

view.addSubview(subview)


NSLayoutConstraint.activate([
                view.leadingAnchor.constraint(equalTo: subview.leadingAnchor),
                view.trailingAnchor.constraint(equalTo: subview.trailingAnchor),
                view.topAnchor.constraint(equalTo: subview.topAnchor),
                view.bottomAnchor.constraint(equalTo: subview.bottomAnchor)
            ])

Upvotes: 0

Merricat
Merricat

Reputation: 2841

iOS 13, swift 5

First, you add this code

    subview.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(subview)

Then, there are two ways of doing this in newer versions of iOS.

  1. With NSLayoutConstraint class

    NSLayoutConstraint(item: subview, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0).isActive = true
    NSLayoutConstraint(item: subview, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: 0).isActive = true
    NSLayoutConstraint(item: subview, attribute: .left, relatedBy: .equal, toItem: view, attribute: .left, multiplier: 1, constant: 0).isActive = true
    NSLayoutConstraint(item: subview, attribute: .right, relatedBy: .equal, toItem: view, attribute: .right, multiplier: 1, constant: 0).isActive = true
    
  2. With NSLayoutAnchor class (less verbose)

    subview.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    subview.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
    subview.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
    subview.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
    

Either way, on iOS 8 and later Apple recommends using isActive() instead of adding constraints directly to a view.

Additionally, I believe the purpose of the NSLayoutAnchor method is to be more concise and readable compared to NSLayoutConstraint.

Upvotes: 6

Petr B.
Petr B.

Reputation: 891

As @rjobidon mentioned you should use following code (Swift3)

    let view = UIView() // existing view

    let subview = UIView()
    subview.setTranslatesAutoresizingMaskIntoConstraints(false)

    view.addSubview(subview)

    NSLayoutConstraint(item: subview, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1.0, constant: 0.0).isActive = true
    NSLayoutConstraint(item: subview, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1.0, constant: 0.0).isActive = true
    NSLayoutConstraint(item: view, attribute: .bottom, relatedBy: .equal, toItem: subview, attribute: .bottom, multiplier: 1.0, constant: 0.0).isActive = true
    NSLayoutConstraint(item: view, attribute: .trailing, relatedBy: .equal, toItem: subview, attribute: .trailing, multiplier: 1.0, constant: 0.0).isActive = true

Upvotes: 0

Kirsteins
Kirsteins

Reputation: 27335

Here is an example:

let view = UIView() // existing view

let subview = UIView()
subview.setTranslatesAutoresizingMaskIntoConstraints(false)

view.addSubview(subview)
view.addConstraint(NSLayoutConstraint(item: subview, attribute: .Top, relatedBy: .Equal, toItem: view, attribute: .Top, multiplier: 1.0, constant: 0.0))
view.addConstraint(NSLayoutConstraint(item: subview, attribute: .Leading, relatedBy: .Equal, toItem: view, attribute: .Leading, multiplier: 1.0, constant: 0.0))
view.addConstraint(NSLayoutConstraint(item: view, attribute: .Bottom, relatedBy: .Equal, toItem: subview, attribute: .Bottom, multiplier: 1.0, constant: 0.0))
view.addConstraint(NSLayoutConstraint(item: view, attribute: .Trailing, relatedBy: .Equal, toItem: subview, attribute: .Trailing, multiplier: 1.0, constant: 0.0))

Upvotes: 9

Related Questions