简体   繁体   中英

Add trailing constraint between two views

I got stuck with a weird behaviour

I added programmatically a trailing constraint between 'UISlider' and 'UILabel', it looks like this:

NSLayoutConstraint *timeLabelTrailing = [NSLayoutConstraint
                                             constraintWithItem:_timeLbl
                                             attribute:NSLayoutAttributeTrailing
                                             relatedBy:NSLayoutRelationEqual
                                             toItem:_seekBar
                                             attribute:NSLayoutAttributeTrailing
                                             multiplier:1
                                             constant:0];

    [timeLabelTrailing setActive:true];
    [self layoutIfNeeded];

And the 'UILabel' trailing wont match the 'UISlider' trailing.

I tried to do the same between the 'UILabel' and the 'UIViewControoler' view and it works just fine, but with the 'UISlider' it goes wrong.

Attached some photos from ViewDebugger:

slider

照片一

label

照片二

It's because you've placed these in a stackview! Hence the stackview is suppressing other contraints.

How do I know it's getting suppressed?

The viewdebugger is an extremely powerful tool, yet most of its features are unknown.

The color of the constraints on the right side convey meaning.

  • The dark black constraints are having an affect.
  • The light gray constraints are ignored either due to being suppressed by a higher priority or conflicts among constraints meaning the Layout engine would decide on its own. The behavior of this decision is unpredictable.

FWIW both the gray & black colored constraints are active , yet not every active constraint gets applied . eg you could have hundred constraints on the width of a label, each with a different priority. While all of them are active, they would get ignored except for the constraint with highest priority.

在此处输入图片说明

As you can see ☝️the label.trailing = self.trailing @1000 is getting ignored. And when you have a priority with '1000' ignored then I'm pretty much sure that debugger is dumping warnings to you, but you didn't mention them in your question.

Long story short when you place things inside a stackview, then you shouldn't be adding much constraints yourself.

  • 'position' related constraints should be heavily avoided.
  • 'size' related constraints are slightly acceptable.

I think what you possibly need is

stackView.alignment = .trailing

And make sure you remove the other trailing constraints.

And if you want your slider to stretch to the full width of the stackview then constrain it to the stackview's width. The label is getting its width from its intrinsicContentSize and that's fine.

在此处输入图片说明

TBH I'm not sure if this is the best approach but I think it works. If anyone knows of a better way then please leave a comment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM