Prevent Single Row from Refreshing in UITableView - ios

I have a custom section header in my UITableView that contains A UICollectionView of some avatar images. The data is sourced once and cached for the images (images change so infrequently that it doesn't warrant real time updates).
I was hoping to make it so this header never redraws again even if the UITableView refresh is called. The reasoning for this is every time you take action, it causes the images to flicker as they're being redrawn from their default anonymous silhouette to the actual image of the person. The images are cached, but it doesn't matter because
I assume this is not possible by design - a UITableView will destroy everything and reload it all over again every time the refresh is called, correct?
I just wish I could hook into the refresh and preserve the section header, and reload the rows only.
Thanks for any ideas/guidance, I know this is a little uncommon but I don't want to move the header out into its own view because i'm using a UITableViewController directly, and it would be a real pain to have to embed it in a containerview and all that.

Yes, even you cached the image and set by local or something, it will take time to load. If you are using lazy loading, it will be splash ( for sure :) ). So, the only possible thing is, you have to update your tableView after refreshing is using tableView.beginUpdates and tableView.endUpdates. Input some add cell or remove cell base on the data after refreshing

Related

UITableView Smooth Scrolling Issue Because of "tableView:willDisplayCell: Method"

As it's clear from the title, I have a scrolling performance issue in a table view.
Since I have read nearly every question that is posted online in this regard, and I assume all of you have much more experience with UITableView and its techniques, I won't bother with general stuff, and I just wanna point out some key things in my code that may help you help me spot where I'm doing wrong.
The UI in each cell is very very basic, so rendering each doesn't take considerable time. No shadows, no rounded corners, no extra effect, nothing. Just a few labels and two images, that's all.
The datasource is an NSArray which is already fetched from CoreData. The data of the labels are set from the content of the array, without much calculations or process required.
The height is each cell is a static integer, so the tableView:HeightForRowAtIndexPath: will immediately return the result as fast as possible. No calculations required.
The tableView:CellForRowAtIndexPath: dequeues and reuses cell with reusable identifiers so any re-creation is avoided.
So far everything is perfectly smooth. The issue is where items in Core Data are fetched from a server (Which is extremely fast) as user scrolls down. Data binding is done inside tableView:willDisplayCell:atIndexPath: to prevent tableView:CellForRowAtIndexPath: from becoming slow, as data needs to be loaded just before the cell goes live on the screen. I also fetch new items from server inside this method whenever there're some cells remaining till the last item fetched. So for example when there are totally 50 cells data fetched and put in the CoreData already and this method is called for cell number let's say 40, I request another 50 cell data from server, so that it will be ready whenever user reaches the end of the table.
As I expect this should only be called for the cells that go live on the screen. But putting some NSLogs shows that it is called multiple times until next 200 cells data are fetched (I guess the amount changes depending on device or simulator and the memory available on them and also OS limits). For example, I'm testing on an iPhone 7+, and I start the app and I go the page in which the table is. It fetches first 50 items and only first 4 items are shown on the screen, But I see that tableView:willDisplayCell:atIndexPath: is also called for cell #25, so another 50 is fetched immediately, and then it is called for cell #75, so another 50 is fetched, and this goes on for like first 200-300 cells, and then when fetching is stopped, scrolling is extremely fast and optimized until next 200-300 cells are fetched.
What can I do? Shouldn't tableView:willDisplayCell:atIndexPath: fire whenever a cell is about to be displayed? Where else should I fetch data as user scrolls?
Any ideas or suggestions is REALLY and GREATLY appreciated.

Preload tableView cells and prevent reloading

