Programatic Constraints Not Obeyed

Programatic Constraints Not Obeyed

make sure you have translatesAutoresizingMaskIntoConstraints set to false.

Also after iOS 9 there is an easier way of writing your constraints.

Add a single constraint without any constant:

self.bandAccountView!.formVw.addConstraint(formVw.topAnchor.constraint(equalTo:
bandCardView.topAnchor)

Add a single constraint with a constant:

self.bandAccountView!.formVw.addConstraint(formVw.topAnchor.constraint(equalTo: 
bandCardView.topAnchor, constant: 10)

Add multiple constraints:

self.bandAccountView!.formVw.addConstraints([formVw.topAnchor.constraint(equalTo:
bandCardView.topAnchor),formVw.bottomAnchor.constraint(equalTo:
bandCardView.bottomAnchor),formVw.leadingAnchor.constraint(equalTo:
bandCardView.leadingAnchor),formVw.trailingAnchor.constraint(equalTo:
bandCardView.trailingAnchor)]

NOTE:

if you ever wrote:

self.bandAccountView!.formVw.leadingAnchor.constraint(equalTo:
formVw.leadingAnchor, constant: 0)

then you have actually forgot to "add/activate the constraint". To fix it you either have to do:

self.bandAccountView!.formVw.leadingAnchor.constraint(equalTo:
formVw.leadingAnchor, constant: 0).isActive = true

OR

let leadingConstraint = self.bandAccountView!.formVw.leadingAnchor.constraint(equalTo:
formVw.leadingAnchor, constant: 0)
leadingConstraint.isActive = true // do this whenever you need
leadingConstraint.isActive = false // if you don't need it...

or simply do like the first snippet


Additionally the relation between bandAccountView & formVw are instance--instance variable and they way you're doing it isn't good. It's much better to do the constraints in it's own class or create a custom init that would only adjust the constants for you.

UIView not obeying autolayout constraints in UIScrollView

UIScrollView automatically shrinks to fit the views inside it. You need to set the width absolutely somewhere.

Recommended tactic:

  1. Completely fixiate the scrollview inside its parent-view using constraints (leading, trailing, top, bottom).
  2. Create a UIView inside the UIScrollView and put everything you need inside it.
  3. Set the constraints so that the UIView will act as a content-view (this means it is big enough to include all elements). Use intrinsic content-size, shrink-resistance and chaining of elements with constraints a lot. The resulting layout must be well-defined and unique (this means if you were to remove all constraints to the outside, the layout would still work).
  4. Connect the bounds of the UIView with their superview (which is the actual content-view of the UIScrollView, NOT the UIScrollView!).

If you do this in interface-builder (it is possible), you need to re-check your constraints every time you touch something in that scene. And by touch I mean "select" not only "modify".

UISearchBar ignores programmatic constraints

I had a similar issue when adding UISearchController's searchBar to a UITableView header view.

When animating constraints of the containerView holding the UITableView after the user selected the searchBar, it would not follow the containerView.

In my case it would appear that after the delegate didPresentSearchController:(UISearchController *)searchController is called, the searchBar had a superview of UISearchBarContainerView instead of the UITableView header view.

Re-adding it back to the original header view before animation helped me.

-(void)didPresentSearchController:(UISearchController *)searchController {

NSLog(@"did present search controller");

self.tableView.tableHeaderView = self.searchController.searchBar;

...animation...

}

Auto layout Constraints on NSView Only Obeyed After Hitting Edge

Added

[tableColumn setWidth:self.view.superview.frame.size.width]

to

- (NSView *)tableView:(NSTableView *)tableView
viewForTableColumn:(NSTableColumn *)tableColumn
row:(NSInteger)row

constraints in prepareForInterfaceBuilder?

Make sure when adding a subview in prepareForInterfaceBuilder that you set its translatesAutoresizingMaskIntoConstraints property to false if you want to use constraints on it and have it show up properly in Interface Builder. Such as:

@IBDesignable class View: UIView {
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()

let subview = UIView()

// Make sure to set this to false!
subview.translatesAutoresizingMaskIntoConstraints = false

// Just setting the background color so it can be seen in IB.
subview.backgroundColor = .blue

// Must add it as a subview before activating any constraints.
addSubview(subview)

// Adding some example constraints with some padding to make sure they're behaving properly.
NSLayoutConstraint.activate(
[subview.topAnchor.constraint(equalTo: topAnchor, constant: 20),
subview.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20),
subview.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -20),
subview.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20)]
)
}
}

This is an easy mistake to make because Xcode (10.3 as of writing this answer) does not give you any feedback about what's happening with the layout engine during IBDesignable rendering (no console log messages, no errors in Interface Builder, and nothing in the Report Navigator).



Related Topics



Leave a reply



Submit