UIStackView not updating after updating height of subview (UITableView with no scroll) while inside a ScrollView

Tom Bevelander

How to make a UIStackView re-distribute it's sub-UITableViews while the stackView is inside a scrollview?

My layout hierarchy is based on the official documentation from apple about Dynamic content for StackViews

 - UISCrollView
   - UIStackView
     - UIView A
     - UIView B
     - UIView C
     - UITableView X
     - UITableView Y
     - UIView D

The constraints are set as documented. The initial layout of the StackView is correct showing all visible subviews. When forcing the regular views to expand beyond the screen's height, scrolling is working as expected. Also when viewing the layout in the storyboard, everything stacks as expected.
At this point the UITableViews are empty. As soon as I add content to the tableView the problem appears.

The problem
When I dynamically update the TableView's by calling .reloadData() on both of them I see their content appearing. (thanks to this answer about non-scrolling tableViews) but the UIStackView is not stacking the UITableViews.

  • UIView D is stacked below UIView C
  • UITableView X and UITableView Y also stacked below UIView B

My guess is that I need to invalidate the stackview, or somehow get it to redistribute it's subviews. How can I do this?

enter image description here

Mischa

First, a warning:

What you're trying to achieve is not really standard iOS behavior. You should first consider a different approach like creating a single grouped table view with multiple sections. You can implement custom views inside your table view as section headers or footers.


Now if you really wanna go with your original approach...

... for some important reason you should be aware that a table view doesn't have an intrinsic content size by default. Thus, you need to tell the table view how tall it should be because otherwise it will only shrink down to a zero height.

You can achieve this by either subclassing UITableView and overriding its intrinsicContentSize() as Rob suggests in this answer to a similar question.

Or you add a height constraint to each of your table views and set their constants dynamically in code. A quick example:

  1. Add both your table views to a vertical stack view in Interface Builder.
  2. Give both table views a leading and a trailing constraint to pin their left and right edges to the stack view.
  3. Create outlets for your table views in the respective view controller:

    @IBOutlet weak var tableView1: UITableView!
    @IBOutlet weak var tableView2: UITableView!
    
    @IBOutlet weak var tableView1HeightConstraint: NSLayoutConstraint!
    @IBOutlet weak var tableView2HeightConstraint: NSLayoutConstraint! 
    
  4. Override the updateViewConstraints() method of that view controller:

    override func updateViewConstraints() {
        super.updateViewConstraints()
        tableView1HeightConstraint.constant = tableView1.contentSize.height
        tableView2HeightConstraint.constant = tableView2.contentSize.height
    }
    
  5. Now whenever the content of any of your table views changes (e.g. when you add or remove rows or change the cell contents) you need to tell your view controller that it needs to update its constraints. Let's say you have a button that adds a cell to tableView1 each time you tap it. You might implement its action like this:

    @IBAction func buttonTappen(sender: AnyObject) {
        // custom method you implement somewhere else in your view controller
        addRowToTableView1DataSource()
        // reload table view with the updated data source
        tableView1.reloadData()
        // triggers an updateViewConstraints() call
        view.setNeedsUpdateConstraints()
    }
    

tl;dr:

A UITableView isn't intended for use without scrolling enabled and thus you always need to explicitly set its height when its contents change - may it be using constraints or by overriding the table view's intrinsic content size.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

After scroll, UILabel not updating in UITableViewCell

From Dev

UITableView not updating

From Dev

$watch not updating subview

From Dev

NSFetchedResultsController can't scroll while table updating

From Dev

ScrollView inside a UIStackView

From Dev

UITableView cellForRowAtIndexPath function not updating after reload function

From Dev

Updating data in UITableView after asynchronous load

From Dev

Height of UITableView changed after scroll the view

From Dev

Updating cell height after image downloads

From Dev

My frame height is not updating after changes made

From Dev

Updating uitableview datasource and updating tabbar

From Dev

Updating Date inside a while loop, Java

From Dev

Dynamically updating cell height without having to scroll Swift

From Dev

Global array not updating after .push inside function

From Dev

UITableView stops updating content while scrolling through view?

From Dev

UITableView cells not updating in Swift

From Dev

searchDisplayController not updating UITableVIew

From Dev

Updating data in UITableView is not smooth

From Dev

UITableView not updating on reloadData

From Dev

Error updating UITableView after smaller sized JSON response?

From Dev

How to scroll a scrollview to come a subview in top in Android

From Dev

UITableViewCell not updating after location callback until scroll or selection

From Dev

How to manipulate scroll position after updating gridview row?

From Dev

Updating database after updating resultset

From Dev

Layout height not updating properly after collapse and expand animation

From Dev

Android: Updating the UI from an adapter inside a While Loop

From Dev

Updating View while running loop inside another class?

From Dev

Android: Updating the UI from an adapter inside a While Loop

From Dev

Python updating lists error! List will not update inside while loop

Related Related

  1. 1

    After scroll, UILabel not updating in UITableViewCell

  2. 2

    UITableView not updating

  3. 3

    $watch not updating subview

  4. 4

    NSFetchedResultsController can't scroll while table updating

  5. 5

    ScrollView inside a UIStackView

  6. 6

    UITableView cellForRowAtIndexPath function not updating after reload function

  7. 7

    Updating data in UITableView after asynchronous load

  8. 8

    Height of UITableView changed after scroll the view

  9. 9

    Updating cell height after image downloads

  10. 10

    My frame height is not updating after changes made

  11. 11

    Updating uitableview datasource and updating tabbar

  12. 12

    Updating Date inside a while loop, Java

  13. 13

    Dynamically updating cell height without having to scroll Swift

  14. 14

    Global array not updating after .push inside function

  15. 15

    UITableView stops updating content while scrolling through view?

  16. 16

    UITableView cells not updating in Swift

  17. 17

    searchDisplayController not updating UITableVIew

  18. 18

    Updating data in UITableView is not smooth

  19. 19

    UITableView not updating on reloadData

  20. 20

    Error updating UITableView after smaller sized JSON response?

  21. 21

    How to scroll a scrollview to come a subview in top in Android

  22. 22

    UITableViewCell not updating after location callback until scroll or selection

  23. 23

    How to manipulate scroll position after updating gridview row?

  24. 24

    Updating database after updating resultset

  25. 25

    Layout height not updating properly after collapse and expand animation

  26. 26

    Android: Updating the UI from an adapter inside a While Loop

  27. 27

    Updating View while running loop inside another class?

  28. 28

    Android: Updating the UI from an adapter inside a While Loop

  29. 29

    Python updating lists error! List will not update inside while loop

HotTag

Archive