This article has participated in the good Article call order activity, click to view:Back end, big front end double track submission, 20,000 yuan prize pool for you to challenge!
RxSwift writes wanAndroid client now open source
RxSwift is now open-source to write wanAndroid clientsProject link. Remember to give a star oh!
Attach an image of the effect:
This article is developed and explored from the comments of enthusiastic netizens in the June post:
It is true that this function was not implemented in June because of the day change, but it was solved in July.
So much nonsense, let’s get to the point.
What is the perceptual pull-up load more
Under normal network conditions, the user can continuously pull up the list, and the list can keep appearing new data without any delay.
If you want to experience, a lot of Web end has been done, such as the home page of the Nuggets, and such as the Nuggets iOS App, the list is perceptual pull up to load more.
I am ashamed to say that after writing the code for a long time, I really did not think about how to realize this function.
How to achieve more perceptual pull-up loading
When I saw this netizen’s message, I began to think.
In my opinion, here are a few places to start:
-
When the list slides, how do you know exactly where to slide to trigger an interface request to add more data?
-
Look for callbacks that are closely related to the location (contentOffset) and contentSize of the scrollView from the UIScrollView’s agent callbacks.
-
Is there mature train of thought on the network?
Following this line, I first ran to look at the UIScrollViewDelegate source code:
public protocol UIScrollViewDelegate : NSObjectProtocol {@available(iOS 2.0, *) optional func scrollViewDidScroll(_ scrollView: // Any offset changes @available(iOS 3.2, *) optional func scrollViewDidZoom(_ scrollView: UIScrollView) // any zoom scale changes...... /// }Copy the code
Let’s jump to the conclusion: After looking around, there is no callback agent related to contentSize or location. ScrollViewDidScroll is a callback that can call back to scrollView, but it’s not specific enough for what we need.
Consider: Since UIScrollViewDelegate’s proxy does not have a ready-made proxy callback, try listening with KVO yourself?
Ideas on the Internet (1)
While I was thinking, I also asked for the answer to realize this function on the network, and then I saw this idea:
And the way to do that is very simple, you need to use one of the proxy methods of the tableView, and you can easily do that. – (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath is this method, custom display cell. This method is not used very often. But this method can be triggered when each cell is about to appear for the first time. We can then set which cell will appear on the current page to trigger a request to load more data.
I looked at it and thought, well, it’s better to write one more TableView agent than it is to write KVO code, so let’s try it and see what happens, so I rolled up the code:
extension SwiftCoinRankListController: UITableViewDelegate {
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let row = indexPath.row
let distance = dataSource.count - 25
print("row: \(row), distance:\(distance) ")
if row == distance {
loadMore()
}
}
}
Copy the code
This code can be in the open source project SwiftCoinRankListController. Swift file to check the specific logic, its main is to request in advance through the cell shows the number of load data, then we can see the effect:
Gif may look ok, I said I debug the feeling:
Although the pull up without perception, but when the speed of the hand slide is relatively fast, in the end the new data does not come back, will wait for a period of time at the bottom.
The function is achieved, but the feeling is not ideal, as expected, the delicate degree of monitoring is not enough.
Ideas on the Internet (2)
Then, as I continued my search, I came across another solution:
Pull up refresh many times we need to load new data, then use MJRefreshAutoFooter triggerAutomaticallyRefreshPercent properties can be achieved, This attribute triggerAutomaticallyRefreshPercent default value is 1, then change to zero row to the bottom will be automatically refresh, to 1, in the end of the row to the bottom 44 px will automatically refresh.
MJRefresh? Use MJRefreshAutoFooter, this simple, I the base class directly to the footer to replace is ok, the code can be in the open source project BaseTableViewController. Swift file view:
/ / / set the tail refresh controls, updated to no perceptual load more let footer = MJRefreshAutoFooter () footer. TriggerAutomaticallyRefreshPercent = 1 tableView.mj_footer = footerCopy the code
Here’s how it works:
Speak directly about your feelings:
Code changes less, write simple, achieve the desired effect, cool crooked. It is smoother and better than scheme 1.
At this point, the function is realized, is it over?
Of course, no, let’s look at the source code.
Tracing the source of the MJRefresh code
First let’s look at the mjrefreshautoFooter.h file:
Here is a special attribute triggerAutomaticallyRefreshPercent to do automatic refresh, then we go to MJRefreshAutoFooter. M in to look at it:
Pay attention to this. Oh, m files have a – (void) scrollViewContentOffsetDidChange (NSDictionary *) change method, and also call the super, From this method name we can clearly see that it is listening for the callback when the contentOffset of the scrollView changes. , let’s follow the trail to see what super is and whether there will be new discoveries:
MJRefreshAutoFooter inherits from MJRefreshAutoFooter.
MJRefreshAutoFooter => MJRefreshFooter => MJRefreshComponent
So let’s go to mjRefreshComponent.m to call super:
From the screenshot above, we can get the following information and conclusions:
-
The MJRefreshComponent listens for changes to the contentOffset of the scrollView via KVO.
-
This class does not implement its methods, but rather subclasses do, as you can see by looking at the mjRefreshComponent.h comment:
- MJRefreshComponent is more like a virtual base class in nature.
conclusion
I probably wouldn’t have looked at this feature too closely if it hadn’t been asked by a friend of mine, and would have continued to use the general pull-up more.
This practice, in fact, is from the idea to find a method, and finally to the source code reading.
The idea may not be difficult, but actually implementing and improving the functionality step by step is not easy, and THIS time I just continued to use the MJRefresh wheel.
Remember one day, in the group of water saw a picture:
Soul interrogation, straight to the heart, most of the time we are not cloud programmers?
The unity of knowledge and action can open up new horizons.
Refer to the article
IOS issue with auto-loading data from list pull-up (smooth loading data)
MJRefresh Tips (pull up to refresh in advance)