How to show fullsize images in scroll view? - ios

My application suppose to show images in full screen and i have lots of images in my list(more than 500 images).
I'm adding image view in scroll view with horizontal scrolling and paging. But I'm facing memory issues as loaded images will eat my device memory?
What is the best way to load images.

Don't attempt to use a vanilla UIScrollView to show a ton of content, especially if you're just going to dump it all in at load-time. As you've seen, that will inevitably crash due to memory pressure.
At a minimum use UICollectionView, which will at least reuse cells and allow a minimum of assets to be in memory at one time. However, the problem of a smooth, low-memory photo collection view is one that many apps encounter, and can have a lot of implementation gotchas. I recommend looking for a well-built component rather than trying to reinvent that particular wheel.

Related

Loaded 50+ images from document directory in UIScrollview app get crash

Loaded 50+ images from document directory in UIScrollview app get the crash.Getting " Connection to assets was interrupted or assets died (with memory warnings)". Can anyone suggest best way to load these images? Thanks in advance. My code is in Objective-C.
The best option for displaying Images in your case would be using a UITableView or UICollectionView because they internally dequeue cells when they are no longer displayed on the screen.
.
In your case the UIScrollView does not dequeue its subviews, thus the screen contains the images all the time which consumes more amount of memory and the operating system closes (crashes) your app due to heavy memory usage.
You should use UITableView instead of UIScrollView.
But if they are very large images, it would crash when just load one image, unless it be preprocessed (resized).

Displaying multiple images causes massive memory usage

I have an app that allows a user to go into their gallery and select photos from their photo library to add to the app, it is displayed in a tableview
This is then added to an array which after UIImagePickerController fetches the image, reloads the collection view with the new images.
My problem is that this uses large amounts of memory. I need a way to display the photos added exactly like the native photos app on the iPhone.
I've looked in lazy loading but I have no idea where to begin.
Could someone please tell how I would go about displaying images in a UICollectionView with lazy loading, or at least reducing the amount of memory used.
The app is generally at normal use using around 10mb of memory. This increases to 50mb+ when displaying a multitude of images in the collectionView.
Thanks.
Holding high-resolution images into an array will generally be problematic. Also, using the full resolution images for thumbnail sized image views in collection view is an extravagant use of memory.
So, when the user selects an image, capture a reference to that asset's URL. Then, as images are required by cellForItemAtIndexPath, retrieve the image, resize it to thumbnail dimensions (e.g. you could use something like this) and use that in your cell's image view.
If you want to be elegant about it, implement a NSCache in which you'll cache previously resized images, but make sure you have reasonable retention rules and have that purge itself upon memory pressure. That way, cellForItemAtIndexPath can see if the image exists in its cache, and if so, use that, otherwise go back to the assets library and resize that image. But by using cache, you can speed up the process of scrolling back through images that were previously resized.
But the key is to avoid holding high resolution images in memory. And if you're going to hold even the thumbnails in memory, you might want to capture that in something like a NSCache rather than an array.

Real Memory Constantly Increasing - Removing Subviews from View - iOS (ARC)

I have an iPad app which is crashing on iPad (First model) as it is running out of memory.
In the app I have a main view which adds as subviews about 20 UIScrollViews (custom class) each containing a UIImageView and UIImage. When the user moves to the next page, I remove all these subviews from the superview and then add 20 new UIScrollViews to the same view.
If I profile the app for allocations and memory leaks everything is ok - the memory allocated stays at about 2MB while the user scrolls left and right.
However if I look at the real memory usage in the Activity Monitor I can see that every time the user moves to a new page, the real memory increases by about 20MB. Eventually after a few new pages the app size hits 150+ MB and crashes.
Can anyone suggest what might cause this type of behaviour and how I can further troubleshoot this ?
Just a bit more info on the app structure :
In view did load the images are loaded into an NSMutableArray using initWithContentsOfFile.
You should not be maintaining these images in an array. Images consume a disproportionate amount of your limited RAM. There are a couple of approaches:
If you want to keep it simple, just don't store the images anywhere. Load the image property of the UIImageView by loading the image via initWithContentsOfFile and call it a day.
If you want some RAM caching for performance reasons, you could use imageNamed instead of initWithContentsOfFile. When the app receives a memory warning, the cache will automatically be purged.
I'd be inclined to use initWithContentsOfFile, but then manually cache in my own NSCache (which is like a NSDictionary, except you can set a countLimit of how many images it should hang on to).
By the way, you don't describe what technically happens when "the user moves to the next page." If you're simply refreshing the existing controls on the existing view controller, then everything is probably fine (once you fix the NSMutableArray problem I discuss above). If you're pushing/presenting to another view controller or scrolling controls off screen but neglecting to remove the old ones from their superview, then that will also cause problems. You might want to clarify what you're doing there.
Bottom line, you just need to make sure that when you go from one page to another, that you're not maintaining strong references to any old images or controls.

