Occasionally I want to scroll to the top when I do reloadData ()
on ʻUITableView`. But this is quite annoying. .. ..
I tried various methods, so I will write it as a memorandum.
What I want to do is "I want to reload + scroll position back to the top when the button is pressed"!
Like this (before is displayed at the bottom and after is scrolled from before to reload + top)
before | after |
---|---|
The table is a grouped
style table where the header written in Last article disappears and appears!
(Before hides header, after shows header)
There are setContetnOffset
and scrollToRow
as a way to scroll the table to the top, and I think there are 4 patterns depending on whether you scroll before or after reloadData
.
The implementation looks like this
//Pattern 1 (setContentOffset scroll forward)
tableView.setContentOffset(.zero, animated: false)
tableView.reloadData()
//Pattern 2 (scrollToRow forward scroll)
tableView.scrollToRow(at: .init(row: 0, section: 0), at: .top, animated: false)
tableView.reloadData()
//Pattern 3 (scroll after setContentOffset)
tableView.reloadData()
tableView.setContentOffset(.zero, animated: false)
//Pattern 4 (scroll ToRow)
tableView.reloadData()
tableView.scrollToRow(at: .init(row: 0, section: 0), at: .top, animated: false)
The result looks like this
Pattern 1 | Pattern 2 | Pattern 3 | Pattern 4 |
---|---|---|---|
Pattern 1 and pattern 4 (but because it is a row setting, I have not scrolled to the header) seems to be good, but patterns 2 and 3 are in halfway positions. .. ..
I don't know what it is, but the content size is not fixed for the time being = I think that the result will be as above because the layout is halfway, should I call layoutIfNeeded ()
? So I implemented it as follows.
//Pattern 1 (setContentOffset scroll forward)
tableView.setContentOffset(.zero, animated: false)
tableView.layoutIfNeeded()
tableView.reloadData()
//Pattern 2 (scrollToRow forward scroll)
tableView.scrollToRow(at: .init(row: 0, section: 0), at: .top, animated: false)
tableView.layoutIfNeeded()
tableView.reloadData()
//Pattern 3 (scroll after setContentOffset)
tableView.reloadData()
tableView.layoutIfNeeded()
tableView.setContentOffset(.zero, animated: false)
//Pattern 4 (scroll ToRow)
tableView.reloadData()
tableView.layoutIfNeeded()
tableView.scrollToRow(at: .init(row: 0, section: 0), at: .top, animated: false)
The result looks like this
Pattern 1 | Pattern 2 | Pattern 3 | Pattern 4 |
---|---|---|---|
All patterns look good: tada:
By calling layoutIfNeeded ()
, each behavior is as expected, but it's ambiguous! There is no problem if the cell height is fixed, but if the cell height is variable, it's a little. .. .. : confounded:
Prepare the following two patterns of cells.
When I try the process of execution result 2, the result looks like this (By the way, if there is no layoutIfNeeded
pattern, scrolling is halfway except for pattern 4)
Pattern 1 | Pattern 2 | Pattern 3 | Pattern 4 |
---|---|---|---|
Other than pattern 3, it seems to work: clap: Probably pattern 3 will work if you return an appropriate value with tableView (_: estimatedHeightForRowAt :)
. It would be nice if there were 2 patterns, but if auto layout was involved here, various height calculations would be troublesome. .. ..
Regarding the height of the cell, various things were carefully described in the following article, so please refer to it (I do not know much ...) What should be set for rowHeight and estimatedRowHeight of UITableView
This time, I wanted to scroll to the header because it was a lot of trouble with calculations, so I adopted the following. (Maybe it's good: v :)
//Pattern 1 (setContentOffset scroll forward)
tableView.setContentOffset(.zero, animated: false)
tableView.layoutIfNeeded()
tableView.reloadData()
The operation is like this
Comment, but it seems that you should change the scroll position from .top
to .bottom
as shown below: tada:
tableView.reloadData()
tableView.scrollToRow(at: .init(row: 0, section: 0), at: .bottom, animated: false)
I don't even need layoutIfNeeded
and I think this is the best: relaxed:
There are some combinations of reloadData
and scrolling to the top, but what should I do after all? I always worry. .. ..
There seems to be the following method.
iOS TableView reload and scroll top
If you know any other good way, please teach me: raised_hands:
Recommended Posts