[SWIFT] I want to return the scroll position of UITableView!

Xcode-12.0iOS-14.0Swift-5.3

Introduction

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
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)

Method

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.

Execution result 1

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
1 2 3 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. .. ..

Execution result 2

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
l_1 l_2 l_3 l_4

All patterns look good: tada:

Execution result 3

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.

cell

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
b_l_1 b_l_2 b_l_3 b_l_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

Conclusion

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

scroll

20201024 postscript

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:

in conclusion

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

I want to return the scroll position of UITableView!
I want to output the day of the week
I want to var_dump the contents of the intent
I want to know the answer of the rock-paper-scissors app
I want to display the name of the poster of the comment
I want to expand the clickable part of the link_to method
I want to change the log output settings of UtilLoggingJdbcLogger
I want to narrow down the display of docker ps
I want to return multiple return values for the input argument
I want to temporarily disable the swipe gesture of UIPageViewController
I want to understand the flow of Spring processing request parameters
I want to return to the previous screen with kotlin and java!
The story of Collectors.groupingBy that I want to keep for posterity
I want to remove the top margin in Grouped UITableView (swift)
I want to control the default error message of Spring Boot
I want to change the value of Attribute in Selenium of Ruby
I want to display the number of orders for today using datetime.
I want to know the JSP of the open portlet when developing Liferay
[Ruby] I want to extract only the value of the hash and only the key
I want to get the field name of the [Java] field. (Old tale tone)
I want you to use Enum # name () for the Key of SharedPreference
[Rails] Button to return to the top of the page
I want to truncate after the decimal point
I want to get the value in Ruby
[RxSwift] I want to deepen my understanding by following the definition of Observable
I want to get the value of Cell transparently regardless of CellType (Apache POI)
I want to control the start / stop of servers and databases with Alexa
I want to separate the handling of call results according to the API caller (call trigger)
I want to see the contents of Request without saying four or five
I want to recursively get the superclass and interface of a certain class
I want to call a method of another class
[Java] I want to calculate the difference from the date
I want to embed any TraceId in the log
I was addicted to the record of the associated model
I tried to summarize the state transition of docker
05. I tried to stub the source of Spring Boot
I tried to reduce the capacity of Spring Boot
I want to dark mode with the SWT app
[SwiftUI] How to specify the abbreviated position of Text
I want to call the main method using reflection
[Rough commentary] I want to marry the pluck method
I want to simplify the log output on Android
I want to add a delete function to the comment function
[Ruby] I want to make a program that displays today's day of the week!
Rails The concept of view componentization of Rails that I want to convey to those who want to quit
[Active Admin] I want to specify the scope of the collection to be displayed in select_box
I want to place RadioButtons in the same RadioGroup at any position on the screen.
[Rails] I want to display the link destination of link_to in a separate tab
I want to reduce the number of unnecessary queries. From considering counter_cache to introducing counter_culture.
9 Corresponds to the return value
I want to set the conditions to be displayed in collection_check_boxes
[Rails] [bootstrap] I want to change the font size responsively
I tried to summarize the basics of kotlin and java
I want to use screen sharing on the login screen on Ubuntu 18
(´-`) .. oO (I want to easily find the standard output "Hello".
I want to bring Tomcat to the server and start the application
I want to make a specific model of ActiveRecord ReadOnly
[Swift] I tried to implement the function of the vending machine
I want to call a method and count the number
I want to use the Java 8 DateTime API slowly (now)
I want to create a form to select the [Rails] category