Programmatically Creating Constraints Bound to View Controller Margins

Programmatically creating constraints bound to view controller margins

Actually the problem in your code is that you did not set the translatesAutoresizingMaskIntoConstraints of myview to false, whenever you want to use auto-layout constraints then you have to set translatesAutoresizingMaskIntoConstraints of a view to false.
Another Problem is that you do not add myview on self.view I have updated your code and Its working fine According your constraints.

Put below code in your ViewController .

let myView = UIView()
myView.backgroundColor = UIColor.redColor()
self.view.addSubview(myView)
myView.translatesAutoresizingMaskIntoConstraints = false

view.addConstraint(NSLayoutConstraint(item: myView, attribute: .Top, relatedBy: .Equal, toItem: self.topLayoutGuide, attribute: .Bottom, multiplier: 1, constant: 0))
view.addConstraint(NSLayoutConstraint(item: myView, attribute: .Bottom, relatedBy: .Equal, toItem: self.bottomLayoutGuide, attribute:.Top, multiplier: 1, constant: 20))

view.addConstraint(NSLayoutConstraint(item: myView, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute,multiplier: 1, constant: 300))
view.addConstraint(NSLayoutConstraint(item: myView, attribute: .TrailingMargin, relatedBy: .Equal, toItem: view, attribute: .TrailingMargin, multiplier: 1, constant: 0))

How to change the layout margins programmatically

This seems to be fixed/changed for iOS 11. Lower versions are out of luck.

I've elaborated more in this question

How to programmatically add constraints to a stackView

If your question is how to convert this:

stackView.frame =  CGRect(x: 0, y: 547, width: 390, height: 350)

and make the height 1/4 of the screen instead of 350

Converting this request into auto layout constraints would go something like this

private func configureStackView()
{
let paddedStackView = UIStackView(arrangedSubviews: [segmentedControl])
paddedStackView.layoutMargins = .init(top: 12,
left: 12,
bottom: 6,
right: 12)

paddedStackView.isLayoutMarginsRelativeArrangement = true

let stackView = UIStackView(arrangedSubviews: [paddedStackView, map])
stackView.axis = .vertical
view.addSubview(stackView)

// AUTO LAYOUT

// This is important for using auto layout
// Setting this to false means the frame is ignored
// So sizing and positioning should be set by NSLayoutConstraints
stackView.translatesAutoresizingMaskIntoConstraints = false

// Add the view to its parent before adding any constraints
view.addSubview(stackView)

// Add constraints equivalent to:
// CGRect(x: 0, y: 547, width: 390, height: 350)
view.addConstraints([
// this is x origin
stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor),

// this is y origin
stackView.topAnchor.constraint(equalTo: view.topAnchor,
constant: 547),

// this is the width
stackView.widthAnchor.constraint(equalToConstant: 390),

// this is height, thanks to @flanker for this update
stackView.heightAnchor.constraint(equalTo: view.heightAnchor,
multiplier: 0.75)
])
}

This should give you what you are looking for.

With that being said, you probably want to check out this SO thread as there are different ways to add auto layout constraints programmatically so see which way you prefer

Update with screenshot

The above configuration gives something like this

Programmatically create UIStackView with auto layout constraints swift iOS

Adding constraints programmatically makes crash

You are trying to set a constraint to a view that is outside your view hierarchy. Auto Layout system provides layout guides to help you align your views with navigation bars and tab bars.

In your bottom constraint, replace self.tabBarController?.tabBar with bottomLayoutGuide.

As a side note, new layout syntax (available on iOS 9+) makes much easier creating programmatic constraints without third party libraries:

let topConstraint = tableView.topAnchor.constraint(equalTo: mapView.bottomAnchor)
let bottomConstraint = tableView.bottomAnchor.constraint(equalTo: bottomLayoutGuide.topAnchor)
let leadingConstraint = tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor)
let trailingConstraint = tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor)

More info for creating programmatic constraints here.

How to Create layout constraints programmatically

