App like default photo browser in iphone? - iphone

i am developing a app which contains feature like default photo browser in iphone. I done some what similar to that. but after loading some(near about 10-15) images from remote server,i am receiving memory warning.My requirement is loading image one by one. For this, on scroll view i am putting an images and increasing the contentSize of scroll view. it will work fine. but due to memory warning app quite.
Guys, any have any idea to approach for this feature which work similar to photo app without problem?
thanks in advance .

You're running out of memory because you're keeping the data for 10 or more images in memory at one time. You need to have more logic in your code that not only preloads and increases the scroll view's content size, but also removes UIImageViews from the scrollview (and thus from memory) as the user scrolls to newer stuff. (You can also save "evicted" images to the cache area on disk so if the users scrolls back you don't have to go to the server again.)

If you use a UITableView, it will request the images only when needed, and will automatically purge off-screen cells to save memory. It may not fit into the aesthetic for your application, though.

Related

How to load images with high Res in UIscrollView

Can anybody tell me how to load or set images with high resolutions in UIScrollVIew .
I am getting memory warning and app is getting crashed without any stack trace.
Thank you in advanced.
I was also working on an app which had UIScrollView and had to request for High Resolution Images. The thing is, you should first check the size of the images being downloaded. Lets say, if the image size is more than 10MB, then it would be difficult for your app to survive with such a heavy load.
You can consider the following methodologies.
1.Download your images and compress them.
2.At a particular instance of time, there is no need to populate your Scroll Views array with all the images at once, instead try to have only three images,i.e
1.The current one which is being shown.
2.The previous one.
3.and the image next to the current one.
You can also take help from the link
http://www.raywenderlich.com/10518/how-to-use-uiscrollview-to-scroll-and-zoom-content
You should use the concept of lazy loading. As you said you used UIScrollView that's mean you have lot's of images and I guess you show them one by one or two or three at a time. Load only that images which are visible to the user. One more thing you have to maintain that is when user swipe to next image or next branch of images that's mean next image(s) that's are going to visible to the user. At that time before load the new images release all the previously loaded images from memory. I hope it'll solve your problem.
If you are trying to create multiple UIImageView of high resolution image inside UIScrollView, then it will create memory warning and application will crash.
I will suggest you to try reusable UIImageView , like create 3 UIImageView and replace images in it.
Try circular scrollview.link or UICollectionView

iPhone, Store Loads of Photos?

In my app I have a bit where the user can take a photo and it get dropped into a list and the user could technically forever keep adding photos.
So what is the best way of saving, storing and loading the photos the user takes? Taking into account, there could be hundreds. Also, loading them all in at once might not be a smart idea as well, but say have a scroll view, scroll down, and when hitting the bottom it could load say 20 more and then another 20, etc.
Any help, much appreciated, thanks.
Just decide where you want to store the photos, built-in photo library or apps documents folder or both (I'd go with photo library for users's convenience in watching, deleting, synchronizing etc.). If you choose documents folder, don't forget to support deleting ... Disk space is the users problem.
If you choose only to store in photos library and want access the photos later from within the app, you have to save the urls of the saved images. This answer tells you how it works.
Loading the photos in scroll view will need some optimization, i.e. it wouldn't be a good idea to load all photos in memory, but only the visible ones. As another answer says, the re-use of cell in UITableView could be a solution, but I think, UITableView is for the typical iPhone table, adjusting and customizing it and its UITableViewCells isn't worth it, if the only reason is memory usage.
I'd go with UIScrollView and react upon the delegate's methods to load new content and drop old one. If you want a non-paging UIScrollView you should use scrollViewDidScroll , which is fired really often, so maybe there will be need for another optimization - test it. A paging UIScrollView seems to be easier to me. Just react on scrollViewDidEndDecelerating for loading and dropping content.
Hope that helps.
use tableview, it will load it manages the memory and jst visible rows are loaded into memory if u use dequecell method
read tableview more here
http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableView_Class/Reference/Reference.html

ScrollView as PhotoViewer, load Images only if needed

I would like to create a PhotoViewer for an iPhone.
For that, I already created a ScrollView with Paging enabled in that I add programmically add the UIImageViews. The problem I see is, that if I would have like 100 Images and I would all add to the ScrollView it would take alot of performance and memory.
How would you make it more performant? I thought about loading the Images of the following 2 pages and releasing the Images after the 2 Images before when scrolling through the pages.
I thought about creating a Subclass of UIScrollView and to name it UIPhotoScroller (or something like that). But I also want to show a UIView in the MainWindow with Information about the Images. Is it possible to make the UIView visible from the Subclass?
You really would help me with that. Thank you in advance :D
Create an NSCache.
When you need a particular image, try to get it from the cache. If it's not there, load it from disk and save it in the cache. The filename is a suitable key.
When you get a memory warning, tell the cache to empty itself.
The cache will release some of its entries periodically, depending on how it's configured. This is a good thing, but you might want to adjust it to have a particular total memory size. Tweak its parameters until it behaves like you want it to. To see your memory usage, use Instruments.
How about doing a UITableView with a single photo per cell. When a cell is being request by the data source, you display a spinner and have a queued NSOperation load the image and refresh the row when done.
You can control the amount of concurrent ops with a NSQueue, so you have complete control on performace/responsiveness. You can then remove old cached images when low on memory/paging, etc.
There are solutions to horizontal UITableView if you need horizontal scrolling.
Have you looked at the three20 library? There's an example of creating a great Photos app-like viewer of photos, and it's pretty easy to work with the three20 library.
Hope this helps!

iPhone memory management, making my app crashproof for multiple devices

