Why are my equally-constrained UIViews not rendered with the same size?

Howdy!

I have a view which is constrained to a height of 0.5 and is reused in several places. When several are rendered near each other however, it becomes clear that their heights are subtly different (but enough to annoy me!). It doesn't appear as if any constraints are breaking.

For additional information, I am trying to roughly replecate the appearance of the UITableView seperator in some of my views. Hints on how UIKit manages to ensure that a UITableView's seperators all appear to be the same height will also be appreciated.

Thanks,

smkuehnhold

Answered by Claude31 in 725345022

That’s seems likely. I’ve noticed that defining constraints in stackviews often create issues.

Could you show both code and the rendering which causes problem ?

.

It doesn't appear as if any constraints are breaking.

Please show constraints you may have defined on the views.

Are you making sure that the position of your view is aligned with pixels on the screen? In other words: are you rounding x and y position to screen scale?

In my effort to reproduce an example, I think have figured out what was breaking.

I had overconstrained the height of a stackview with .fillEqually s.t. it was marginally taller than the combined height of its arranged subviews (off by 0.5 pt)

It seems UIKit was making up for that difference by stretching one of my seperator views (a descendant of an arranged subview). This is weird because they are constrained to a height of 0.5 with required priority.

If this is what is happening, is this a bug? Or is .fillEqually best-effort to some extent?

Thanks, smkuehnhold

Accepted Answer

That’s seems likely. I’ve noticed that defining constraints in stackviews often create issues.

Also please be aware that a height of 0.5pt will render blurry on 3x devices. If the goal is to have a 1px line, you need to take the screen's scale into account (and update that accordingly if it changes e.g. because a view moved to a different screen).

That's basically what I am trying to do.

Is this a valid way to acheive that?

override func willMove(toWindow newWindow: UIWindow?) {
    if let newWindow = newWindow {
       let pts = 1 / newWindow.screen.nativeScale // px / scalingFactor = pts
       heightConstraint.constant = pts // constrain height to 1 px
    }
}
Why are my equally-constrained UIViews not rendered with the same size?
 
 
Q