How to Create Layout Constraints Programmatically

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.

How to programmatically create layout and constraints using Swift IOS

There are three main steps. First you have to define the element, add it to the view, then add constraints.

For example,

let button = UIButton() 
button.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(button)

NSLayoutConstraint.activate([
button.heightAnchor.constraint(equalTo: view.heightAnchor)


])

Adding constraints programmatically

Here is an example of adding constraints programatically,

ConstraintLayout mConstraintLayout  = (ConstraintLayout)fndViewById(R.id.mainConstraint);
ConstraintSet set = new ConstraintSet();

ImageView view = new ImageView(this);
mConstraintLayout.addView(view,0);
set.clone(mConstraintLayout);
set.connect(view.getId(), ConstraintSet.TOP, mConstraintLayout.getId(), ConstraintSet.TOP, 60);
set.applyTo(mConstraintLayout);

To know more details you can refer Constraint layout

ConstraintLayout: change constraints programmatically

  1. To set constraints of image view to:

     app:layout_constraintRight_toRightOf="@+id/check_answer1"
    app:layout_constraintTop_toTopOf="@+id/check_answer1"

    use:

     ConstraintLayout constraintLayout = findViewById(R.id.parent_layout);
    ConstraintSet constraintSet = new ConstraintSet();
    constraintSet.clone(constraintLayout);
    constraintSet.connect(R.id.imageView,ConstraintSet.RIGHT,R.id.check_answer1,ConstraintSet.RIGHT,0);
    constraintSet.connect(R.id.imageView,ConstraintSet.TOP,R.id.check_answer1,ConstraintSet.TOP,0);
    constraintSet.applyTo(constraintLayout);
  2. To set constraints of image view to:

     app:layout_constraintRight_toRightOf="@+id/check_answer2"
    app:layout_constraintTop_toTopOf="@+id/check_answer2"

    use:

     ConstraintLayout constraintLayout = findViewById(R.id.parent_layout);
    ConstraintSet constraintSet = new ConstraintSet();
    constraintSet.clone(constraintLayout);
    constraintSet.connect(R.id.imageView,ConstraintSet.RIGHT,R.id.check_answer2,ConstraintSet.RIGHT,0);
    constraintSet.connect(R.id.imageView,ConstraintSet.TOP,R.id.check_answer2,ConstraintSet.TOP,0);
    constraintSet.applyTo(constraintLayout);

Creating layout constraints programmatically

When using Auto Layout in code, setting the frame does nothing. So the fact that you specified a width of 200 on the view above, doesn't mean anything when you set constraints on it. In order for a view's constraint set to be unambiguous, it needs four things: an x-position, a y-position, a width, and a height for any given state.

Currently in the code above, you only have two (height, relative to the superview, and y-position, relative to the superview). In addition to this, you have two required constraints that could conflict depending on how the view's superview's constraints are setup. If the superview were to have a required constraint that specifies it's height be some value less than 748, you will get an "unsatisfiable constraints" exception.

The fact that you've set the width of the view before setting constraints means nothing. It will not even take the old frame into account and will calculate a new frame based on all of the constraints that it has specified for those views. When dealing with autolayout in code, I typically just create a new view using initWithFrame:CGRectZero or simply init.

To create the constraint set required for the layout you verbally described in your question, you would need to add some horizontal constraints to bound the width and x-position in order to give a fully-specified layout:

[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:|-[myView(>=748)]-|"
options:NSLayoutFormatDirectionLeadingToTrailing
metrics:nil
views:NSDictionaryOfVariableBindings(myView)]];

[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"H:[myView(==200)]-|"
options:NSLayoutFormatDirectionLeadingToTrailing
metrics:nil
views:NSDictionaryOfVariableBindings(myView)]];

Verbally describing this layout reads as follows starting with the vertical constraint:

myView will fill its superview's height with a top and bottom padding
equal to the standard space. myView's superview has a minimum height
of 748pts. myView's width is 200pts and has a right padding equal to
the standard space against its superview.

If you would simply like the view to fill the entire superview's height without constraining the superview's height, then you would just omit the (>=748) parameter in the visual format text. If you think that the (>=748) parameter is required to give it a height - you don't in this instance: pinning the view to the superview's edges using the bar (|) or bar with space (|-, -|) syntax, you are giving your view a y-position (pinning the view on a single-edge), and a y-position with height (pinning the view on both edges), thus satisfying your constraint set for the view.

