Zooming out for the first time in UIScrollView is not smooth - iphone

I created UIScrollView and added UIView with lots of tiled UIButtons in the UIView. My problem is, when every time I zoom out the content using zoomToRect method of UIScrollView to the minimum scale I set, the zooming out is not smooth. But zoom-in and zoom-out for the second time is smooth. How can I make the zooming out for the first time to smooth zooming?
Thanks.

The slow initial zoom is obviously due to the phone allocating all the UIButtons the first time it has to draw them. They should be allocated incrementally or before the user starts to interact with them.
What are you doing that requires so much loading and drawing? It doesn't sound like the user would be able to interact with the million or so buttons they might be viewing.
I would suggest adding a pile of code to a UIScrollView Sub Class that makes it aware of it's content size, and it can then init the required UIButtons before the user starts to interact with your UIScrollview, or incrementally as I said.
There is demo code called 'Tiling' that sheds some light on using UIScrollViews to manage large content. It's quite complex, but a very complete demo that I'm sure most projects implement if they handle UIScrollViews with tiled content.

Before zoom out set your UIScrollView* scrollView like:
scrollView.contentInset = UIEdgeInsetsMake(0,0,0,0);

Related

UIScrollView pinch zoom into CGContextStrokePath without changing line width

I have a UIScrollView that contains a custom UIView. In my UIView I am overriding drawRect to draw a path using CGContextStrokePath. I would like to slightly alter the way the zoom works. Pinch zooming out will show more of the paths on the screen. This is what I want but i want the line width to stay the same not shrink as you zoom out so that they are still clear to the user.
I thought I would just do this (myUIView zoom target is called _lineView)
-(void)scrollViewDidZoom:(UIScrollView *)pScrollView
{
_lineView.zoomScale = _scrollView.zoomScale;
[_lineView setNeedsDisplay];
}
and then just calculate an appropriate line stroke size in my _lineView drawRect method to give the effect of constant line width as you zoom out.
This is really slow and I have read that this is expected as drawrect is not optimised to be called many times a second.
I then started looking at using a GLKView instead and just rendering the whole thing in opengl directly. The problem with this is I will have to implement all of the zooming and panning myself (with all the lovely zoom and pan bounce effects you get for free in UiScrollView). I will also have to implement all the controls I want to use in opengl, buttons etc.
Is there a way to do this whilst still using Quartz2d? I feel like opengl will give me lots of power but it will take me much longer to get the rest of my app done if I go down that route.
I figured this out. I found a simple way to do this that does not slow down the zoom / bouncing animations at all and is very fast and fluid.
Quartz has a class called CAShapeLayer that lets you do some pretty cool stuff. Among these is being able to set a CGPath property and specify a linewidth. Changes are reflected in the view.
So i basically call shapeLayer.lineWidth from my scrollViewDidZoom method and it does exactly what i need.
What I would do if I were you is to use default zooming behavior while zooming (which does not redraw, but instead just applies a transform to the zoomed view, which can be done by the GPU very, very quickly, but as you have noticed can lead to inferior quality).
Then, when the user finished zooming, redraw the whole view as you do now. The appropriate delegate method is scrollViewDidEndZooming:withView:atScale:.
This way, you have fast (but slightly ugly) zooming, and nice (but slightly, probably unnoticeably, slower) display after the zoom is finished.

UIScrollView lags on iPhone

I'm trying to create a crossword app. The game runs in a UIScrollView, because the player should be able to zoom, scroll etc. The largest crossword are 21x21 which means there need to be 441 touchable tiles. What i've tried so far were to create an UIView and added it as a subView to the UIScrollView. Then I call a method that creates 441 custom UIButtons and set the backgroundImage.
Some of the UIButtons need to have a custom label overlay, so i added a UILabel and set it on top of the UIButton.
When I run the app in simulator all works as it should, but when i test it on an iPhone 4 the UIScrollView lags a lot.
I don't know if this the way to do it? Can you maybe try to guide me in the right direction of how to do this so the UIScrollView won't lag on a device.
Thanks in advance.
Big UIScrollViews are difficult to make smooth without some sort of caching mechanism, such as the one provided by UITableView.
One thing you can do, however, to make life easier for your rendering, is to make sure to use opaque backgrounds whenever possible. In stead of making a view transparent you should make it the same color as its underlying view. This is something that does help.
Also, I have experienced better performance using imageWithContentsOfFile: in stead of imageNamed: for initializing images to be used in a UIScrollView.
In order to not keep all those buttons in memory, you should work with reusable table view cells, this will really improve the scroll performance. Here's one component that could make your life easier: DTGridView, there are also others (you can check Cocoa Controls)

