iOS UICollectionView lags with scrolling at start - ios

I use a simple UICollectionView in ma iOS in my project.
The view loads about 100 Cells. The Problem appears even if a let the Cells empty.
After ViewDidLoad the Collection view Appears. When i start Scolling about the first three screen Pages down it lags - even with empty cells!
after that i becomes smooth. I also can get top of the page and try again. Scrolling kepps smooth.

2 reasons that you might also encounter
1. Google analytics
If you set up to count every cell view. It starts fast but then slows down and lags because google analytics writes i/o (maybe some caching) as you scroll too fast.
2. DateTime Parsing
DateFormatter is hard if you setup for every cell. Make sure you have a singleton if possible.

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.

How to use NSFetchedResultsController for scrolling bottom to top in messaging app?

I am building a message app. When I am messaging in my application all the messages are getting store in core data. I have connected the core data with TableViewController with NSFetchedResultsController. I know how does this work and I am using NSFetchedResultsController for a long time with TableView. In most of the case TableView load from top and it's scroll down to load more data on requirement, thus my application works pretty well.
Here for the message app the TableView behaviour is opposite from the previous one. It loads the last messages(20-30 batch size) and if I want to see the old message I will scroll top. So I am trying to implement this on NSFetchedResultsController.
Example :
Suppose I have 100 messages. I am setting batch size is 10. So first it will load 90-100 messages and it will scroll down to the last indexpath(here 100th). Then If I want want to scroll top and reach 90th indexpath it will give me 10 again so now I have 80-100 messages now it won't scroll down it will be keep on doing the same thing is I scroll to top.
I know I can sort in reverse order but that time I will get 100-90 but it won't so the last message(100) bellow.
So how can I fix this issue? Any configuration is there for NSFetchedResultsController that I am missing? How to fix?

iOS chaining together animations for scrolling table view

So this is a rather simple problem that I've had a rather hard time fixing. I'm trying to take advantage of table views for displaying a huge list of cells because it is already optimized for cell reuse and saves me time in that regard. I need this list to smoothly scroll at an accurate duration. If I scroll too fast cells are still loading when they show on screen so I'm only scrolling one cell at a time.
The code I'm currently using is modified from here: https://stackoverflow.com/a/17956396. I've changed it to only add a single animation to the array and to never remove it. Instead I have a counter that checks to see if there is another cell before scrolling.
This is working fine, but my issue is that I can't update the animation duration to be faster or slower to keep an accurate pace. Is there a way for me to chain animations in a way that would allow me to dynamically update the duration so as to keep accurate timing?

Scrolling lag & scrollbar jumping when UITableView gets bigger

As the title says, I'm working with a UITableView which is hooked up to a FetchedResultsController mediated by the ViewController.
The lag happens when the user scrolls close to the bottom of the grid and we fetch more data to display to the user. When the data is received, and the tableview's content gets larger, the scrolling pauses momentarily followed by some stuttering and then the scrollbar jumps higher and finally everything smooths back out.
This happens in:
-(void)controllerDidChangeContent:(FetchedResultsController *)controller {
[tableView reloadData];
}
I've done all the optimization that I have found scouring Apple's dock's and SO.
Reusing views as I should. This helped the most with performance. Init's for cells hardly ever get hit.
Decoding images in background threads (drawing on a context) before using the imageview. (note the stutter happens before we even get images to replace the "loading" ui of the cells).
Extremely short and quick delegate methods.
Opaque hand drawn views.
Does anyone have any recommendations on handling additions of rows to a UITableView that does not block the UI thread and prevents the scrollbar from jumping? I've tried using [tableView insertRows...] but the same stuttering and scrollbar jumping happened, which I thought was odd.
Cheers,
Zed
This is actually quite natural for a UITableView to do. Unfortunately, it's not graceful. If your app is continually retrieving data and reloading, then that also impacts your performance. I've even tested your theory and manually populated a UITableView using a NSMutableArray. I gave the array several values, and that was even enough to make it lag. (Keep in mind that there were no extra methods involved, even reloadData wasn't involved. Just the basic delegate methods).

Custom UIView with Lazy Loading scrolls too slow

So, I currently have a GridView class, which is essentially what it sounds like. It is a subclass of UIView that has a staging area that has a bunch of subviews placed in a grid-like manner. Each cell of the GridView is a custom UIView subclass which calls drawRect.
I implemented lazy loading by following the UITableView pattern. I only loaded and added the grid cells which were visible (+/- 2 cells on each side). As the view is scrolled through, I cache cells that are no longer visible in a NSMutableSet and also re-use cells from that Set to build the cells that are now visible. Everything about that seems to work fine, as I have tested and profiled it, with no memory leaks.
The problem is that scrolling is too slow / jerky. The faster the user scrolls, the jerkier it is. Sometimes, if you scroll very fast, it throws a memory warning. After some debugging work, I found when it starts freezing and jerking, the subviews in the gridview don't get removed, like they should
I also noticed that the scrolling is significantly slower on the iPad 1 vs. the iPad 2.
My questions is, does anyone have any ideas on how to handle this? Any tricks or optimizations to stop the jerky-ness of the scrolling? Anything would help at this point, as I have been trying to figure this out for 2 days. Thanks in advance
Possible slowdown causes : 1) drawRect 2) cacheing during user enabled active interface
choice a) preload, and then present smooth interface, or b) smooth scroll while loading stuff in background, blank areas where load is in progress?
Debugging: have you tried doing NSLog during the process, for example for each cache call, seeing if it is doing a lot of unnecessary work?

Resources