Understanding UIScrollView - iphone

I'm trying to understand how UIScrollView works for zooming.
I was trying to rotate a UIImageView within a zoomed UIScrollView and I ended up with weird sizes, my centering in the scrollview not working anymore.
I solved the problem by setting the zoomScale to 1.0 before doing the rotation, and then by resetting it back to the previous value once the transformation was done.
I was wondering what was the impact of the UIScrollView on its subviews. Does it change their sizes, their positions. Or is it simply the UIScrollView that handles the zooming and the drawing of the zoomed subviews.

I realise that is an old question, but I thought I'd add additional information for those still arriving here like myself.
The scroll view manages its contents view, it zooms by adding tranformations to the content. So, for an image when you zoom in, it uses a tranformation to scale the image to the required zoom level.
When you are panning/scrolling a ScrollView, it changes the zoom level and origin positions to move the content around. So the content may well be larger than the scrollview itself. It clips the content at the scrollviews bounds and just adjusts this origin position.
The central notion of a UIScrollView object (or, simply, a scroll view) is that it is a view whose origin is adjustable over the content view. It clips the content to its frame, which generally (but not necessarily) coincides with that of the application’s main window. A scroll view tracks the movements of fingers and adjusts the origin accordingly. The view that is showing its content “through” the scroll view draws that portion of itself based on the new origin, which is pinned to an offset in the content view. The scroll view itself does no drawing except for displaying vertical and horizontal scroll indicators. The scroll view must know the size of the content view so it knows when to stop scrolling; by default, it “bounces” back when scrolling exceeds the bounds of the content.
Source Documentation

Related

iOS How to get the content offset of a view inside a scrollview

Lets say I add 10 views to a scrollview. I obviously give them a rect inside of the scrollview. Is there any way to figure out what each item's offset is in the scrollview?
I'm guessing that probably isn't applicable here. What I need in essence is, "If this item is at this content offset in the scrollview (meaning visible to the user in a certain area of the scrollview), then do this".
Each view's frame is expressed in its superview coordinate system (bounds). That is, in your case for each view its content offset is CGRectGetMinY(view.frame).
You might want to find the current scroll position by looking at UIScrollView contentOffset
The point at which the origin of the content view is offset from the origin of the scroll view.
With the contentOffset, you can then compare this with the frame x and y coordinates of the content views and determine if they are onscreen or not.

UIScrollView change pages after animation

Ok, I have a complicated scenario here. I have a scrollview which scrolls horizontally and contains tiles, 1 centered on the screen at a time with the user still able to see if there are more to the left or right by way of having the edges of the 2 views visible on either side. I am able to add the views programmatically to the scrollview and have paging work properly, so the user can swipe back and forth between them. Another requirement is to have an initial animation where the first view slides in, then is bounced off to the left by the second view. I accomplished this by using a series of UIView animations, and it works well.
Here is my problem: After the animation completes, you cannot scroll left to get to the first UIView that was created. I suspect that this is because it was animated out to the left of the content area of the scrollview. I have tried to increase the contentSize of the scrollview, but I still get the same behavior.Once the initial scrollview has been moved off to the left, I cannot swipe to page to it.
Is there a common pattern I could use to accomplish this in a better way?
It sounds to me like you're animating the child view's frame to the left so that the x coordinate of that first view's frame is negative, instead of animating the scroll view's contentOffset to the right. If that's the case, is there a reason you aren't just setting the scroll view's contentOffset inside an animation block? If there is a reason, what if after the animation completes you "fix up" the content offset and the frames of the child views so that none of the views are in a negative position.
But, I guess I have more questions than answers right now, so it might help to post the code showing how you do your animations to make it easier to answer your question.

trouble with rotating view (and resizing elements within) in ipad application

