I got an UITableView
which is filled with an unknown amount of rows. Each row contains (for example 3) images and the application gathers this information from a webservice.
For the UITableView
I implemented infinite scrolling. Whenever the table almost reaches the end of the current amount of rows, I initiate a call to the webservice, to fetch the next 50 rows of data. I do this in the scrollViewDidScroll
method which is called by the UITableView
.
- (void) scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat actualPosition = scrollView.contentOffset.y;
float bottomOffset = 450;
if([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
bottomOffset = 1000;
CGFloat contentHeight = scrollView.contentSize.height - bottomOffset;
if (actualPosition >= contentHeight && !_loading && !_cantLoadMore)
{
self.loading = YES;
_currentPage++;
NSMutableDictionary* dict = [[NSMutableDictionary alloc] init];
[dict setObject:[NSNumber numberWithInt:_currentPage] forKey:@"page"];
[dict setObject:[_category objectForKey:@"ID"] forKey:@"category"];
[self performSelectorInBackground:@selector(getWallpapersInBackground:) withObject:dict];
}
}
The images in the rows of the UITableView
are lazy loaded. Whenever a row is visible, the images are loaded in a separate thread and the rows are updated once an image is fully downloaded. The principle I use for lazy loading, is the same as Apple suggests in their documentation. The image is also added to a local NSDictionary
, so I can fetch it when the row scrolls out of the screen and back in (and the row is recreated).
Because the amount of pictures in a single view can go up to 2000 - 3000, I also cache the images to disk and clear out the images from the NSDictionary
when they are further than X rows away. When the user scrolls down and up again the following happens:
UIImage
is added to NSDictionary
for faster caching of images that need to be within reach.NSDictionary
, because of memory problems (too many UIImage
objects in the NSDictionary
cause out-of-memory errors).When the UITableView almost reaches the end, the following occurs:
numberOfItemsInSection
method.reloadData
is called to make sure the UITableView
populates with the extra new rows.So, the problem I have is when I am adding new records from the webservice. When I call a reloadData
on the UITableView
some images are loading from disk again and some hickups occur while scrolling.
I am looking for a solution for this. I tried using insertItemsAtIndexPaths
with the amount of new rows, to add them to the UITableView
, but this makes my lazy load method already download the images (because somehow all the cells are created at that time, even when they are not visible, checking if cell is visible during creation delivers unexpected results, images not loading, cells look weird, etc).
So, what I essentially am looking for is a solution for an infinite scrolling UITableView, which lazy loads images from the web/disk and is as smooth as the photo application. Since images are all loaded in separate threads, I don't understand why scrolling isn't as smooth as a baby's skin.
A view that presents data using rows in a single column. iOS 2.0+ iPadOS 2.0+ Mac Catalyst 13.1+ tvOS 9.0+
Pagination in Swift is the ability to scroll to the bottom of the page and it automatically fetches more data. Every app nowadays uses this feature to load more information.
I'm not sure if I totally grok the fullness of your question, but here are some things that I did when confronted with a similar problem.
I used -tableView:cellForRowAtIndexPath:
as my cue to load more data from the web. I picked a number (in my case 10), when indexPath.row + 10 >= self.data.count
load more data.
-tableView:cellForRowAtIndexPath:
anyway.-scrollViewDidScroll:
.I subclassed UIImageView
with a class that would async load images which I called URLImageView
.
-tableView:cellForRowAtIndexPath:
, I assigned a URL to the URLImageView
instance.I had a table view with hundreds (but not thousands) of images. I only had 2 or 3 table cells on the screen at once.
-refreshData
: it worked like a champ.URLImageView
to fade in the image. It was a very nice effect.I hope that helps.
to avoid the flickering try calling beginUpdates
on the table, then insertrowAtIndexPaths:withRowAnimations:
and finish with endUpdates
.
Good luck.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With