3

I'm currently building a reusable view that takes advantage of the dynamic resizing that UITableView has on offer with its cells.

What I'm trying to achieve is to give a view within the cell a width and a height depending on the size it has been given within the size property that is defined within a struct, I pass this through using a configure function, after setting the size of the view.

I then center it on the xAxis and apply any margins around the view using a property within the struct which is just a UIEdgeInset property. Using the SnapKit library this looks like this.

    if  let formImageItem = formImageItem,
        let size = formImageItem.size {

        formItemImgVw = UIImageView(frame: CGRect(x: 0, y: 0, width: size.width, height: size.height))
        formItemImgVw?.image = formImageItem.image
        formItemImgVw?.contentMode = formImageItem.aspectFit

        contentView.addSubview(formItemImgVw!)

        formItemImgVw?.snp.makeConstraints({ (make) in
              make.size.equalTo(CGSize(width: size.width, height: size.height))
              make.top.equalTo(formImageItem.margin.top)
              make.bottom.equalTo(formImageItem.margin.bottom)
              make.centerX.equalToSuperview()
        })
    }

The issue I seem to be having is i'm getting the following warning.

2018-10-12 14:57:34.101532+0100 xxxx Dev[6104:2160548] [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. 
(
    "<SnapKit.LayoutConstraint:0x2830ec720@FormImageViewTableViewCell.swift#61 UIImageView:0x10530a940.height == 114.0>",
    "<SnapKit.LayoutConstraint:0x2830ec780@FormImageViewTableViewCell.swift#62 UIImageView:0x10530a940.top == UITableViewCellContentView:0x105503500.top>",
    "<SnapKit.LayoutConstraint:0x2830ec7e0@FormImageViewTableViewCell.swift#63 UIImageView:0x10530a940.bottom == UITableViewCellContentView:0x105503500.bottom>",
    "<NSLayoutConstraint:0x2837e2580 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x105503500.height == 44   (active)>"
)

Will attempt to recover by breaking constraint 
<SnapKit.LayoutConstraint:0x2830ec720@FormImageViewTableViewCell.swift#61 UIImageView:0x10530a940.height == 114.0>

I understand what this is telling me basically that it's choosing to use the height 44 that is set by default for a table view cell. But I can't seem to get my head around why it's using this default height rather than the one that I have defined within my constraints and applying the height to the view whilst also adding the spacing to the top and bottom.

Also when using the debugger to inspect the UI it seems like a height isn't being set at all and as you can see the height of 44 is just clipping the entire imageview.

enter image description here

So ultimately what I'm trying to achieve is the ability to give a view a defined height and width, and use values to apply top and bottom spacing(margins) in order to resize the cell that it's currently within.

Tunds
  • 1,804
  • 2
  • 15
  • 30
  • Looking at SnapKit's docs, it looks like you want your top and bottom constraints to be: `make.top.equalTo(contentView.snp.top).offset(formImageItem.margin.top)` and `make.bottom.equalTo(contentView.snp.bottom).offset(formImageItem.margin.bottom)` ? I'm assuming `formImageItem.margin.top` is a numeric value? And, keep in mind, the bottom value probably needs to be negative... – DonMag Oct 12 '18 at 16:36
  • @DonMag So just tried that and it seems like a height of 44 is being enforced by the contentview, which is overriding my height that i'm setting.... – Tunds Oct 12 '18 at 16:39
  • I think you need to double check your code, and double check (debug) all the values you're getting in your `formImageItem` object. I just downloaded SnapKit and did a quick table view, using your `formItemImgVw?.snp.makeConstraints()` block, getting this result: https://imgur.com/a/qkvY9FP ... no auto-layout errors or warnings, and the cells sized themselves as expected. – DonMag Oct 12 '18 at 17:35
  • @DonMag Dunno why but after resetting to the last commit and adding the property from the accepted answer below everything is working now, so somewhere in my code i must of been setting the wrong property – Tunds Oct 12 '18 at 17:42

1 Answers1

5

You need to lower the priority of the bottom constraints so replace this

make.bottom.equalTo(formImageItem.margin.bottom)

with

make.bottom.equalTo(formImageItem.margin.bottom).priority(999)

plus in viewDidLoad

tableView.estimatedRowHeight = 120 
tableView.rowHeight = UITableViewAutomaticDimension

abd don't implement heightForRowAt

Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87
  • Tried that already and the same with the top I still don't get the desired effect because there isn't a bottom constraint the tableviewcell height doesn't change. – Tunds Oct 12 '18 at 14:24
  • So why 120? On the estimated row height and row height? – Tunds Oct 12 '18 at 14:35
  • 1
    you need to give an estimated height to help autolayout in drawing before calculating the real one in log 114 – Shehata Gamal Oct 12 '18 at 14:36