UIScrollView paging slow animation - iphone

I have an application i'm currently developing for iOS which is suffering from some performance issues.
The app takes user input through a navigation controller with 5 views, the last view generates a view with a UIScrollView which has a paging effect.
Each page in this UIScrollView has 16 buttons arranged in a grid, each of these buttons is loaded with an image.
Unfortunately when I scroll to a new page in the UIScrollView, the app stumbles across in a jerky animation rather than a smooth one.
I was wondering if anyone had any suggestions on how to improve the performance for the paging UIScrollView effect.
Many thanks.

Is it smoother the second time you navigate to that view?
If so, it's probably the loading of the images that is taking the time. You can fix that by preloading your button images when the app first loads using [UIImage imageNames:...] in your app delegate. That way they will already be cached and available to render when the view is displayed.
If it's not faster the second time, it's probably the actual rendering of the views that is too slow. You can fix that by preloading the views themselves. If you store a reference to your scrollview's subviews in an array, you can preload those views in your app delegate and just keep them in memory ready to display whenever the scrollview is shown.
I doubt that those views will use up too much memory (probably a couple of MB, max), but if you are worried about it, just add a memory warning handler that flushes out the array and then re-create it next time it's needed.

Related

iOS - Force a UIWebView to load content?

I set the content of a UIWebView using loadHtmlString:. I don't add them to the UIView until they are need, but I need to know the max scroll height of each of them.
The problem is that UIWebView doesn't start loading it's data until it's added to a superView, and It's the delay of loading content that is causing this problem.
Question: Is it possible to force a UIWebView to load its content, without being added to a view?
You can add it to the view and set it's opacity to 0.01 to force the load. I've had to do this with MKMapView before.
I'd use hidden property of UIWebView - setting it to YES before view is added and clearing it to NO in webViewDidFinishLoad: should do the trick.
However, you comment to #logancautrell's answer is a bit unsettling - do you ever plan to get that many web views added to your views? I assume you know that, but just in case: depending on your possible HTML(5)/JavaScript/CSS code, you may observe severe performance hit even with a small number of web views for which iOS needs to allocate lots of resources.
If you plan to update your web views often, maybe you could benefit from UIWebView's stringByEvaluatingJavaScriptFromString: method? To some extent, the performance hit can be bearable, I think.
I suggest either pre-calculating the scroll heights somehow (not during web view load), or finding a way to display your UIViews without waiting for the scroll heights initially, and correct them later.

iPhone Memory Warning Problems with UIScrollView

I am working on an iPad app that lets the user scroll through a number of images (usually around 20 .jpg files in a single horizontal scroll view). The file sizes are around 200 kb each. The images are set as the "Background" property of a UIButton because I wanted to allow the user to click the button to save the image. Every time I run the app, it crashes after scrolling for a little while. If you don't scroll, it behaves normal. I did run the app using the performance tools and didn't find any leaks.
I am getting a "Level=1" memory warning just before the app crashes. I had it running with about 8 images in the scrollview and never had a problem. So I know it has something to do with the scrollView and the images/buttons. In the "viewDidLoad" method, I simply did the following to set up the scrollView and then linked it in Interface Builder:
[scrollView setContentSize:CGSizeMake(5722, 340)];
[scrollView setScrollEnabled:YES];
[scrollView setDelaysContentTouches:YES];
Any ideas on how to get this to work? I added the images directly to the button in Interface Builder. Would it help if I deleted the background image, and instead set the backgrounds in the "viewDidLoad" method? Any help would be appreciated.
Sounds like what you need to do is create individual cells that these images live on, that get recycled like you'd get in a tableview. I have some code which does this that you may use for your purpose, or at least give it a go anyway. Works just like a tableview.
It's available here. This does the heavy lifting for you already, in that all you need to do is create one of these, slap it in a view somewhere, and create your individual cells. Those cells will be reused as you scroll so you won't need more than N + 2 cells loaded into memory at any one time, where N is the number that fit on your screen.
as jer wrote, the problem seems to be in the recycling. Make sure to remove, release and update the content of each cell every time you get a new one in tableView:cellForRowAtIndexPath:
(I would have commented jer's post but I'm unable to do this, probably because of my limited permissions).