I'm having a nightmare with the rotation on iPad. I've searched all over the place for some tutorials, but nothing seems to really be for what I want. (Possibly not searching for the right thing?!)
I have a portrait view by default which is an image and a button inside the view. When I rotate, I detect this can work out if it's landscape. I then try to set the frame size of the uiview to fit nicely on the screen.
If I let it autoresize, it simply stretches and fills the screen. This I don't want.
but the trouble is, when I resize, the button gets resized too, but not in the same ratio as the image.
My question is: What's the best way to resize the view. I wanted to simply reduce the uiview by say 60% and it resizes EVERYTHING in that view with the same 60%. The only way I see this is working at the moment is to create two views... but that's twice the work and maintenance!
I've tried messing with the autosizing arrows in Interface builder, but that again seems to screw things up more!
I'm completely lost here!! Thanks for any info
The problem you have there is that the view is automatically resized to the screen ratio. On an iPad in Portrait Orientation the screen size is 1024x768. After the rotation to Landscape the origin rotates too and your screen content is skewed or stretched to 768x1024.
What you need to do is to override the
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
message of the UIViewController of the view which rotates. This message is called within the animation block of the rotation. You just set the framesize of your subviews (the button) to whatever is best for you. Once i had a problem with rotating an OpenGL view. The content of the view was stretched when rotating to landscape. Since it is not possible to alter any OpenGL matrices within the animation block the only solution i found was to make the view quadratic and to set the origin behind the bounds of the screen (in -x direction). You have to override the message also to reset the origin above the screen (in -y direction) bounds in landscape mode, to keep the viewport in the middle of the screen. That way the view kept its ratio. Whatever solution is best for you, overriding this message should work out.
Have you tried disabling the autoresizesSubviews property on your UIView? It should prevent any size changes on the subviews when you resize your view.

Problem with UIScrollView

Sorry for long winded post.
I am trying to understand UIScrollView and running into very simple problem.
I am creating a scroll view
I am making this view 1.5 size larger then normal size
Using UIScrollView I expect to see some edge elements of view out of bounds, but should be able to pan the view therefore bringing missing elements back to the visible area.
However I am seeing that I can't just pan/scroll view anyway I want, instead view always wants to scroll up, as soon as move away my finger from the screen (touch end event).
I am not handling any touches, etc - I just want to understand why does not scaled view stay put where I scroll it?
CGRect viewFrame = self.view.frame ;
viewFrame.size.width *= 1.5;
viewFrame.size.height *= 1.5;
CGSize mySize = viewFrame.size;
[ ((UIScrollView *) self.view) setContentSize: mySize];
self.view.transform = CGAffineTransformMakeScale(1.5, 1.5);
What I really trying to accomplish is something similar to Number on iPad (the same code will work on iPhone):
There is a view with lots of controls
on it (order entry form)
User can zoom into the entire form so all elements look bigger
user can pan the form therefore bringing various elements into the visible area of the screen.
It seems that UIScrollView can should be able to handle zoom and pan actions (for now I am using Affine Transform to zoom in to the order entry form and iPad)
Thanks
When you transform a view, you transform its internal coordinate system as well. This means that if you scale a view, the view still "thinks" it is the same size it was before the scale because its coordinate units scaled as well.
For example, if you have an image view that has a size of (50,50) and you transform it so that it covers (200,200) on the screen, when you ask the image view its size it will report that its size is still (50,50).
Scrollviews are unusual types of views because they have understand their absolute size relative to physical device screen in order to work properly. When you transform their coordinate system, they lose that connection to the physical device screen and can no longer function properly. This is what you are seeing.
I haven't done this but I'm pretty sure to create the illusion of a zoom in a scrollview, you increase the frame of the scrollview and then transform its subviews (or transform the subviews and then increase the frame of the scrollview to contain the new subview size.) That is the only way to keep the scrollview in sync with the physical device screen.

What is actually changing when we zoom out a subView inside a UIScrollView?

I have a subview inside a uiscrollview. Then I zoom it out. So it becomes bigger and allows me to scroll through it.
So what is actually changing here? ContentSize of UIScrollView?
If you are not manually responding to changes in the zoom scale (like I describe in this answer), the view that you return from the -viewForZoomingInScrollView: delegate method is simply having a scaling transform applied to it by the UIScrollView. The frame size of the view is not changing, it is just being graphically transformed (which is why you see blurriness at higher scale factors).
The content size of the scrollview remains logically the same. If you check the frame of the scroll view it remains the same.
I think all that is changing is the scaling of the CGLayers. When you zoom in, it shrinks the clipping region frame smaller but then scales the CGLayer transform upwards. In other words, all the logical elements are still present it is simply choosing to draw and display a different part of it.
In the iPhone Application Programming Guide they have a good explanation about the relationship between frames, clipping regions and various transforms on views.