A. Vin
A. Vin

Reputation: 885

Why does Autolayout not produce consistent results?

Either I'm out of my mind, or AutoLayout is straight broken. Can someone please explain this to me. I have a TableViewCell in a TableView that spans the width of the ViewController. I put 4 Labels inside my TableViewCell. I created constraints using AutoLayout such that each label is 25% the width of the TableViewCell. And yet, the 4 labels are CLEARLY different widths and they don't even add up to 100% of the width of the entire cell. Here's the screenshot. (Horizontal position of each of the labels is ambiguous, yes, but that shouldn't make a difference). Why are they not the same width? And why does 25% + 25% + 25% + 25% not add up to 100%? Running XCode 7.2 and targeting iOS 9.

enter image description here

enter image description here

Upvotes: 1

Views: 218

Answers (4)

Dhruv Khatri
Dhruv Khatri

Reputation: 813

For autolayout constraints it requires to give for constraint to particular object x,y position and hight , width If you are not giving any one of this it shows error to you. So make sure to give all the require constraints to your object.

Other option is uistackview for the ios 9 and later. Here is a link for you to learn about stackview https://m.youtube.com/watch?v=XqVWyA5PLwk

Upvotes: 0

rob mayoff
rob mayoff

Reputation: 386018

Daniel Hall's answer has useful information, but doesn't tell you specifically why you're seeing what you're seeing, so I will.

Xcode doesn't always enforce your constraints in the storyboard editor until you ask it to. In this case, you can select the table view cell's content view and from the menu bar choose Editor > Resolve Auto Layout Issues > All Views in BBRowTableViewCell > Update Frames. (Sometimes it takes two or three tries for Xcode to get everything right.)

However, you probably won't like the result. Because you haven't constrained the horizontal positions of the labels, Xcode will probably pile them all up at the left edge of the cell, or maybe somewhere outside the bounds of the cell where you can't even see them.

If your deployment target is iOS 9 or later, the easiest solution (as Daniel Hall said) is to put the labels in a UIStackView set to “Fill Equally”, and constrain the stack view's edges to the cell content view's edges.

If your deployment target is earlier than iOS 9, then you should create the constraints described by user3802077.

Upvotes: 2

Daniel Hall
Daniel Hall

Reputation: 13689

Error Symbol

This red error symbol is Interface Builder telling you that it cannot solve your constraints. In this case, as you have said, it's likely because you have not provided x position constraints for the labels.

Auto layout can either solve all constraints and get a right layout, or it can't and the result will be undefined. Remember that auto layout is an algebra-based process that solves for unknown values by using known values that you provide in constraints. If you don't provide sufficient and unambiguous known values, the equations for the remaining values simply cannot be solved and there can be no expectation of a correct result. The solution is to create enough constraints to make the layout solvable.

As a note, as of iOS 9 I would suggest using a UIStackView to hold those labels. UIStackView exists precisely to take the pain out of setting up manual constraints for these types of scenarios. If you used a horizontal stack view in the cell, you would constrain its edges to the cell's edges, drag the 4 labels into it and set it to "Fill Equally". And that's all you would need!

Upvotes: 3

user3802077
user3802077

Reputation: 849

This is not the only way, but here is how I usually do it.

As you did for the top and bottom for each labels, then:

  • Leading of label1 to leading of superview
  • Trailing of label4 to trailing of superview

Then a constraint for each neighbouring label:

  • label1.trailing to label2.leading,
  • ...

Then put an equal width constraint from each labels to label1:

  • label2 to label1
  • label3 to label1
  • label4 to label1

This should be it. No need of specifying 25%.

Upvotes: 0

Related Questions