I'm developing an app which uses a UIScrollView to show a list of images based on search criteria. Using a button the user can load more images.
When testing on an iPhone 4 the ViewController receives a memory-warning at ~750 images. When testing on an iPod 2nd generation a memory warning is received at ~150 images.
My understanding is that when didReceiveMemoryWarning is called, one can free memory by releasing objects but recovery from low memory is not guaranteed.
I've implemented didReceiveMemoryWarning and release basically all objects. In instruments I see memory usage drop back to ~3MB. The first time the iPod reaches its memory limit all goes well, memory is released and the app resumes normal operation. The second time however, when didReceiveMemoryWarning is called, I can see the objects released, but the app crashes anyway.
So, how do I make my app crash proof? I want to make sure that all devices running the app can load as much images as memory allows but I also want to make sure that the app doesn't crash.
I would prefer the app never to reach didReceiveMemoryWarning and set a limit to the number of images that can be displayed, but how can I determine how many images each possible device should be able to load?
Furthermore, the size of the images is not guaranteed. While testing I come to this arbitrary number of 150 on an iPod, but what if the images on the server at some point in time are twice as big? Then the app would probably crash at 75 images.
Any sugestions?
First off, what you probably want to do is not display all your images all at once. You rather, probably only want to disable the images that are currently visible, plus a few that are off screen preloaded for when the user scrolls to that location.
This is much the same way as the photos app works, how UITableView is implemented. Basically it boils down to this:
You have your main scrollview, and inside it, you have individual cells. These cells are small views that are added as subviews to your scrollview at specific offsets. You then add your images to these cells.
When a user scrolls the scrollview, you first ask the scrollview to dequeue a new cell for you, much the same way you'd ask a table view to dequeue a cell for you to use. This saves the cost of an allocation, if one has been recycled. If you cannot dequeue one from a recycled set, then what you have to do is quite simple: allocate one as you are doing currently.
Furthermore, to implement this cell recycling, what you need to do is see which cells are visible on screen. If one or more cells go off screen, you add them to the recycled cells NSSet which you create. This set just holds cells for later recycling. There's some sample code Apple has which demonstrates this, and it's called PhotoScroller. It also is demonstrated in a WWDC10 video, session 104. I suggest you watch it. Ignore the parts about tiling, you don't need to know that for your purpose.
Once you have this in place, this will force you to set up your cells only when they're needed, which is also another key aspect of this behaviour.
Finally, when you do receive a memory warning, just drop the recycled cells set. If you ever get high enough that this matters, that is, you'll save a few megs of memory. :) (Do not forget to implement it though, ever, when you hold onto temporary data that you don't specifically need around...cells which are not visible on the screen are a good example of this, as are caches.)
You should lazy load your images and only load the images you need at that time. Your app can't show all those images on one screen anyways, so on your scrollview you should only load those images that can fit on the screen and maybe a few around that, and as the user scrolls to release the images it no longer needs.

iPhone: Reading many images quickly

I've got an app I'm working on where we handle a LOT of images at once in a scrollview. (Here's how it looks, each blue block being in image on a scrollview expanding to the right: http://i.stack.imgur.com/o7lFx.png) So to be able to handle the large strain doing this puts on memory. So I've implemented a bunch of techniques such as reusing imageviews etc which have all worked quite successfully in keeping my memory usage down. Another thing I do is instead of keeping the actual image in memory (which I of course couldn't do for all of them because that would run out of memory very quickly) I only keep the image's filepath in memory and then read the image when the user scrolls to an area of the scroll view near that image. However, although this is memory efficient, it's causing a LOT of lag in the scrollview because of the fact that it has to constantly read images from the disk. I can't think of a good solution on how to fix this. Basically right now the app draws to the screen only the visible uiimageviews and while the user scrolls the app will look to see if it can dequeue another imageview so it doesn't have to allocate another one and at that point it reads the image into memory, but as I said it's causing the scrolling action to be very slow. Any ideas on a strategy to use to fix this? Does anyone know what the native photos app does to handle this kind of thing? Thanks so much!
I can suggest you a simple solution to balance both the memory and the computer processing. You only keep small images like thumbnails in memory and only keep about 20 of them. One project that I am doing, I keep 20 thumbnail images (100 x 100) recently accessed, which doesn't cost a lot of memory. I believe that it costs about 200 kb all the time but comparing to a general available memory. I think it is good enough.
It also depends on your use case : if user scroll really fast and you don't know when will they go. You can have even smaller images than the thumnail and when you show it on the UIImageView, you resize it to fit. When user stops scrolling for a while. You can start loading bigger images and then you have a nicer images. User may not even notice about the process
I don't think there is a solution that can be fast and using as less memory as possible. Because we have memory, maybe not big but have enough if we use it smartly.
Slow scrolling performance might mean that you're blocking the main thread while loading images. In that case, the scrolling animation won't continue until the images are loaded, which would indeed cause pretty choppy scrolling performance.
It would be better to lazily load requested images in the background, while the main thread continues to handle the scrolling animation. A library that provides this functionality (among other things) is the 'three20' library. See the Tidbits document, and scroll down to the bottom where the 'TTImageView' class is described.
I had a similar issue with a PDF viewer, The recommended way to do this is to have as low a res image as you can get away with and if you are allowing the user to blow the image up/zoom, then have two versions or three versions of that image increasing the res as you go.
Put as much code as you can get away with in the didDecelerate method (like loading in higher res images like vodkhang talks about), rather than processing loads in didScroll. Recycle Views out of scope as you have said. and beware of autoreleased Context based Image Creation functions.
Load images in on background threads intelligently (based on the scrollView Offset position and zoom level), and think about using CALayer/Tiled Layer drawing for larger images.
Three20 (an open source iOs lib) has a great Photo Viewer that can be subclassed, it has thumbnail navigation, large image paging, caching and gestures right out of the box.