0

So in my tableViewCell I have a imageView which has 0 points constraint to the trailing and leading superview. Top constraints of 8 and Bottom constraint of 30 to the superview. And then I add aspect constraint of the imageView according to the image with this code:

override var image: UIImage? {
        didSet {
            if let image = image {
                let aspect = image.size.width / image.size.height
                aspectConstraint = NSLayoutConstraint(item: self,
                                                      attribute: NSLayoutAttribute.width,
                                                      relatedBy: NSLayoutRelation.equal,
                                                      toItem: self,
                                                      attribute: NSLayoutAttribute.height,
                                                      multiplier: aspect,
                                                      constant: 0.0)
            }
        }
    }

    internal var aspectConstraint : NSLayoutConstraint? {
        didSet {
            if oldValue != nil {
                self.removeConstraint(oldValue!)
            }
            if aspectConstraint != nil {
                self.addConstraint(aspectConstraint!)
            }
        }
    }

how is my code breaking any constraints? they have nothing to do with eachother

2017-01-10 21:15:18.502301 Gymkhana[4538:65958] [LayoutConstraints] Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (

"<NSLayoutConstraint:0x78698d60 UILabel:0x7869e890'Identical twins play a mi...'.top == UITableViewCellContentView:0x7869e500.topMargin   (active)>",
"<NSLayoutConstraint:0x7869c930 V:[UILabel:0x79ba65a0'1h']-(8)-[Gymkhana.ThumbnailImageView:0x7869c340] (active)>",
"<NSLayoutConstraint:0x786a9ef0 H:[Gymkhana.ThumbnailImageView:0x7869c340]-(0)-|   (active, names: '|':UITableViewCellContentView:0x7869e500 )>",
"<NSLayoutConstraint:0x78689700 H:|-(0)-[Gymkhana.ThumbnailImageView:0x7869c340]   (active, names: '|':UITableViewCellContentView:0x7869e500 )>",
"<NSLayoutConstraint:0x7869a1b0 V:[Gymkhana.ThumbnailImageView:0x7869c340]-(30)-|   (active, names: '|':UITableViewCellContentView:0x7869e500 )>",
"<NSLayoutConstraint:0x7869ca10 V:[UILabel:0x7869e890'Identical twins play a mi...']-(8)-[UILabel:0x79ba65a0'1h']   (active)>",
"<NSLayoutConstraint:0x798fb620 Gymkhana.ThumbnailImageView:0x7869c340.width == Gymkhana.ThumbnailImageView:0x7869c340.height   (active)>",
"<NSLayoutConstraint:0x79b85b80 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x7869e500.height == 329   (active)>",
"<NSLayoutConstraint:0x79b82b80 'UIView-Encapsulated-Layout-Width' UITableViewCellContentView:0x7869e500.width == 320   (active)>" )

Will attempt to recover by breaking constraint

<NSLayoutConstraint:0x798fb620
Gymkhana.ThumbnailImageView:0x7869c340.width==Gymkhana.ThumbnailImageView:0x7869c340.height   (active)>
toddg
  • 2,863
  • 2
  • 18
  • 33
samitarmum
  • 83
  • 8

1 Answers1

2

Constraints can be treated rules that AutoLayout uses when trying to calculate 4 parameters of a view: x, y (meaning coordinates of the top left corner), width and height. You put 5 constraints on your image view so, except for special cases, there will be some conflicts between them.

The first 4 constrains you mentioned already give enough information for the AutoLayout to calculate all 4 parameters for your imageView that I mentioned. Then aspect ratio constraint comes in and that is almost certain to be in conflict with other constraints unless your previous already lead to exactly same aspect as you set in the constraint.

There are 2 ways you could solve this:

  1. If the image you want to set to the imageView already has the aspect ratio you want: remove the aspect ratio constraint completely. Use imageView's contentMode property instead.

  2. If you really do need a specific aspect ratio to your imageView, then you need to rethink your other 4 constraints, since it clearly seems that some of them do not represent accurately how you want your imageView to be positioned and resized. For example: perhaps you don't need the leading and trailing constraints and you just wanted the imageView to have same distance from both left and right side of its superview? Then remove trailing and leading constraints and add a "center horizontally" constraint instead.

johnyu
  • 2,152
  • 1
  • 15
  • 33
  • add a center horizontally and remove trail and lead constraint make my image view bound expand to be larger than the cell containing it, making it cropped on the left and right side. Do you have any other solution? – samitarmum Jan 10 '17 at 14:46
  • 1
    As in point 1: Remove aspect constraint completely. Set imageView's `contentMode` to `UIViewContentModeScaleAspectFit` – johnyu Jan 10 '17 at 14:49
  • The reason why I add aspect constraint in the first place is this problem: http://stackoverflow.com/questions/26041820/auto-layout-get-uiimageview-height-to-calculate-cell-height-correctly . – samitarmum Jan 10 '17 at 14:55
  • 1
    Did you set `tableView.rowHeight = UITableViewAutomaticDimension`? – johnyu Jan 10 '17 at 15:19
  • yes, I have set automatic tableview dimension but the problem is not the cell itself but the imageview. can you look at this problem: http://stackoverflow.com/questions/26041820/auto-layout-get-uiimageview-height-to-calculate-cell-height-correctly – samitarmum Jan 10 '17 at 15:37
  • 1
    Maybe try setting top and bottom space constraints to 999 instead of the default 1000? – johnyu Jan 10 '17 at 16:23