To fix a view to the bottom of the screen you need following constraints to set.

  1. Leading Constraint with respect of Parent View for - X
  2. Trailing Constraint with respect of Parent View for - Width
  3. Bottom Constraint with respect of Parent View for - Y
  4. Height Constraint attached to self for - Height.

Lets add.

UIView *subView=bottomView;
UIView *parent=self.view;

subView.translatesAutoresizingMaskIntoConstraints = NO;

//Trailing
NSLayoutConstraint *trailing =[NSLayoutConstraint
constraintWithItem:subView
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:parent
attribute:NSLayoutAttributeTrailing
multiplier:1.0f
constant:0.f];

//Leading

NSLayoutConstraint *leading = [NSLayoutConstraint
constraintWithItem:subView
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:parent
attribute:NSLayoutAttributeLeading
multiplier:1.0f
constant:0.f];

//Bottom
NSLayoutConstraint *bottom =[NSLayoutConstraint
constraintWithItem:subView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:parent
attribute:NSLayoutAttributeBottom
multiplier:1.0f
constant:0.f];

//Height to be fixed for SubView same as AdHeight
NSLayoutConstraint *height = [NSLayoutConstraint
constraintWithItem:subView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:0
constant:ADHeight];

//Add constraints to the Parent
[parent addConstraint:trailing];
[parent addConstraint:bottom];
[parent addConstraint:leading];

//Add height constraint to the subview, as subview owns it.
[subView addConstraint:height];

Hope this helps.

Cheers.

Trailing and Leading constraints in Swift programmatically (NSLayoutConstraints)

You need to use the leading and trailing attributes, not the leadingMargin and trailingMargin attributes:

override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
...
...
view!.addSubview(gamePreview)
gamePreview.translatesAutoresizingMaskIntoConstraints = false

view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .Trailing, relatedBy: .Equal, toItem: view, attribute: .Trailing, multiplier: 1, constant: 0))
view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .Leading, relatedBy: .Equal, toItem: view, attribute: .Leading, multiplier: 1, constant: 0))

view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .Top, relatedBy: .Equal, toItem: self.topLayoutGuide, attribute: .Bottom, multiplier: 1, constant: 0))
view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute,multiplier: 1, constant: 131))
}

How do I use Safe Area Layout programmatically?

Here is sample code (Ref from: Safe Area Layout Guide):

If you create your constraints in code use the safeAreaLayoutGuide property of UIView to get the relevant layout anchors. Let’s recreate the above Interface Builder example in code to see how it looks:

Assuming we have the green view as a property in our view controller:

private let greenView = UIView()

We might have a function to set up the views and constraints called from viewDidLoad:

private func setupView() {
greenView.translatesAutoresizingMaskIntoConstraints = false
greenView.backgroundColor = .green
view.addSubview(greenView)
}

Create the leading and trailing margin constraints as always using the layoutMarginsGuide of the root view:

 let margins = view.layoutMarginsGuide
NSLayoutConstraint.activate([
greenView.leadingAnchor.constraint(equalTo: margins.leadingAnchor),
greenView.trailingAnchor.constraint(equalTo: margins.trailingAnchor)
])

Now, unless you are targeting iOS 11 and later, you will need to wrap the safe area layout guide constraints with #available and fall back to top and bottom layout guides for earlier iOS versions:

if #available(iOS 11, *) {
let guide = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
greenView.topAnchor.constraintEqualToSystemSpacingBelow(guide.topAnchor, multiplier: 1.0),
guide.bottomAnchor.constraintEqualToSystemSpacingBelow(greenView.bottomAnchor, multiplier: 1.0)
])
} else {
let standardSpacing: CGFloat = 8.0
NSLayoutConstraint.activate([
greenView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor, constant: standardSpacing),
bottomLayoutGuide.topAnchor.constraint(equalTo: greenView.bottomAnchor, constant: standardSpacing)
])
}

Result:

Sample Image

Sample Image



Here is Apple Developer Official Documentation for Safe Area Layout Guide


Safe Area is required to handle user interface design for iPhone-X. Here is basic guideline for How to design user interface for iPhone-X using Safe Area Layout



Related Topics



Leave a reply



Submit