How to reorganize iOS project to avoid memory issues

I am building my first project that is an interactive ebook app for the iPad
I started with the Single View App template from XCode
So far, the project is mostly a series of block animated transitions between UIImageViews and MPMovieController videos, very serial so far
Everything is coded within a single view under a single view - the image views fade in and out with alpha animations
I am beginning to run into memory issues. I've used memory instruments and see that most everything is loaded into memory at the beginning (images from the InterfaceBuilder) aside from some videos instantiated at runtime
My question is - how should I reorganize my code to better utilize memory? Should I separate into different views under one view controller, or have multiple view controllers?
And which might be the most straight forward to implement?
Images are very memory-intensive. So:
Do not load an image until you actually need it (for display). When you are done with it (the image view is no longer visible), release it (by setting that image view's image to nil). Do not maintain the images in an array or anything like that. Do not create the image views preloaded with images in advance in the nib.
When you actually need an image for display, load it in code using imageWithContentsOfFile:, not imageNamed:. Thus you prevent caching of the image.
It is a waste of memory to work with an image larger than the display size. If these images are large, you can save a lot of memory up front if you load the image at the actual size needed for display. This is easy to do with Image IO framework and CGImageSourceCreateThumbnailAtIndex.
I think you need to use multiple view controllers and separate your code in small separated views and objescts that controll you app flow..
On the one hand it's better to have multiple views and so on..but it's a pain to rewrite code you worked on (unless it's absolutely necessary).
In my opinion if you don't have anything unnecessary in memory (i.e. when you take a view off screen you release the memory it used) you don't need to do anything.
After all, even if you split the code as it should have been, if your memory management is good, it will take the exact same memory.
You should be able to do this with a single view controller:
Load your images lazily from code. Keep an array of the image names rather than the images themselves, and load them just before you need them.
Make sure your images aren't larger than they need to be.
Recycle your image views. If the user won't see more than two image views at a time (including both the from and to in a transition), you should only have two image views.
Don't worry about whether the images are cached; iOS's caches are designed to release their contents under stress. That said, do not implement your own caching system. You might not release images properly under stress. If you need caching, use NSCache.

UIScrollView: Bad performance with large images

TL:DR
What technique does Apple use to make Photo.app so fast, even with large images?
Long Version
I watched Apple's WWDC 2010 video about scroll views to learn how to replicate Photo.app pagination behavior and low memory utilization (PhotoScroller Demo). It works well, but since images are loaded only when they are needed, when I try to paginate to another image, the app locks while the JPEG is being decompressed.
The same video shows a tiling technique to get better performance, but since I'm using photos taken from the camera and stored in the app, that doesn't seem feasible (having multiple copies of each photo, in different resolutions, would consume too much space - 4MB vs 27MB). Also, using iExplorer I noticed Photo.apps has only a copy of each photo (it doesn't even have a small thumbnail copy for the gallery).
What technique did Apple use to make Photos.app so fast? How can I get that same performance in my app?
I'm a bit confused if this should be here or on Programmers,
since there's no code in the question, but F.A.Q. says that algorithm
questions are part of Stackoverflow, and the tags here match it
better.
So if you just show one image fullscreen you can do this:
In the WWDC11 Session 104 - Advanced Scroll View Techniques they talk about infinite scrolling and how to do it. The basic idea is to scroll the view and after scrolling reposition the (UIImage)view inside the scroll view so it appears centered or whatever you layout constraints are.You could then load the new UIImage into the UIImageView. Since you only have one UIImageView it should be pretty low memory consuming. I am not sure about how the loading times of the images will behave though.
Maybe preload the next UIImage to the left and right to the current image and then load it into the UIImageView after reposition the scrollView can help here.
For anyone who is still looking for simply implementation of scroll view that hold lot's of images.
https://github.com/sumofighter666/ReusableScrollView
It is as simply as implementing UITableView

Resources