iPhone - subview stacking slowing down application?

As title says, I'm wondering if stacking subviews can slow down an iPhone application.
For example, I have a UIViewController, which has a view occupying the whole screen. When the user presses a button, I create a second view controller and add its view as a subview of the original VC, making the second view completely hide the first one.
Does the application have some kind of automatic optimization which would be something like "ok, I know what to draw for every pixel of the screen, I stop seeking for subviews" ?
If not, I don't think stacking 2 full-screen views can really slow down the app, but could 3, 4 or more views be problematic if they include many subviews themselves (labels, images)?
Read the View Controller Guide sections on Modal View Controllers and memory management. Prefer to use modal Views instead of subviews when you want to present a new screen temporarily and a UINavigationController for "drill-down" views.
You can always set UIView#hidden = YES on the views not seen. That should prevent redraws.
This is largely dependent of what the subviews contain and what is the total memory load of the app. Memory is very crucial for devices like iPhone and you should never keep the things which you don't require. When you are adding many subviews without releasing any, your memory requirement obviously will increase. This may slow down the app, even may crash the app. Stacking of two may not be a problem, but stacking many is not a very good design.
So the summary is you should always check the memory load of the app through instrument and always properly respond to memory warnings.

Lazy loading of subViews into a non-paging UIScrollView

I am trying to implement a filmstrip-like UIScrollView that will be populated with thumbnails of catalog pages. Selecting a thumbnail image will cause the main UIScrollView to move to the selected page. The Catalog may contain 100 - 200 pages, and I want to load them lazily only when required.
I have done this in a UIScrollView with paging enabled, but haven't seen anything on the best way to do this in a non-paging scenario. There will be 6 thumbnails visible in the UIScrollView (+ 1 when the view is being scrolled) at any one time. I want to dequeue and reuse the thumbnail's UIView when the view is scrolled, as I am doing in the main UIScrollView (which is a paging scroll view).
Thanks -
Jk
I am also going to suggest you take a look at some sample code of Apple, that is, Photo Scroller. If you are a registered iOS developer, you should also take a look at the WWDC10 session about scroll views in iPhone applications.
http://developer.apple.com/library/ios/#samplecode/PhotoScroller/Listings/main_m.html
What you need to do is mimic the behavior of a table view (which is nothing more than a subclass of UIScrollView). What you should mimic is the reuse of the cells. It is pretty easy to implement and will dramatically reduce the memory foot print of your application since you only load the content that is currently visible in the scroll view.
I hope this helps.
Check out the scrollview suite sample code from apple. The tiled example can probably be repurposed very easily.
http://developer.apple.com/library/ios/#samplecode/ScrollViewSuite/
Check out this class..it may proove helpful..
VSScroller

UIScrollView vs. UITableView

For a vertical scroller are there any advantages to using UIScrollView over UITableView?
I ask because I am currently using two vertical UIScrollViews with UIImageViews inside of them and am having memory issues and poor scrolling performance. I am not doing much with the scrollers, only highlighting images as they scroll into the center of the scrollviews and adding a delete button above an image if the user wants to remove it. I've started to look at lazy image loading/reuse and it seems that most of these issues have already been resolved in the UITableView class, so I'm wondering if there's any reason to stick with UIScrollView?
You should be able to use a UIScrolLView with no problem if you just, like you said, lazy load the controllers, when scrolling (assuming your views are full size) you dont need to have more than 3 views loaded at any one time, all you need is the current view, the view that goes behind it and infront of it, as you scroll your view you can unload and load the appropriate views. You should look into Page Control sample application, it does exactly this and you can pretty much get all the lazy loading code from there. Link is here https://developer.apple.com/iphone/library/samplecode/PageControl/index.html