Using pan gesture recognizer to move multiple imageviews together - iphone

I'm creating an app for the iphone in xcode where the background image is much larger than the screen. I've added in a pan gesture recognizer to the imageview of the background, which allows it to be moved freely so the user can see beyond the character they control.
This is working perfectly, but when I add in additional imageviews(for the character and other objects throughout the area) they will remain stationary. Is there a way to connect multiple imageviews to a single pan gesture recognizer so that when one is moved, they all move together?
I tried connecting the other imageviews to the referencing outlet collections of the pan gesture recognizer, but when the program is run it only pans the last imageview connected, while the others remain stationary.
I'm new to xcode, and I'm sure this is something relatively simple that I'm overlooking, but I haven't been able to find an answer on the internet so any help would be appreciated. :)
Thanks!

The best way is to make the character (and other views) a subview of the backgroundImage.
Note that in the NIB (.xib) file you cannot add a Subview to UIImageView but you can do it programatically.
If you prefer working in the NIB file you can make a "container" UIView that holds the background image and other characters inside that view.
Then for the gesture recognisers you'll transform that view.

Related

iOS: how to allow all gestures/events *with a couple exceptions* to pass through a top level view to its subviews

I have an atypical iOS interface. Perhaps it's not practical but I'm giving it a go. Hope someone can help!
I have a menu in the form of a UIVIew. It contains 5 small UIImageViews. A UIPinchGestureRecognizer is attached to the UIVIew. When pinched inward, the 5 UIImageViews animate from off screen to form a circle in the middle of the window. When pinched outward, they animate back offscreen. Everything works great there.
I'd like to be able to, at any point in the application, pinch the screen to reveal the menu, select one of the 'buttons' (UIImageView), and load the associated subview.
The real problem is, if the current visible view is a UIScrollView or UITableView, my app is having trouble figuring out whether the menu or other subview should handle the touch event. If I really focus and make sure two finger touch the screen at the EXACT same time, the pinch will work and pull the menu inward. But otherwise, it attempts to scroll the current visible view.
I would like all events except the pinch gesture, (and a tap gesture when the menu is visible), to pass through the menu view to the rest of the subviews.
I understand I can override the hitTest:withEvent method to determine the correct view to handle the event, but I'm unclear at this point how exactly to use it. Neither the Apple docs nor any answers I've read on stack overflow have made this method clear to me.
Any help is much appreciated.
As UITableView is a subclass of UIScrollView, it inherits all of UIScrollView's properties including its gesture recognisers.
UIScrollView declares a UIPinchGestureRecognizer and UIPanGestureRecognizer. I'm not sure of the implementation details but I imagine the UITableView disables the pinch gesture recogniser as you are not supposed to be able to zoom a tableview!
In any case, you can attach your own UIPinchGestureRecognizer to the table view:
UIPinchGestureRecognizer *yPGR = [[UIPinchGestureRecognizer alloc]
initWithTarget:probablySelf action:yourMenuShowSelectorHere];
UITableView *tv = ...
// ...
[tv addGestureRecognizer:yPGR];
Then, you can make sure that the UITableView scoll does NOT scroll until your pinch has failed:
[tv.panGestureRecognizer requireGestureRecognizerToFail:yPGR];
This way, the UITableView will not scroll until it is sure that it has not detected a pinch.
EDIT: UIScrollView only uses (or at least declares public access to) UIGestureRecognizers in iOS 5 and up.

Sliding finger across multiple image views

I have dynamically created a grid of 8x8 image views over which letters are displayed and assigned the tag to each.I can detect the touch on each image view through Tap Gestures but what I want now is : if the user slide its finger across the letters, i would be able to get the each image view tag. So that the letters touched can be detected(the continuous touch).
Please Help,
Thanks In Advance.
Disable user interaction on the individual image views and handle touches on the superview containing them instead. Then you can figure out which image the user's finger is over in touchesMoved.
As the other poster said, you need to handle the touch events on the superview. You could use touchesBegan/touchesMoved, or you could add a pan gesture recognizer to the superview. Personally, I prefer gesture recognizers. I find them cleaner and easier to use, so I'd go that route.

How to pass a 'tap' to UIButton that is underneath UIView with UISwipeGestureRecognizer?

