How to zoom UIScrollview together with added UIImage - objective-c

I have a background image that is added to UIScrollView with zoom enabled. I am trying to add additional UIImage's on top of the background image that zoom together with the background image?
The idea is to have a background with multiple playing cards were the user can either see the whole playing field with small playing cards or zoom in the whole background including the playing cards for better views on the playing cards.

Your UIScrollview should contain a single zoomable UIView subview. That subview should contain your background UIImageView and all of the card UIImageViews as it's own subviews (if you add the background image first, it will be layered at the back of the resulting composite view)
The containing UIView that is the immediate subview of your scrollview should be the return value to the UIScrollviewDelegate method
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
You can manage your view hierarchy through a UIView's subviews property, which is an NSArray of views. They are layered in the order of the array, so the first view on the array will be at the back when the views are composited for display.

Well you could use the scrollviewdidzoom delegate method to notify you when the scroll view has been zoomed in and out.
From there you could do a number of things like present new UIImages at a specific zoom level using the scrollView.zoomScale property.
Let me know if this helps.

Related

Put different backgrounds in a View Controller

I am doing my first steps creating applications in iOS, so maybe I am asking a dumb question.
In a View Controller, I put some buttons and text fields to make different actions. To improve the organization, I want to put several backgrounds with borders to delimitate the areas where the buttons and text fields are placed.
I tried putting a text label without text and color background, and move my objects over it, but I don't know why the layer is placed over the buttons and text fields. Then, I tried modifying the text label's opacity, but it's totally unsatisfactory.
label1.layer.cornerRadius = 5.0;
label1.layer.masksToBounds = YES;
label1.layer.borderColor = [UIColor lightGrayColor].CGColor;
label1.layer.borderWidth = 1.0;
label1.layer.opacity = 0.1;
label1.layer.backgroundColor = [UIColor whiteColor].CGColor;
Can help me anyone to find a better way to do this or improve my code?
1) you could just use a normal UIView instead of a label with no text (same difference just more correct)
2) in the story board the order in which the UI elements are on the left bar is important, it is basically the draw order of the elements, the ones at the top are drawn first, therefore things below it will be drawn over
You can try in Interface Builder to put multiple UIImageView objects and set your backgrounds as desired from Attributes Inspector and watch out how you put your elements in your UIView. The ones below are drawn after the ones at the top.
If I understood you right, ...
Make yourself familiar with the logic behind the subview hierarchy and the drawing sequence of siblings.
In your interface builder/storyboard you could align the views as followed:
UIView (the default view that is connected to the view controller's view property)
\--UIView (This is a background to group UI Items as buttons or Lables
\-- UILabel
\-- UIButton
\--UIView (the next background)
\-- UILabel
\-- UIButton
When it comes to coorindates then you will notice that the coordinates of each view are relative to its subview. So the UILabel and UIButton might have the same coordinates but each of them will be located within its very subview.
Another option would be:
UIView (the default view that is connected to the view controller's view property)
\--UIView (Background)
\--UIButton
\--UILable
\--UIView (Background)
\--UIButton
\--UILable
Or even
UIView (the default view that is connected to the view controller's view property)
\--UIView (Background)
\--UIView (Background)
\--UIButton
\--UILable
\--UIButton
\--UILable
In that case all UI elemets share the same coordinate space. In that case you need to care for a proper layout.
This one is would not work:
UIView (the default view that is connected to the view controller's view property)
--UIButton
--UILable
--UIButton
--UILable
--UIView (Background)
--UIView (Background)
Even if all coordinates etc. are identical with those of the examples above, the two background views would hide the other UI elements just because they are drawn after the others. And the last one wins the space.

Zooming the whole screen with UIPinchGestureRecognizer

I was trying to add a pinch gesture zoom-in zoom-out feature to a UITextView and then I decided that adding a pinch gesture which zooms the whole screen, covering the whole view hierarchy is a better and more general solution. But I am confused about how to do it: Should I change the frame sizes of all UIView objects or should I somehow scale them? What is the most correct way to do it?
Put all your views in a UIScrollView and then return the view in this delegate method of UIScrollView
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView

Zoom in many UITextView

I have many UITextView and UIImageView inside UIScrollView.
This UITextViews and UIImageView I create dynamic.
How can I put zoom in and zoom out if this elements I create dynamic? Sometimes I have one UITextView and one UIImageView, sometimes I have two UIImageViews and one UITextView and etc...
You will need to figure out the contentSize for the UIScrollView. Loop through all of the UIViews added and determine the one in the lowest-right corner then grab it's frame origin + size and that should be the full size then set the scrollview.contentSize to that CGSize value.
You'll need to create a view (either UIView or a subclass of UIView) with everything you would like to zoom in on on it and return it in the UIScrollView's viewForZoomingInScrollView: delegate method.
Obviously set the contentSize, maximumZoomScale and minimumZoomScale properties accordingly.

Rotate UIViewControllers in UIScrollView

I have UIViewController with UIScrollView in it.
UIScrollView contains multiple UIViewControllers (something like PageControl Apple example).
Each inner UIViewController in UIScrollView is able to handle the change of UIInterfaceOrientation and to redraw it's view.
But when the UIViewControllers are in UIScrollView the rotations events never reaches inner UIViewControllers.
How can I make those inner UIViewControllers to handle rotation events?
Thanks in advance.
Only a viewController in a viewController structure (like tabbarcontroller or navigationcontroller) gets (and handles) rotation events. If you just added the views of some viewControllers, they won't actually rotate, but they will change their framesize accordingly to the new size of the main view. In general you should use autoresizingMasks on every view. Read about them in the documentation.
But in a scrollView there is probably no autolayouting possible. You could overwrite layoutSubviews: in your main view to handle the layout of all scrollView subviews based on the scrollView frame.
Perhaps you can detect when the device is rotated, then using the transform property apply the necessary rotation programmatically using CGAffineTransformMakeRotation(-M_PI_2), for example...

Removing views from UIScrollView

I have two UIScrollViews that I move images between. The user can drag and forth between the scroll views. I am trying to animate the movement of the image from one scroll view to another. In -touchesMoved (handled in my UIViewController which has two custom UIScrollViews that intercept touch and sends to my UIViewController), I am trying to set the "center" of my UIImageView that is being moved. As it is moved, the image gets hidden behind the UIScrollView and not visible. How do I make it appear on top of the UIScrollView? I am able to handle the -touchesEnded properly by animating in the destination scroll view.
I am also confused about -convertPoint:fromView: usage in the iPhone Programming Guide (See Chapter 3, Event Handling). If the touch coordinates are in window coordinates, to change my view (UIImageView inside a UIScrollView which is inside a UIView and inside a window) center don't I have to use -convertPoint:toView:, i.e.,
imageView.center = [self.view.window convertPoint:currentTouchPosition toView:imageView];
What am I missing?
You can use the method - (void)bringSubviewToFront:(UIView *)view for making the image view the front most view.
Johan
It depends on how you structured your views. If both scrollviews and the imageview are at the same level, it should work. If the imageview is a subview of one of the scrollviews, you can try bringing the scrollview to the front. That way also the imageview will be drawn over the other scrollview.
Johan
I have a View Controller with two ScrollViews. Images are added as subviews. ScrollViews are already in the front. I tried bringing scrollview to the front and also imageview of the scrollview to the front. But somehow when i drag, the center of the image goes over my other scrollview2 which i also tried sending back. But does not seem to work. Here is what i do, in TouchesMove (inside a ViewController)
view= [[scrollView1 subviews] objectAtIndex:currentImageIndex];
[self.view bringSubviewToFront:scrollView1];
[scrollView1 bringSubviewToFront:view];
[self.view sendSubviewToBack:scrollView2];
scrollView1 and scrollView2 are two scrollviews that are part of the ViewController's view.
Does this make sense ?
thanks
mohan