oldergod oldergod - 5 months ago 18
Swift Question

Center UIView without overlapping neighbors views of different size?

What I wish to achieve, the three of them are UILabels:

enter image description here

Spec:


  1. left
    and
    right
    are edged UIViews.

  2. middle
    is centered, even though side views are not the same size.

  3. On collision between
    middle
    and
    left
    or
    middle
    and
    right
    , the text in
    middle
    gets tail truncated while
    left
    and
    right
    do not change.



Problem:

I cannot have meet both requirements (2) and (3) at the same time.


  • (2) is achieved with
    middle.autoAlignAxisToSuperviewAxis(.Vertical)



    • problem: no truncate, it just overlaps
      leftLabel
      and
      rightLabel
      .


  • (3) is achieved with
    middle.autoPinEdge(.Left, toEdge: .Right, ofView: leftLabel)
    and same strategy for the
    rightLabel
    .


    • problem:
      middle
      is centered in the area between
      leftLabel
      and
      rightLabel
      , if the last two do not have the same size,
      middle
      is not superview centered anymore.




Both applied create a constraint conflict and I don't know how to fix it, hence my question:

How can I center a UILabel and truncate it to avoir overlaps with side views of different sizes?

Answer

All you need is adding two constraints, one is horizontal spacing between middle and left, set the relation to 'Greater than or Equal', and constant for example 10; another is horizontal spacing between middle and right, the same configuration like constraint one.

When the text of middle label is too long, the constraints below will prevent middle from overlapping with label left and right.

Add sample code:
I suppose you had set the constraints to UILabel left and right in storyboard or in code. The sample below is used to configu UILabel middle

func setupConstraint() {
    self.middle = UILabel()
    self.middle!.backgroundColor = UIColor.yellowColor()
    self.view.addSubview(self.middle!)
    self.middle!.numberOfLines = 0
    self.middle!.translatesAutoresizingMaskIntoConstraints = false
    let middle = self.middle!
    var constraint = NSLayoutConstraint(item: middle, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: left, attribute: NSLayoutAttribute.Top, multiplier: 1, constant: 0)

    self.view.addConstraint(constraint)

    constraint = NSLayoutConstraint(item: middle, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.GreaterThanOrEqual, toItem: left, attribute: NSLayoutAttribute.Right, multiplier: 1, constant: 10)

    self.view.addConstraint(constraint)

    constraint = NSLayoutConstraint(item: right, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.GreaterThanOrEqual, toItem: middle, attribute: NSLayoutAttribute.Right, multiplier: 1, constant: 10)
    constraint.priority = 1000

    self.view.addConstraint(constraint)

    constraint = NSLayoutConstraint(item: middle, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0)

    self.view.addConstraint(constraint)

    constraint = NSLayoutConstraint(item: middle, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.GreaterThanOrEqual, toItem: middle, attribute: NSLayoutAttribute.Height, multiplier: 1, constant: 100)

    self.view.addConstraint(constraint)

    self.middle!.text = "self.middle.translatesAutoresizingMaskIntoConstraints = false"
}



Sanpshot
enter image description here

Comments