In regards to your second question:

Using NSDictionaryOfVariableBindings(self.myView) (if you had an property setup for myView) and feeding that into your VFL to use self.myView in your VFL text, you will probably get an exception when autolayout tries to parse your VFL text. It has to do with the dot notation in dictionary keys and the system trying to use valueForKeyPath:. See here for a similar question and answer.

How to programmatically add views and constraints to a ConstraintLayout?

I think you should clone the layout after adding your ImageView.

ConstraintLayout layout = (ConstraintLayout)findViewById(R.id.mainConstraint);
ConstraintSet set = new ConstraintSet();

ImageView view = new ImageView(this);
view.setId(View.generateViewId()); // cannot set id after add
layout.addView(view,0);
set.clone(layout);
set.connect(view.getId(), ConstraintSet.TOP, layout.getId(), ConstraintSet.TOP, 60);
set.applyTo(layout);```

swift how to set autolayout programmatically

There are various ways to do this. One approach:

  • declare two "constraint" arrays

    • one to hold the "narrow view" constraints
    • one to hold the "wide view" constraints
  • activate / deactivate the constraints as needed

Here is a complete example:

class ChangeLayoutViewController: UIViewController {

let redButton: UIButton = {
let v = UIButton()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .red
v.setTitle("Red Button", for: [])
return v
}()

let blueButton: UIButton = {
let v = UIButton()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .blue
v.setTitle("Blue Button", for: [])
return v
}()

var narrowConstraints: [NSLayoutConstraint] = [NSLayoutConstraint]()
var wideConstraints: [NSLayoutConstraint] = [NSLayoutConstraint]()

override func viewDidLoad() {
super.viewDidLoad()

view.addSubview(redButton)
view.addSubview(blueButton)

let g = view.safeAreaLayoutGuide

var c: NSLayoutConstraint

// MARK: - narrow orientation

// constrain redButton above blueButton

// constrain redButton leading and trailing to safe-area (with 8-pts on each side)
c = redButton.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 8.0)
narrowConstraints.append(c)
c = redButton.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -8.0)
narrowConstraints.append(c)

// constrain blueButton leading and trailing to safe-area (with 8-pts on each side)
c = blueButton.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 8.0)
narrowConstraints.append(c)
c = blueButton.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -8.0)
narrowConstraints.append(c)

// constrain redButton top 40-pts from safe-area top
c = redButton.topAnchor.constraint(equalTo: g.topAnchor, constant: 40.0)
narrowConstraints.append(c)
// constrain blueButton top 20-pts from redButton bottom
c = blueButton.topAnchor.constraint(equalTo: redButton.bottomAnchor, constant: 20.0)
narrowConstraints.append(c)


// MARK: - wide orientation

// constrain redButton & blueButton side-by-side
// with equal widths and 8-pts between them

// constrain redButton leading 8-pts from safe-area leading
c = redButton.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 8.0)
wideConstraints.append(c)
// constrain blueButton trailing 8-pts from safe-area trailing
c = blueButton.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -8.0)
wideConstraints.append(c)

// constrain blueButton leading 8-pts from redButton trailing
c = blueButton.leadingAnchor.constraint(equalTo: redButton.trailingAnchor, constant: 8.0)
wideConstraints.append(c)

// constrain buttons to equal widths
c = blueButton.widthAnchor.constraint(equalTo: redButton.widthAnchor)
wideConstraints.append(c)

// constrain both buttons centerY to safe-area centerY
c = redButton.centerYAnchor.constraint(equalTo: g.centerYAnchor)
wideConstraints.append(c)
c = blueButton.centerYAnchor.constraint(equalTo: g.centerYAnchor)
wideConstraints.append(c)

// activate initial constraints based on view width:height ratio
changeConstraints(view.frame.width > view.frame.height)

}

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
// change active set of constraints based on view width:height ratio
self.changeConstraints(size.width > size.height)
}

func changeConstraints(_ useWide: Bool) -> Void {
if useWide {
NSLayoutConstraint.deactivate(narrowConstraints)
NSLayoutConstraint.activate(wideConstraints)
} else {
NSLayoutConstraint.deactivate(wideConstraints)
NSLayoutConstraint.activate(narrowConstraints)
}
}

}

Results:

Sample Image

Sample Image



Related Topics



Leave a reply



Submit