UIScrollView decide between drag and tap - objective-c

I am trying to determine a Single Tab on a View inside of a UIScrollView. The Problem is that The UIScrollview catches all the gestures.
What I tried so far:
I override the following method in my UIScrollView:
-(BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view
{
UITouch *touch = [touches anyObject];
if([touch tapCount]== 2) return YES;
return NO;
}
This works fine, I can now reach the UITapGestureRecognize on my UIView, unfortunately I can only detect double-taps because the [touch tapCount] == 1 is always beeing called (dragging or zooming in the UIScrollView). But actually the UIScrollview does not need the "Single-Tap-Function"
Is there a way to decide between a drag (Scroll or zoom) and a single Tap inside this method? I cant find it..
-(BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view
Thanks in advance
Fabi

It sounds like you only want the tap recognizer to succeed if the touch doesn't scroll the scroll view. This is pretty easy because the scroll view uses a pan gesture recognizer for scrolling. On iOS 5, you can just do this:
[self.tapRecognizer requireGestureRecognizerToFail:self.scrollView.panGestureRecognizer];
If you want to support older versions of iOS, you have to do this:
for (UIGestureRecognizer *recognizer in self.scrollView.gestureRecognizers) {
if ([recognizer isKindOfClass:[UIPanGestureRecognizer class]])
[self.tapRecognizer requireGestureRecognizerToFail:recognizer];

touchesShouldBegin: is a delegate method on UIView. It is not part of a UIGestureRecognizer.
You'll need to create a UITapGestureRecognizer, set the number of taps you want to trigger the recognizer and add it to your view.
Here is the documentation for UITapGestureRecognizer

I'm assuming you meant "single tap"--your scrollView belongs to the UIView tied to your controller. Assign the tap gesture recognizer to the that UIView. It gets first picks on all gestures and then passes down the ones it isn't interested in.

Related

UIViewController not passing touches to other Views

I have an overlay view (covering the entire screen), I can receive touches but it isn't passing them down the responder chain.
I add the subview like this:
UIWindow *mainWindow = [[UIApplication sharedApplication] keyWindow];
[mainWindow insertSubview:self.view aboveSubview:mainWindow];
It doesn't seem to matter if I use addSubview or insertSubview.
My touchesBegan looks like:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//do some stuff here..
[super touchesBegan:touches withEvent:event];
}
It doesn't seem to matter if I am using SUPER or various other combinations of self.nextResponder, etc..
In the end, I need to have an overlay view that covers the entire screen, I need to detect touches then pass them to the views/viewControllers below them.
Thanks!
You are addView to the mainWindow, your super view is the mainWindow, not the viewBlow it.
You need to add the view to VC's view, and if you want the full screen. set the status bar to hidden (or transparent. not tried) and then set the view's frame to (0, -20, weight, height+20).

How do I forward touch events to a view behind a uicollectionview?

I have a uicollectionviewcontroller which I use to create a small toolbar at the bottom of the screen. I add the view of the uicollectionviewcontroller to another viewcontroller's view. My problem is that it won't forward touch events to a view underneath it. I did move it to the bottom and that worked for a while but now I need to use 2 uicollection views.
How am I supposed to forward touch events to views beneath a uicollectionviewcontroller's view?
In case the question is still relevant, the following can be used to achieve touch forwarding.
Subclass UICollectionView
Overwrite - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
[super touchesEnded:touches withEvent:event];
[self.yourCustomDelegate forwardTouches:touches withEvent:(UIEvent *)event];
}
That is how UICollectionView can keep its ability to respond to user interaction, and the same time forward received touches.
As i think you can add your toolbar as footer of UICollectionView and it will work
have a look into this link How to Add Header and Footer View in UICollectionView

how to use tap gesture in pageBased application for other functionality by not using for swiping of pages

I am using a page based application for one of my apps.In this there is scenario where if v tap once it swipes to next page.
What my requirement is i dont want this tap gesture for swiping of pages,instead i want this tap gesture to be used for some other functionality like once tap it shd zoom in or else if i tap some other tab bar should appear..
I know we can remove this tap gesture in viewdidload method by code.But i dont want to remove this gesture instead i want to use this Tap gesture for other functionality for example like zoomin and so on.So anyone tel me is this possible????If it is possible how can be achieve it???can anyone tel me by code???If its not possible then what are the other alternative????
I think you can implement something like this:
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
if ([touch tapCount] == 2) {
//your code here
}
//other code
}

Adding touch-area to UIView (iOS5)

I have a MainView with MainViewController. Now I want to add a specific area where I want to register touches (painting in a specific area). How could I do this?
I thought about adding a sub-view with its own sub-viewcontroller, but this guy tells this is not a good approach.
The post you linked to is partially out of date because it was written before Apple introduced support for View Controller Containment in iOS 5.
That said, it's your choice whether:
the subview is managed by its own view controller or
you use the MainViewController directly to respond to touches in the subview or
you create a UIView subclass that interprets touches on itself without the help of a view controller.
Add a custom view as a property, called touchArea
-(void) touchesBegan/Moved/Ended (NSSet *)touches withEvent:(UIEvent *)event {
CGPoint location = [[touches anyObject] locationInView:self.view];
if (CGRectContainsPoint(touchArea.frame, location))
//code
}
}

Drag event in subview of UIScrollView

How can I add a drag event to a subview of a UIScrollView? The structure is the following:
-UIView
-UIScrollView
-UIView
-UIView
...
I tried to start with the following:
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *aTouch = [touches anyObject];
CGPoint location = [aTouch locationInView:self.superview.superview];
[UIView beginAnimations:#"Dragging A DraggableView" context:nil];
self.frame = CGRectMake(location.x, location.y,
self.frame.size.width, self.frame.size.height);
[UIView commitAnimations];
}
But nothing happens! Help would be very much appreciated.
Thanks
Just incase anyone finds this question like I did, I solved this problem by adding a gesture recognizer to the subviews in the scrollview. The gesture recognizer will handle the touch event itself.
Bruno, one possibility is to use the gesture recognizers, as Scott mentions.
Another possibility is to use the touchesMoved: method you mention. Using the touchesMoved: method requires you to implement another three methods, touchesBegan:, touchesEnded:, touchesCancelled:. They cover the phases of the finger touching the screen:
First contact (touchesBegan) allows you to set up variables as needed.
Continuous move (touchesMoved) allows you to track the move and move your content continuously.
And finally removing the finger (touchesEnded) where you can finalize any changes you want to keep.
touchesCancelled is required for clean-up if the gesture is interrupted (by phone call, or some other controller grabbing the touch event).
You need all four methods on the same class, otherwise a superclass implementing the method will grab the touch processing and your code won't run as expected.
Regards, nobi