1

target

This is what I'm trying to achieve. Inside of a UITableView Cell, I have a UIlabel populated with dynamic content and a separate UIView that has a set height. In some cases the when there is a lot of text, the UIlabel determines the height of the UITableView Cell. In other cases when there is only one line of text populating the UILabel, the UIView sets the height of the cell. (This is what I currently have.)

    self.myLabel.setTranslatesAutoresizingMaskIntoConstraints(false)
    self.myView.setTranslatesAutoresizingMaskIntoConstraints(false)


    let viewsDictionary = [
        "myLabel":myLabel,
        "myView":myView,
    ]


    let myLabel_H:Array = NSLayoutConstraint.constraintsWithVisualFormat("H:|-15-[myLabel]-60-|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDictionary)
    let myLabel_V:Array = NSLayoutConstraint.constraintsWithVisualFormat("V:|-[myLabel]-|", options:NSLayoutFormatOptions(0), metrics: nil, views: viewsDictionary)

    self.contentView.addConstraints(myLabel_H)
    self.contentView.addConstraints(myLabel_V)


    let myView_H:Array = NSLayoutConstraint.constraintsWithVisualFormat("H:[myView(50)]-|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDictionary)
    let myView_V:Array = NSLayoutConstraint.constraintsWithVisualFormat("V:|-(>=10)-[myView(100)]-(>=10)-|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDictionary)

    self.contentView.addConstraints(myView_H)
    self.contentView.addConstraints(myView_V)

Instead I get this: (And I'm throwing errors: =10)-| (Names: '|':UITableViewCellContentView:0x7fc21bc6d050 )>)

current

DeliciousMe
  • 71
  • 10

2 Answers2

2

You need to use the non visual auto layout format.

In ObjC it would look something like this:

[self.viewOuterView addConstraint:[NSlayoutConstraint constraintWithItem:self.innerView attribute:NSLayoutAttributeCenterY relateBy:NSLayoutRelationEqual toItem:self.outerView attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];
Chris
  • 7,830
  • 6
  • 38
  • 72
  • great will try this out. Is this is in conjunction with VFL or are you saying there is no VFL way to do this? – DeliciousMe Apr 09 '15 at 15:21
  • This works in conjunction with what I've got. Except I am still throwing an error: 2015-04-09 09:43:06.403 tables[87834:4701607] Unable to simultaneously satisfy constraints. Will attempt to recover by breaking constraint =10)-| (Names: '|':UITableViewCellContentView:0x7f8ee8e37ee0 )> – DeliciousMe Apr 09 '15 at 16:42
  • That is because you now have two 'vertical' constraints on the same view, which auto layout won't accept. Try removing the constraint it complains about, and see what happens – Chris Apr 09 '15 at 20:16
  • removing one of the problematic constraint causes the cell to collapse because the cell bottom is not longer pushed out by the UIView. – DeliciousMe Apr 10 '15 at 04:05
0

You can align your two subviews using the alignment values in the options parameter of the visual layout method (.AlignAllCenterY), so you don't need to add a separate constraint for the image view to center it in the y direction. Also, it would be better to make the horizontal constraints go from the left edge to the label to the image view to the right edge, instead of pinning the label to both edges of the superview.

class RDTableViewCell: UITableViewCell {

    var myLabel = UILabel()
    var myView = UIImageView()

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        myLabel.numberOfLines = 0
        myLabel.setTranslatesAutoresizingMaskIntoConstraints(false)
        myView.setTranslatesAutoresizingMaskIntoConstraints(false)

        contentView.addSubview(myLabel)
        contentView.addSubview(myView)

        let viewsDictionary = ["myLabel":myLabel, "myView":myView]

        let horizontalCons = NSLayoutConstraint.constraintsWithVisualFormat("H:|-15-[myLabel]-[myView(50)]-|", options: .AlignAllCenterY, metrics: nil, views: viewsDictionary)
        let myLabel_V = NSLayoutConstraint.constraintsWithVisualFormat("V:|-[myLabel]-|", options:NSLayoutFormatOptions(0), metrics: nil, views: viewsDictionary)
        let myView_V = NSLayoutConstraint.constraintsWithVisualFormat("V:|-(>=10)-[myView(100)]-(>=10)-|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDictionary)

        contentView.addConstraints(horizontalCons)
        contentView.addConstraints(myLabel_V)
        contentView.addConstraints(myView_V)
    }
}
rdelmar
  • 103,982
  • 12
  • 207
  • 218
  • masterful. Are you getting any warnings thrown? About breaking constraints? I'm still getting a message that a constraint needs to be broken. In particular, I think it's "V:|-(>=10)-[myView(100)]-(>=10)-|" – DeliciousMe Apr 09 '15 at 16:47
  • Does the hugging priority of the label need to be lowered? – Brian Nickel Apr 09 '15 at 16:54
  • @DeliciousMe No, I'm not getting any warnings. Are you setting the contentMode property of the image view to something other than the default, UIViewContentModeScaleToFill? Are you adding the subviews in code like I do (no xib or storyboard)? Also, are you setting the estimatedRowHeight and setting the row height to UITableViewAutomaticDimension? – rdelmar Apr 09 '15 at 18:53
  • Yep. I didn't touch the contentMode property, and I'm adding all the subview in code without xibs or storyboards. And I also am setting estimatedRowHeight and rowHeight to UITableViewAutomaticDimension. The only difference is that I wrapped this all up in a layout function which I am calling from the override init method. Note, that everything looks right, it's just throwing errors. – DeliciousMe Apr 10 '15 at 04:01
  • @DeliciousMe Hard to say what the problem is if you're saying you basically have the same thing I posted, but yours throws errors and mine doesn't. – rdelmar Apr 10 '15 at 06:34