UIImageView in UIScrollView - iphone

I have a series of UIImageViews in a UIScrollView. The user can zoom into each one, but after a bit of usage the images start disappearing, and then various images in the app disappear. I'm wondering if anybody has any any experience with this and has any idea why this could be happening?

Its a complete guess until you give us source, but chances are that you are doing something like not retaining your image views or are adding them to another view – effectively removing them from the first view they were in.

Related

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).

Do I need to remove subviews that aren't visible in UIScrollView to keep it running smoothly?

I'm working on making a special UIScrollView to show a timeline of events, (Like a gantt chart if you're familiar with such things) and there could potentially be dozens of these events, some visible and some not at different times.
What I'm wondering is this: should I make an implementation similar to UITableView to remove the items that have scrolled out of sight, and reuse the views for other items as they come into the screen?
It seems like it could take some work, and I don't want to waste time on it if this isn't something that will affect performance on a small scale.
I'm getting the idea from the UIScrollView class reference:
"The object that manages the drawing of content displayed in a scroll view should tile the content’s subviews so that no view exceeds the size of the screen. As users scroll in the scroll view, this object should add and remove subviews as necessary."
Thanks for any help.
It depends on how much memory each item in the scrollview requires. You cant really tell unless you build it or provide more information about exact amounts and what each element in the UIScrollview contains. Removing items that are not visible is not a massive job but it can have some problems. I would first try it without removing them and optimise the elements that you add to the scrollview so they use as little memory as possible and then use instruments to check your mem usage. Then go from there. Hope that helps.

Mini Scrollbar with thumbnails on iphone

I was wondering, what would be the best way, to implement an 'extra' scrollbar, showing thumbnail versions of the pages, you are currently viewing.
In my case, I would like to have maybe around 20 images, which I would animate with Cover Flow Layers and while I 'scroll' up an down to view them, a scrollbar appears at the side, showing the smaller thumbnail versions of all the pages while the thumbnail currently visible is rendered slightly highlighted.
Is there anything specific I need to keep in mind? Thanks in advance for any ideas!
You are not giving much info to work with:)
Build a UIScrollView and a UIView, stick all the thumbnails into the UIView, stick the UIView into the UIScrollView.
If you have a lot of images, consider loading them in as "dummies/blank image" and have an NSOperation load them in the background. Consider releasing images that are outside of the screen, so that if 3-7 is on the screen then you only load in 2-8 and release everything else.
Regarding the logistics of it:
Build a viewController for holding everything. Then build a thumbnail viewController "component" that has a delegate method for setting the "displayed" image and maybe one for scroll and click.
Build a FullSize viewController component for handling the full size images. Have that also implement some delegate methods to communicate to the top most viewController. Add the two components to the top viewController, hook up the logic and you are done.
Make sure there exists only one model array/dictionary in the top most viewController and "feed" that downwards to the thumbnail and fullsize viewController, when some one clicks or scrolls, inform the top most viewController and have that update the other viewController.
Was that the kind of answers you were looking for?
:)

how to add more than 100 uiimageviews in uiscrollview

i have an uiscrollview and i add one by one uiimageviews but when i add more than 40 objects i have problem with memory i guess and the app crashes...what should i do? i am trying to make an app like photo viewer from apple! Help please!
i do not want thumbnais i just want to show the next image when the user flick from one to another but i have to unload the previous image and show the next one
i remove the previous like this
UIImageView l;
l=[[scroll subviews] objectAtIndex:0];
[l removeFromSuperview];
l=nil;
and then i add the next one like this
[scroll insertSubview:imageView atIndex:counter];
but i see a black background no image
please help!
The best way to do this is to load a few of the images at a time into a table view. In each cell of the table, put three thumbnails. You'll need to make a custom cell. That way, the table cells will be de-queued and the memory re-used. Check the Facebook Three20 project, I think they've implemented it like this, so you'll have some code to work with.
http://joehewitt.com/post/the-three20-project/
Ask yourself, do you really need to load all 100 images into memory? Why not just load a few images at a time in the background, depending on what image the user has scrolled to?
Don't do it that way.
If you want to display a 100 small thumbnails, resize them first with core graphics. Then they take up much less memory when you display 100 images at once.
If you want to display a 100 large images but only one is visible at a time, have 1 or 2 image views that load up the current and next images, and animate them in a clever way to make it look an endless stream. You can still use a scrollView, just monitor it's position and position your image views appropriately.
There is exactly an apple sample code that do what you want. Look for the PageControl sample, it is already implemented. Basically the slider gets the image controller from an array of controllers; among other things, when the scroller changes to the previous or next image, controllers are added and removed from this array dynamically to keep memory footprint low.
Have a look at the sample code, it is quite simple.
Hope it helps.

Adding UiImageView to UiScrollView one at a time... but how?

My problem is that my 300 images are being added to UiScrollView and shows up after it's done finishing with addsubview: calls.
How do I set it up so that it adds a subview, who's up on the Screen .. and continue adding ?
You could add to UIScrollView only first couple of pictures that fit the screen and then add others on request, when user scrolls you have to check bounds and add new image if it would be displayed.
I'm not sure about the code details though.
I know for a sure that UIScrollView with 3 images are shown in demo in the lecture 8 (including source code) at Stanford's CS193P course about iPhone development, the presenter (a guy from Apple) mentioned in the video (on iTunesU) that you could load up on demand other images - he just gave general pointers not the actual solution.
But if you need to display screen full of icon size images (kind of like iphone image library) maybe it would be better to try UITableView (I haven't used it for that purpose yet but give it a try).
stefanB's answer is a good one. For the code details, I'd suggest you take a look at - [UIView drawRect:]. Given the size of each of your rows, you can easily calculate when the passed rect represents a new cell being brought into view due to a scroll, and then update with the new image accordingly.
Have you thought about putting your images not in a UIScrollView, but in a UITableView and having that handle all the caching and lazy loading for you? It sounds more specialized to handle what you'd like to do.