When Should Translatesautoresizingmaskintoconstraints Be Set to True

When should translatesAutoresizingMaskIntoConstraints be set to true?

translatesAutoresizingMaskIntoConstraints needs to be set to false when:

  1. You Create a UIView-based object in code (Storyboard/NIB will set it for you if the file has autolayout enabled),
  2. And you want to use auto layout for this view rather than frame-based layout,
  3. And the view will be added to a view hierarchy that is using auto layout.

In this case not all of these are true. Specifically, point 2.

After you return the header view from viewForHeaderInSection it is added to the table view and its frame is set based on the current width of the table view and the height you return from heightForHeaderInSection.

You can add subviews to the root header view (header in your code) and use constraints to layout those subviews relative to the header view.

You have discovered the reason why you can't use autolayout for the header view itself in your comments; at the time you create the view it isn't yet part of the view hierarchy and so you cannot constrain its edges to anything.

In order to have dynamic header sizing, you will need to add subviews to your header view and add constraints between those subviews and header. Then, auto layout can use the intrinsic content size of header to determine the header view size.

Since you are not constraining the frame of header, do not set translatesAutoresizingMaskIntoConstraints to false. You will need to ensure that you have sufficient constraints on your subviews for auto layout to determine the size of header.

You will need a continuous line of constraints from top to bottom and potentially some height constraints for your subviews if the intrinsic content size of that subview is not sufficient.

Any subviews you add to header do need translatesAutoresizingMaskIntoConstraints set to false

You also need to return something from estimatedHeightForHeaderInSection - the closer to your actual header height the better - if you are using tableview.sectionHeaderHeight = UITableViewAutomaticDimension

Do you have to set translatesAutoresizingMaskIntoConstraints to false for a ViewController's 'main' view?

First you should never set .translatesAutoresizingMaskIntoConstraints = false on the main view of a view controller (unless you load the controller as a child, but that's not what you're talking about in your question).

You need to read-up on view / view-controller life-cycle.

In viewDidLoad(), auto-layout HAS NOT yet run to do its management of the view and subview(s) layout.

In viewDidLayoutSubview(), auto-layout HAS run, but depending on how dynamic your design is (among other factors) this may be called more than once.

In viewDidAppear(), all the layout has been completed (unless your code is running an async process to animated views, add additional views, whatever).

So, try running this simple example - it will print the name of the currently executing function along with the output from .hasAmbiguousLayout:

class TestLayoutViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

var view1 = UIView()
view1.backgroundColor = .red
view.addSubview(view1)
view1.translatesAutoresizingMaskIntoConstraints = false

NSLayoutConstraint.activate([
view1.topAnchor.constraint(equalTo: view.topAnchor, constant: 20),
view1.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
view1.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
view1.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -20)
])

print() // blank line
print(#function)
print() // blank line
print("In viewDidLoad(), does subview have ambigous layout?")
print(view1.hasAmbiguousLayout)

}

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()

guard let v = view.subviews.first else {
return
}

print() // blank line
print(#function)
print() // blank line
print("In viewDidLayoutSubviews(), does subview have ambigous layout?")
print(v.hasAmbiguousLayout)

}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)

guard let v = view.subviews.first else {
return
}

print() // blank line
print(#function)
print() // blank line
print("In viewDidAppear(), does subview have ambigous layout?")
print(v.hasAmbiguousLayout)

}

}

This is what you should see in the debug console:

viewDidLoad()

In viewDidLoad(), does subview have ambigous layout?
2021-02-14 08:41:46.694337-0500 PanZoom[43869:6978294] [LayoutConstraints] View has an ambiguous layout. See "Auto Layout Guide: Ambiguous Layouts" for help debugging. Displaying synopsis from invoking -[UIView _autolayoutTrace] to provide additional detail.

*UIView:0x7fd472604960- AMBIGUOUS LAYOUT for UIView:0x7fd472604960.Width{id: 90}, UIView:0x7fd472604960.Height{id: 93}

Legend:
* - is laid out with auto layout
+ - is laid out manually, but is represented in the layout engine because translatesAutoresizingMaskIntoConstraints = YES
• - layout engine host
true

viewDidLayoutSubviews()

In viewDidLayoutSubviews(), does subview have ambigous layout?
false

viewDidAppear(_:)

In viewDidAppear(), does subview have ambigous layout?
false

As you can see, during viewDidLoad() we get auto-layout ambiguities, but NOT in viewDidLayoutSubviews() or in viewDidAppear().

Why Constrains Break when I just set translatesAutoresizingMaskIntoConstraints to true, ChangeSizesInRunTime?

translatesAutoresizingMaskIntoConstraints = true
It tells auto-layout to translate the frame setting and the .autoresizingMask property into constraints.
Why this warning poped to you?
Because this line converts the frame layout to constrains, and in this case, the compiler removed already all your old constraints and started to convert the frame to constrain it to find only the height constrain
it's still need to have two constraints for X, Y to dismiss the warning
You still must provide valid frames to avoid conflicting/broken constraint warnings.

How does translatesAutoresizingMaskIntoConstraints actually work?

You are correct that the autoresizingMask is interpreted (along with the frame) to determine which constraints to create.

In the example you give the system would create the following constraints -

  • Width constraint of 50
  • Height constraint of 50
  • Leading, trailing and top constraints to the nearest neighbours, with the fixed distance to those neighbours
  • Greater than or equal bottom constraint to the nearest neighbour with the distance to that neighbour.

This would result in a 50x50 view that was fixed horizontally and at the top and where the space between the bottom and its neighbour can grow as required.

Do I need to set translatesAutoresizingMaskIntoConstraints = false if I change the storyboard cell size in code? If, so, where?

The answers to my questions:

  1. Do I have to set translatesAutoresizingMaskIntoConstraits = false? Yes.
  2. Where do I do it? In the code for the custom CollectionViewCell.

Here's what I did.

  1. Delete the prototype cell from the storyboard and do everything in code.

  2. Set up the custom cell something like this:

class WWCollectionViewCell: UICollectionViewCell {

override init(frame: CGRect) {
super.init(frame: frame)
translatesAutoresizingMaskIntoConstraints = false
}

required init?(coder: NSCoder) {
fatalError("Init(coder) has not been implemented.")
}

}

  1. In the ViewController that manages the ContainerView, register the cell in viewDidLoad()
boardCollectionView.register(WWCollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)

Now my cells resize for different devices and always have a 6x6 grid, with cell sizes based on calculations made in the ViewController.

Can't set translatesAutoresizingMaskIntoConstraints

translatesAutoresizingMaskIntoConstraints is actually a method on UIView and not a property.

The syntax works because ObjC lets you use dot-notation for calling methods as well (there's a whole other discussion on how properties actually auto-generate getter/setter methods).

Use the method instead of trying to use the property notation from ObjC

view.setTranslatesAutoresizingMaskIntoConstraints(false) 


Related Topics



Leave a reply



Submit