iOS zoom algorithm

I am creating a graphing calculator application in OpenGL on iOS, and I would like to implement pinch zooming that works like the google maps application or uiscrollview zooming. I'm pretty sure I can't use a uiscrollview because the content of the graph is being generated dynamically.
Implementing zooming where the center of the screen is assumed to be the center of the zoom is easy, but in other cases it is not obvious to me how its being implemented. Can anyone point me in the right direction?
The view that does your custom drawing should be capable of drawing at a certain scale. When your user zooms in or out of the scroll view, send the appropriate zoom factor and let the view redraw itself. The changing bounds is not a problem. The scroll view adjusts its bounds as you pan inside, so its subviews shouldn't have any concern over the bounds of the scroll view.
Of course, you'll probably have to consider performance. For example, it may be too slow to redraw the graph at every frame as a user zooms. Instead, you may only want to redraw when the user stops zooming, which is what Maps.app does.
There are many other considerations for this problem, but that would be where I would start.
EDIT: Ah, I overlooked the OpenGL aspect. Still, with a GL layer-backed view, you still should be able to make the appropriate translations based on both the current zoom factor as well as the scroll view's bounds.

Zooming in UIScrollView is not smooth

I created a minesweeper clone game in iphone. My implementaion of the cells in the grid is this, I created a UIView and added buttons in the UIView and then I added the UIView in a UIScrollView, but every time I zoom out or zoom in using zoomToRect method of UIScrollView the zooming is not smooth and the zoom out was distorted. How can implement smooth zooming in UIScrollView?
I would try rendering your content view into a bitmap image when scrolling or zooming begins, and replacing the large grid of buttons with the bitmap until the scrolling/zooming is completed. The UIScrollViewDelegate protocol should provide you with the necessary information to know when to swap the bitmap in or out. Part of the problem is that your content view is so computationally intensive to render (all those buttons).
A more sophisticated approach would be to re-implement your game grid at a lower level using coreanimation and more fundamental touch event handling, but that might be overkill if the bitmap hack works well enough.
You know how in the maps app, while panning or zooming, there are grey tiles that show up? That means that the iPhone is currently downloading the tiles. In Safari, there is a similar effect where Safari lays down checkered grey instead of webpage, as it is currently rendering it and will be just a moment. Both of these mean that scrolling will not wait for content to load before displaying the area, it will let scrolling be smooth.
You could try looking here [http://stackoverflow.com/questions/1098234/optimized-image-loading-in-a-uiscrollview] for some ideas, and a point in the right direction would be to use threading to load views in the background while displaying grey in its place.

uiview Transition problem

i have a UIview holding two other UIviews. that two subviews having 15 buttons and images. i have to translate the parent view. but the translation is not smooth in 3g phone. im using UIviewanimation and CGAffineTransformTranslate for translating the view. please help me for making it more smoother.
This is a though question to answer in a general way. I have had views that scrolled smoothly suddenly animating jerkily after just a small change. In short, you need to make sure to have as few subviews as possible and have as few non-opaque views as possible (pngs with alpha values translates to non-opaque UIImageViews).
If all else fails, you can render the whole view into an image, switch out the view for the image just before scrolling, and then re-insert the view again after the animation. That way, you are only moving one big and (hopefully) opaque view.
If you have many images make sure they are small-sized, otherwise theyd take up too much memory and there would be nothing to do. To my experience 4-5 large images(740-480) were too much for the phone to handle.