I already found entries with that topic on this page and also a website that provides a tutorial for that problem. But nothing worked very well.
The tutorial sad I should double the height of my tableView so cells loaded earlier, but with a higher tableView I never reached the last cells.
My problem is, I use a tableView to display my apps mainpage. This mainPage shows every time a topic and if its necessary for that topic it shows for example a cell with a map, one with pictures and sometimes not. Problem now, if I trying to scroll to my view its always lagging because it loads a map or this pictures. And scrolling back again because the loaded cells already deleted. I used a tableView because of the possibility to switch celltypes(mapCell, pictureCell, textCell) on and off.
I understand this feature, because of memory issues but in my case its not that much and it would be better if all my cells be preloaded and stay in memory until I change the topic.
Is there a swifty way to told my tableView to have this behavior?
Thanks a lot and nice greetings
I would suggest a different approach. Set up your table view controller to install placeholder images in your cells, trigger an async download that you cache to disk, and then update the cell with it's downloaded content if it's still visible when the download is finished.
There are various third party frameworks that do all this housekeeping for you.
Declare a cell array.
Follow these steps whenever change in your topic.
Clear you array
Create and configure all cells add to your array.
Return these cells to datasource methods using row index. Don't use tableview dequeue method here.

Swift stop unloading of table view cells?

I'm making a table view that downloads an image for the cell off the web, every time the cell is loaded.
This proves a problem though, as when you scroll down then up again, the cells are reloaded.
Is there any way to stop the unloading of cells, and control how many cells are loaded when the view appears?
I propose that instead of trying to stop your UITableView from reusing cells, which would decrease performance, you store the images you download, using NSCache for example.
NSCache works the same way as a Dictionary - with key value pairs. The main difference however is it incorporates various auto-removal policies, which ensure that it does not use too much of the system’s memory. Here's the documentation on NSCache: https://developer.apple.com/library/ios/documentation/Cocoa/Reference/NSCache_Class/index.html
Using this method: when you're setting up your UITableViewCell, you could check if an image has been downloaded for that NSIndexPath. If an image hasn't been downloaded you download it and add it to the cache once its finished, otherwise you use your cache and get the image from there.

How can I make my UITableView request the X next cells that are outside the visible table?

I would like to have my UITableView load 3 or 4 cells outside of the table so that any data to be shown there is already loaded when I scroll down.
I have some images, and data that must be downloaded before it can be shown in the cell.
This causes a visible delay before the images are loaded when scrolling.
I can manually trigger loading of this data by doing it in the UITableViewDataSource tableView:cellForRowAtIndexPath: method. I've done this before, but I'm curious if there's an easier way to do it.
Is there any way to expand the reusable cell pool, or adjust how the cells are loaded/recycled?
EDIT:
To clarify, I have lazy loading of images and data in place.
Everything works fine, I just wanted an easy solution to the "prefetching" problem.
Which can be solved in many ways that has nothing to do with the view itself. Right now you can easily see the images load as you scroll. I just wanted them to load right before they become visible.
You may be looking for an asynchronous table view that loads the data asynchronously.
Apple provides a sample app demonstrating this:
LazyTableImages
Of course, you could pre-cache the data and begin downloading data into your datasource before they scroll.
The general idea is that you are loading data into a datasource (that is separate from the UI), so you can do this at any time (and in the background). You can display temporary data or some type of loading image or spinner if the data isn't loaded yet.
If data of the cell will be loaded when cel becomes visible, you can programmatically scroll the table view by scrolling to the bottom cell and go back to the first cell without animation. Another way would be creating all the cells and placing them into array when your view controller is created, and feed the table from that array that contains already created cells. I think there is no way to extend the cell pool as you are asking. Hope this helps, Good Luck!

How can I load a large amount of data in a UITableview without memory warnings?

I'm trying to create a custom view that can display a large amount of data, similar to the way UITableView is able to display many rows of data. Right now I'm displaying the data in a UIScrollView, but after I reload the data several times my app starts to receive memory warnings.
What's the right way to design a custom view to display a large amount of data, and how can I avoid these memory warnings?
It doesn't. UITableView loads only as many rows as it can fit on the screen. When it needs more rows it asks the data source for them. This gives the appearance that the table contains all the data without all the overhead of copying everything at once.
When your tableView cell is too heavy means, it has imageView and more than one text label better create a custom cell by subclassing the UITableView.
Make sure that in custom cell the subview should be added only once and reused for cells. Just you need to sent the image of imageview or text of label. Even if you have so many cells in tableview the performance will be good.
And also make sure that if you are loading images from server don't fetch every time when you are setting image for cell. use image cache.
The following link might me useful for loading data to table view from server.
http://www.raywenderlich.com/4295/multithreading-and-grand-central-dispatch-on-ios-for-beginners-tutorial

Resources