I am working on a photo gallery app. Root view is a navigation controller which takes the user to the thumbnail view. Tapping any thumbnail takes the user to PhotoView which shows the tapped image in full screen.
Below is what I have done in my PhotoViewController:
The approach is pretty much similar to the ScrollingMadness project which I found at github.
I initialize a UIScrollView and add it as a subView to my view controller's view. Set some basic properties of UIScrollView.
Add images to UIImageViews (5 in numbers).
Add all these imageViews as a subview to UIScrollView.
When zoom operation is performed on any image, all the image subviews but the current one are removed from the scroll view.
When the image zooms out back to the minimum scale, all the images are added back to the UIScrollView.
As explained in the sample code from Apple, I am using TapDetectingImageView delegate to create the imageViews and handling touch events.
When I run the app, everything works fine in simulator. No issues whatsoever. But when I run the app in device, it crashes after I scroll to 3rd or 4th image. While debugging I found out that didReceiveMemory warning is called after I scroll to 3rd or 4th image.
I run the app using Instruments. The object allocations shows allocation levels to only 1.5-2MB when the crash happens. I believe memory usage to this level is very normal ... right?
Anyone who experienced this before OR any input as to how I can get rid of it... would be all the help I need in world at this time.
Let me know in case you need any other info.
PS > Its frustrating to see the whole app perfect in simulator but crashing in the device :(
It is crashing because its running out of memory, one thing you should check is the size of the pictures, are you picking the image from the photo library w/o editing, sometimes this will give u images of resolution of 1600x1400 which will pretty much just crash the phone because it runs out of memory, for this you should just resize your images to smaller ones. Another problem that could be causing it is you are loading too many images at once (i dont think so though), if you are using t he scroll view to have a scrolling similar to the photo application on the Iphone then you should only need to load 3 images at a time. Also maybe you arent r eleasing the images properly when you are zooming . I dont know if you a re trying to accomplish a similar functionality to the scrolling of pictures in the photo app on iphone, if you are look at the sample project PageControl, they illustrate that pretty well there.
Related
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).
I have a simple tabbar app. Built directly from the tabbar template. As I test the app, I notice that the app sometimes crash. After pinpointing the right sequence, I found out that the app will crash if I do this:
Run app. Open the view that has a UIPickerView on it.
Open another view.
Tap home button (this will send the app to background).
Tap the app icon again to bring it at the front.
Tap the view that has the UIPickerView in it.
Crash!
Checking the console shows:
-[UIPickerView setFrame:]: invalid height value 130.0 pinned to 162.0
The UIPickerView I use is a custom size. I use transform of scale 0.8f on the height. So if you calculate 0.8*162.0 is indeed 129.9f (130 as mentioned by the console).
I have no idea how to fix this. Any ideas?
The problem is solved. It seems when the app goes to the background, UIPickerView needs to find its components resources again. It is not about sizing of UIPickerView at all.
I used images for the UIPickerView components, so after I populate the UIPickerView with these images, I released all the images that were allocated earlier. These images must not be released if it were to work in iOS4.
Only release them when the app ends.
Your problem has been fixed by another guy with a radical approach. See this post'sanswer provided by a guy named bhavinb.
I have a tabBar in my application. In one of the section i have two views which i toggle between using segment buttons.
In one of the view i have MapView which i use to display list of users using their pic as annotation. On the other view i have tableView which shows the same users in table format.
Now everything is working fine, i am getting all the users and it displays fine on the map. It works perfectly most of the time on all device and all iOS but sometimes when i bring the mapView to front or toggle or try to zoom in. Both the views (tableView and mapView) just gets removed somehow and i see black screen (which is btw my superview so thats not a problem).
Does anyone know why this happens. It happens frequently on iPhone 3G the older iPhone.
Thanx for any help.
I've had the same problem. I think it's due to low memory to which your app responds by deallocating the tableView and mapView. My solution was to have both views allocated in viewDidLoad. I'm not 100% sure about this, but you could give it a try.
I noticed some iPhone apps give you the title screen instantly.
Then there are some apps that gives you a black/blank screen for a brief moment.
I have the latter issue, but its lasting about 2 seconds.
I would like to display a PNG image (over 200 KB size) and a loading indicator view.
My app is based on UIView. The specified a custom UIView that basically loads and renders the said image as the wallpaper.
I tried not loading this image, yet im still getting a 2 second delay time to load.
The app delegate basically sets the view controller's view as a subview.
This delay is only seen on the device, not on the simulator.
What am i over-seeing?
If you place a Default.png file in your mainbundle, it gets displayed at launch time between the time that the app is tapped on till the time that you replace it with another view.
The reason you don't see it in the simulator is because it is faster at loading your app.
If you want to display a progress indicator, you will only be able to do it once the appDidFinishLaunching is called, but the delay that you are seeing is still there.
One trick I use is to have the same Default.png displayed again in appDidFinishLaunching and then draw a progress bar on top of that. Sure there is still the static display during the initial delay, but from there until all my initial views are loaded, I display a progress bar.
There have been some recent discussions about this on StackOverflow that you should see. And see this: How To Make Your iPhone App Launch Faster
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.