1

I have two labels in my UITableViewCell and the constraints are set up so they are centered in the cell:

func setConsraints() {

    // horizontal constraints

    // vertical constraints
    mainLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor, constant: someVariable).isActive = true
    infoLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor, constant: -someVariable).isActive = true
}

normal (desired result)


But because the constant is a variable, sometimes it looks like:

overlapping (unwanted result)


I tried adding a constraint between mainLabel and infoLabel and played around with the priority but none of these solutions was working.

Question:

How can I add a "minimum" constraint to these two labels so they won't overlap each other but at the same time centering it to the UITableViewCell, maintaining a certain distance?

Rakesha Shastri
  • 11,053
  • 3
  • 37
  • 50
Henny Lee
  • 2,970
  • 3
  • 20
  • 37
  • increase value of someVariable?. Don't let it be less than a certain value? – Andrey Chernukha Aug 22 '18 at 10:51
  • @Larme Why would you recommend a stackView for just 2 views? It adds another view to the heirarchy. It would be useful if a lot of views following a pattern is involved? – Rakesha Shastri Aug 22 '18 at 10:53
  • Why not use bottom anchor of the first and top anchor of the second when setting relative to the center of contentView? Otherwise you'd need to calculate label height and set the spacing greater than labelheight/2 to get any amount of spacing. – Rakesha Shastri Aug 22 '18 at 10:56
  • Is there a particular reason why you need to offset both labels from the vertical center? Why not have the `MainText` centered and add a `bottom` constraint to the `InfoText`? – Sylvan D Ash Aug 22 '18 at 10:59
  • @RakeshaShastri I don't know how to do: "setting relative to the center". Do you mind showing it to me in an answer? SylvanDAsh: Then both label's wouldn't be centered within the cell anymore no? – Henny Lee Aug 22 '18 at 11:02
  • @SylvanDAsh because he wants both of them equidistant from the center of the view. For symmetry maybe? – Rakesha Shastri Aug 22 '18 at 11:06

2 Answers2

3

What about putting them inside of a vertical UIStackView with the spacing you require and then center the stackview instead of the labels. This way you only have to manage the constraints of 1 view instead of 2.

Kind of like this: stackview setup

bitwit
  • 2,589
  • 2
  • 28
  • 33
  • I think stack view for just 2 views is not optimal because it adds another view to the heirarchy for a simple layout which wouldn't require much effort to layout without stackview. Someone else had actually posted it as a comment and i had responded to that. – Rakesha Shastri Aug 22 '18 at 11:29
  • 1
    Personally I love the UIStackview and use it liberally. I nest them inside of each other all the time too. It saves a lot of autolayout headaches. If your layout changes in the future you are more ready to adapt too.To each their own but I think it's worth the extra UIView. – bitwit Aug 22 '18 at 11:32
  • I understand that because i did the exact same thing when i was developing my sample app. When i showed it to my lead, he said use it only when there is scope for layout changes in the future. Not just because 2 views need to be spaced equally or something. He said that the extra view overhead is unnecessary, although a stack view here and there won't cause much damage. It is not good practice. – Rakesha Shastri Aug 22 '18 at 11:35
  • @RakeshaShastri Unless you profile and see that extra views in your heirarchy is actually a problem i think that's premature optimization. I'm happy with my practice. – bitwit Aug 22 '18 at 11:36
  • 1
    By problem i meant memory problem and it won't be a problem for most devices if you use one here and there, but when a lot are involved in an already heavy view, maybe? Like you said - To each his own. _peace_ :) – Rakesha Shastri Aug 22 '18 at 11:37
  • Thanks! One thing I see that Apple always says in the WWDC videos is to profile everything. So I try not to worry too much about these things unless the profilers say it is a problem. I usually find the real issues lie in much greater architectural design issues than the # of views in the heirarchy unless it is absurdly heavy like you suggest. My designers frequently change minds or want me to move things though and I find that UIStackView leaves me prepared for change. All the best w your app dev! – bitwit Aug 22 '18 at 11:42
1

Did you consider this alternative?

func setConsraints() {

    // horizontal constraints

    // vertical constraints
    mainLabel.bottomAnchor.constraint(equalTo: contentView.centerYAnchor, constant: -someVariable).isActive = true
    infoLabel.topAnchor.constraint(equalTo: contentView.centerYAnchor, constant: someVariable).isActive = true
}

Otherwise you need to get the height of the string and set the center anchor relative to that. There are string extensions which allow you to get the height of a string for a particular width like this answer. You can use that to get the height of the label and add half of that to someVariable in your approach.


Edit: I noticed that you have set a positive constant value for the mainLabel and negative for the infoLabel. If you want your mainLabel to be above the center then you need to add negative value to the mainLabel and the opposite for infoLabel.

Rakesha Shastri
  • 11,053
  • 3
  • 37
  • 50
  • Thanks, I've already tried this though. Problem is my cell has a dynamic height as well which is why I resorted to centering it to the cell instead. As for your edit, that was my mistake. I typed the code right in SO without thinking :p. – Henny Lee Aug 22 '18 at 11:16
  • @HennyLee My answer still has it centered to the cell, but in a different way. Notice that they are relative to the center of the contentView which is exactly what you are trying to achieve. You could have tried the code and checked it with dynamic height. – Rakesha Shastri Aug 22 '18 at 11:18
  • 1
    My bad, I didn't read your answer correctly. Working fine now. Thanks! – Henny Lee Aug 22 '18 at 11:28