I have a UIButton underneath a (transparent) UIView. The UIView above has a UISwipeGestureRecognizer added to it, and that is its only purpose - to detect certain swipe gestures. I want all other touches to be ignored by that UIView, and passed to other views (such as my UIButton underneath). Currently, the UIView above seems to be detecting the tap (for example), doing nothing (as it should be), and not letting the UIButton underneath get a chance to respond.
I would prefer not to implement my own swipe recognizer, if possible. Any solutions / advice? I basically just want to know how to tell a UIView to pay attention to only a certain type of added gesture recognizer, and ignore (and thus let through to views behind) all other touches.
Have you set:
mySwipeGesture.cancelsTouchesInView = NO;
to allow the touches to be sent to the view hierarchy as well as the gesture?
Additionally, ensure that the view on top is:
theTransparentView.opaque = NO;
theTransparentView.userInteractionEnabled = YES;
I've had pretty good success attaching gestures to the parent view without needing to create a transparent subview on top for the gesture. Are you sure you need to do that?
I must have just been in a funk yesterday - I woke up with a simple solution today. Add the UISwipeGesture to a view which is a superview to both the UIView and the UIButton. Then, when processing those swipes, figure out where the swipe originated, and whether that point is in the frame of where I used to have the UIView. (As I mentioned, the only reason for the existence of the UIView was to define a target area for these swipe gestures.)
Can't you put your button on top of the view and add gesture recognisers to that button too?
In the end, your UIButton inherits form UIView via UIControl. Therefore there is practically nothing that you could do with a view but not with a button.
In my case, I fixed it by not using a button, but rather a UITapGestureRecognizer. My pan gesture recognizer was added to the background view, and the tap gesture was added to a view above it.

Drag UIView without disabling its child controls iPhone/iPad

I have a UIView control (white rectangle in image)
Moreover I am able to drag that control...
And when I press the button I load a subview which is another nib that I created and I placed random controls in it to illustrate my point...
If you guys are interested in finding out how I placed that nib file in that UIView control take a look at this question. I don't thing you have to read it in order to understand my question.
Anyways the problem when loading that nib file is that I can no longer drag the top UIView. Because of this I changed:
for:
in the UIView of the subview. In otherwords the UIView of the nib file that I am placing in the UIView that has the white background.
and when I did that I was able to drag the control but the controls inside the subview no longer works. I have also tried placing the touchesMoved method in the subview instead but when I do that the application behaves strange. Plus the purpose of placing the nib file in a UIView control was to avoid repeating the same drag funcionality on several nib files.
I actually need to create an application like a power point presentation and I need to change the slide as the user slides the UIView and if it's cords are less than x for example then I load the next slide (nib file) in that uiview controller. Maybe there is a simpler way of doing what I need but if I get this drag to work I am done cause I would just have to do that functionality just once.
You should leave the UserInteractionEnabled flag on for your subview if you want it to respond to events.
One way to achieve this would be to do your dragging using a UIGestureRecognizer.
UIPanGestureRecognizer is perfect for this (UIGestureRecognizer at apple)
Basically you'd attach the gesturerecognizer to the view which you want to pan then adjust it's position in the callbacks it provides.
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc]
initWithTarget:self action:#selector(handlePanGesture:)];
panGesture.minimumNumberOfTouches = 1;
[draggableSubview addGestureRecognizer:panGesture];
[panGesture release];
Then in the handlePanGesture method you figure out how far the user panned using the translationInView method of the recognizer which it gets passed and translate the subview accordingly.

UIScrollview with two images - Keeping 1 image zoomable and 1 image static (fixed size)

I have a UIView which contains a zoomable UIImageView and also another semitransparent UIView on top of that.
What I am trying to achieve is to be able to zoom the UIImageView while keeping the semitransparent view static and not zoomed.
If I add the semitransparent UIView on top of the UIImageView (which is added to the UIScrollView), everything zooms. However, if I add both as subviews to the base UIView, the touches only get tracked is the semitransparent UIView since its the last one added.
I do need control to reside first at the semitransparent UIView for the touches since I may want to resize the semitransparent view. However, I'd like to pass control of the touches to the UIScrollView if two fingers are used. Is there anyway for me to achieve this? The nextresponder doesn't seem to work. I also tried to use hittest in addition to subclassing UIWindow, but the base UIView needs to push/pop navigation controlling ability so I don't think I can subclass UIWindow to push onto the navigation stack.
Any help would be appreciated.
Thanks,
Winston
Hm.. you can try this hierarchy (possibly subclasses):
UIView (container)
> UIView (semitransparent overlay)
> UIScrollview
- UIView (zoomable content)
Like this, the overlay does not scale.
The tricky thing then is the user interaction on multiple layers. Its easy if there are areas in your overlay that should not detect user touches, for that you just set the UIView property 'userInteractionEnabled' to 'NO' for the view parts where touches should be 'forwarded' to the underlaying layers.
But if I get you right, you need something more complicated. You probably could set up some kind of master-touch-controller in the container UIView, that finds out what is happening and then calls certain methods of its subviews / forwards the events.
I don't know all the exact methods you need to override/implement in the container, but check out the tapZoom demo from the ScrollView Suite sample code. It's a pretty nice example there.
Just out of curiosity, may I ask what this interaction model is used for?