0

I've stack view inside table cell which contains three views. I want the stack view to adjust itself when one or two views are hidden. My issue is exactly as described in below questions except that my stack view is inside table cell. The solution mentioned in these threads don't work for me. See screenshot below for the exact problem.

Stack view is pinned to all sides and distribution is fill equally.

How do we make it work?

UIStackView shift content to left when inner views are hidden

UIStackView Distribution Fill Equally

enter image description here

Constraints Storyboard func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    guard let cell = tableView.dequeueReusableCell(withIdentifier: "tableCellID", for: indexPath) as? TableViewCell else {
        fatalError("Can't find cell")
    }

    let profile = array[indexPath.row]

    if profile.status {
        cell.view2.isHidden = false
    } else {
        cell.stackViewTrailing.constant += cell.view2.frame.size.width
        cell.view2.isHidden = true
    }

    return cell
}
Davis
  • 105
  • 1
  • 12
  • Show your `TableViewCell` class. This is actually really easy with autolayout. – Rakesha Shastri Mar 31 '19 at 17:40
  • I've uploaded storyboard screenshot. – Davis Mar 31 '19 at 17:44
  • What is the stack view trailing set to? – Rakesha Shastri Mar 31 '19 at 17:45
  • It's set to superview it is contained in. – Davis Mar 31 '19 at 17:46
  • Is that view's anchors set to the `contentView`'s anchors. – Rakesha Shastri Mar 31 '19 at 17:48
  • Yes view is also pinned to contentView on all sides. – Davis Mar 31 '19 at 18:03
  • My bad. I understood the question wrong it seems. You need the padding to remain huh? Then you would need to call `layoutIfNeeded` on the cell after changing the constraint before returning it. That should do it. – Rakesha Shastri Mar 31 '19 at 18:04
  • @Davis: You should precisely describe the problem you're facing in your question. As you can see, a screenshot alone can easily be misunderstood and you cannot expect fellow developers to guess your specific problem from only linking other questions. Please link other questions or answers as additional information, but not as a replacement for the description of your problem. – Mischa Mar 31 '19 at 18:13
  • It's simple question. "Shift left" views when one or more views are hidden. It's exactly the same problem described in both questions which I've mentioned in the link. – Davis Mar 31 '19 at 18:43

1 Answers1

0

Your problem is that you're always adding some value to your trailing constant (cell.view2.frame.size.width) and never subtract it again (in the code you posted). Table view cells are being reused / recycled. So when you scroll and an old table view cell that scrolled out of the view and had only 2 arranged subviews is being resued but this time with 3 arranged subviews, it still has this extra constant you set for your stackViewTrailing constraint.

Try setting an absolute value for your constraint's constant rather that adding a value to it using the += operator, i.e. instead of

cell.stackViewTrailing.constant += cell.view2.frame.size.width

do this:

cell.stackViewTrailing.constant = cell.view2.frame.size.width + padding

That should solve the problem. (That is, if I understand your problem correctly.)

Note:

You might reconsider if a stack view is the right choice here. Stack views always adjust their arranged subviews' widths when one of them is hidden (or revealed) so that the remaining visible one take up all the available space. If you want to have 3 fixed columns no matter how many of them are visible, it might be a better idea to just use plain constraints and give all three subviews equal width constraints.

Mischa
  • 15,816
  • 8
  • 59
  • 117
  • Out of these three views inside stack view any of them can be hidden so the remaining view(s) have to shift left. It's exact same problem described in the link I've added in my question. I can't give fixed width to each view as it has to distribute equally within the device width. I don't want to stretch views to fill the width. Please see the second link in my question which described what I want to achieve. – Davis Mar 31 '19 at 18:02
  • cell.stackViewTrailing.constant = cell.view2.frame.size.width + padding this doesn't solve issue of cell reuse. – Davis Mar 31 '19 at 18:06
  • Then you'll just have to adjust your constraint constant depending on the the number of hidden arranged subviews. – Mischa Mar 31 '19 at 18:06
  • The code I posted is only an example for your specific question. The point is that you will have to set an _absolute_ value for your constant. Of course, you need to calculate that. (For example, if you have 2 columns hidden, it's `2 * columnWidth + padding` under the assumption that all your 3 columns are supposed to have the same width.) – Mischa Mar 31 '19 at 18:08
  • Tx Mischa, it was the indeed the calculation of correct trailing constraints. It took me sometime but I think I've found solution. – Davis Mar 31 '19 at 23:46
  • Glad to hear that. – Mischa Apr 01 '19 at 03:10