In the UIView, there is several sub views of UIImageView objects.
Since I need to detect the touch events from the UIImageView and from the remaining area of the UIView.
Can I implement touch events in UIView and UIImagView simultaneously ?
Thanks.
Based on your comment, I think you should consider gesture recognizers. Use the UITapGestureRecognizer to identify and respond to taps on a view.
UITapGestureRecognizer *tapGesture;
tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapOnView:)];
tapGesture.numberOfTapsRequired = 1;
tapGesture.numberOfTouchesRequired = 1;
[view addGesture:tapGesture];
[tapGesture release];
...
tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapOnImage:)];
tapGesture.numberOfTapsRequired = 1;
tapGesture.numberOfTouchesRequired = 1;
[imageView addGesture:tapGesture];
[tapGesture release];
...
define -(void)handleTapOnView:(UITapGestureRecognizer*)gesture and -(void)handleTapOnImage:(UITapGestureRecognizer*)gestureand handle the touches there.
There are other kinds of gestures too. You can read more about them here.
Related
In viewDidLoad I set:
UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeFrom:)];
[swipeGesture setDirection:(UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight)];
[self.view addGestureRecognizer:swipeGesture];
-(void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer {
NSLog(#"Swipe received.");
UISwipeGestureRecognizerDirection temp = recognizer.direction;
if (recognizer.direction == UISwipeGestureRecognizerDirectionLeft)
{
[self backCalendarPressed:nil];
}
else if (recognizer.direction == UISwipeGestureRecognizerDirectionRight)
{
[self nextCalendarPressed:nil];
}
}
but recognizer.direction is always equal to '3'.
And that's why I can't determine if it's left or right swipe.
you have to set a separate gesture recognizer for each direction if you want to discern between left and right gestures. the direction property only gives you what you set as allowed direction (3 = both directions).
You can give the same target method to both, and in that method ask for the direction of the recognizer as you are doing.
You should try this. It is working fine.
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(backCalendarPressed:)];
[swipeLeft setDirection: UISwipeGestureRecognizerDirectionLeft ];
[self.view addGestureRecognizer:swipeLeft];
swipeLeft=nil;
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(nextCalendarPressed:)];
[swipeRight setDirection:UISwipeGestureRecognizerDirectionRight];
[self.view addGestureRecognizer:swipeRight];
Basically you cannot set multiple directions to a single Swipe gesture recognizer. Use separate gesture recognizers for Left and Right directions.
try this:
The direction property only defines the allowed directions that are recognized as swipes, not the actual direction of a particular swipe.
The easiest would be to use two separate gesture recognizers instead.
If you want to capture swipes left and right that you can differentiate between, you'll have to set up a separate recognizer for each. Apple does this in their Simple Gesture Recognizers
UISwipeGestureRecognizer *swipeGestureLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeFromLeft:)];
[swipeGestureLeft setDirection:UISwipeGestureRecognizerDirectionLeft];
[self.view addGestureRecognizer:swipeGestureLeft];
UISwipeGestureRecognizer *swipeGestureRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeFromRight:)];
[swipeGestureRight setDirection:UISwipeGestureRecognizerDirectionRight];
[self.view addGestureRecognizer:swipeGestureRight];
-(void)handleSwipeFromLeft:(UISwipeGestureRecognizer *)recognizer {
[self backCalendarPressed:nil];
}
-(void)handleSwipeFromRight:(UISwipeGestureRecognizer *)recognizer {
[self nextCalendarPressed:nil];
}
You should implement all the UIGestureRecognizer states in this handler method. Thus you can handle all the cases. I am stating this because I suspect the gesture recognizer has not yet properly recognized it's gesture. Try looking for the direction in the UIGestureRecognizerStateChanged case.
I have problem with tap gesture. My case is:
- A view with UITapGestureRecognizer to dismiss keyboard
- A label on view, which has 2 gesture. One UITapGestureRecognizer to open popup, and UITapGestureRecognizer (number of touches is 2) to quickly confirm popup.
But when I tap on label, the UITapGestureRecognizer on view always receive the action. How can I forward action to UILabel.
Thanks
To get taps on label, you need to enable user interaction for that label
To receive 2 taps you need to do following
In short [tap requireGestureRecognizerToFail:dTap]; will do trick for you making single tap to wait for a while to check if double tap is to happen
UITapGestureRecognizer *dTap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(doubleTapped:)];
dTap.delegate = self;
dTap.numberOfTapsRequired = 2;
dTap.numberOfTouchesRequired = 1;
[label addGestureRecognizer:dTap];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(tapped:)];
tap.delegate = self;
tap.numberOfTapsRequired = 1;
tap.numberOfTouchesRequired = 1;
[label addGestureRecognizer:tap];
[tap requireGestureRecognizerToFail:dTap];
// it Enables user interaction on you Lable, by default its NO, so you have to do it.
[lbl setUserInteractionEnabled:YES];
Actually i want to implement swipe left and right in UIScrollview. i have scrollview with content size (768,1500). i have tried this but problem is that sometimes its not detecting swipe and perform scrolling there. so now i want to disable scrolling on 2 finger touch.
swipeGesture = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(nextswipedScreen:)] autorelease];
swipeGesture.numberOfTouchesRequired=2;
swipeGesture.direction = UISwipeGestureRecognizerDirectionLeft;
[self addGestureRecognizer:swipeGesture];
swipeGesture = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(previousswipedScreen:)] autorelease];
swipeGesture.numberOfTouchesRequired=2;
swipeGesture.direction = UISwipeGestureRecognizerDirectionRight;
[self addGestureRecognizer:swipeGesture];
i have tried custom scrollview for that but i have problem with touchesBegan method. its not calling every time. even i tried this but not able to stop two finger scroll in UIScrollview.
for (UIGestureRecognizer *mgestureRecognizer in _scrollView.gestureRecognizers) {
if ([mgestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])
{
UIPanGestureRecognizer *mpanGR = (UIPanGestureRecognizer *) mgestureRecognizer;
mpanGR.minimumNumberOfTouches = 1;
mpanGR.maximumNumberOfTouches = 1;
}
}
Let me know if you have any solution or alternative for that.
I had the same problem; I needed to disable two-finger scrolling so that I could detect a two-finger swipe to the left or right. Here's what I did to set up my scroll view:
- (void) setUpGestureHandlersOnScrollView:(UIScrollView *)scrollView {
// set up a two-finger pan recognizer as a dummy to steal two-finger scrolls from the scroll view
// we initialize without a target or action because we don't want the two-finger pan to be handled
UIPanGestureRecognizer *twoFingerPan = [[UIPanGestureRecognizer alloc] init];
twoFingerPan.minimumNumberOfTouches = 2;
twoFingerPan.maximumNumberOfTouches = 2;
[scrollView addGestureRecognizer:twoFingerPan];
// set up the two-finger left and right swipe recognizers
UISwipeGestureRecognizer *twoFingerSwipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleGestureFrom:)];
twoFingerSwipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
twoFingerSwipeLeft.numberOfTouchesRequired = 2;
[scrollView addGestureRecognizer:twoFingerSwipeLeft];
UISwipeGestureRecognizer *twoFingerSwipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleGestureFrom:)];
twoFingerSwipeRight.direction = UISwipeGestureRecognizerDirectionRight;
twoFingerSwipeRight.numberOfTouchesRequired = 2;
[scrollView addGestureRecognizer:twoFingerSwipeRight];
// prevent the two-finger pan recognizer from stealing the two-finger swipe gestures
// this is essential for the swipe recognizers to work
[twoFingerPan requireGestureRecognizerToFail:twoFingerSwipeLeft];
[twoFingerPan requireGestureRecognizerToFail:twoFingerSwipeRight];
}
The handler method should look something like this:
- (void)handleGestureFrom:(UISwipeGestureRecognizer *)recognizer {
if ([recognizer numberOfTouches] == 2) {
// do whatever you need to do
}
}
You can create two gesture recognizers, one for single tap and one for double tap:
UITapGestureRecognizer *singleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTouchesOne:)];
singleTapGesture.cancelsTouchesInView = NO;
singleTapGesture.delaysTouchesEnded = NO;
singleTapGesture.numberOfTouchesRequired = 1; // One finger single tap
singleTapGesture.numberOfTapsRequired = 1;
[Scroll_view addGestureRecognizer:singleTapGesture];
[singleTapGesture release];
UITapGestureRecognizer *doubleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTouchesTwo:)];
doubleTapGesture.cancelsTouchesInView = NO;
doubleTapGesture.delaysTouchesEnded = NO;
doubleTapGesture.numberOfTouchesRequired = 1; // One finger double tap
doubleTapGesture.numberOfTapsRequired = 2;
[Scroll_view addGestureRecognizer:doubleTapGesture];
[doubleTapGesture release];
And then, here comes the punch:
[singleTapGesture requireGestureRecognizerToFail : doubleTapGesture];
requireGestureRecognizerToFail Reference
The last line, makes your single tap handler work only if the double tap fails. So, you get both single tap and double tap in your application.
And So you can do like, in "doubleTapGesture" method you just specified the scrollview with content size (0,0), In "singleTapGesture" method you specified the scrollview with content size (768,1500).
Source knowledge
i got a strange problem. I got a Superview with customcontrols as subviews.
Their are GestureRecognizer both in superview and subviews.
If i tap a subview its GestureRecognizer gets called and on tap on the superview its tap gets called.
but on long press in the subview SOMETIMES the GestureRecognizer of the superview gets called. I add the GestureRecognizers in the same functions but there is a different attitude.
Superview
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapPiece:)];
tapGesture.numberOfTapsRequired = 1;
//contenView is the area where my controls can be
[self.contentView addGestureRecognizer:tapGesture];
[tapGesture release];
UILongPressGestureRecognizer *longTapGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longTapPiece:)];
tapGesture.numberOfTapsRequired = 1;
[self.contentView addGestureRecognizer:longTapGesture];
[longTapGesture release];
Subviews
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(selectPiece:)];
tapGesture.numberOfTapsRequired = 1;
[self addGestureRecognizer:tapGesture];
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPiece:)];
longPressGesture.numberOfTapsRequired = 1;
[self addGestureRecognizer:longPressGesture];
Can anyone tell me why the longtap doen't response to my subview and how to fix it.
THANK YOU
got a solution but this is not what i wanted i set the duration of the control lower than the one of the superview [longPressGesture setMinimumPressDuration:0.4]; But the gestureRecognizer should be independend
I have a UIScrollView with multiple UIImageViews in it created like this.
frame = [[UIImageView alloc] initWithImage:bg];
frame.frame = CGRectMake(FRAME_SEPARATOR + numPage*1024 + numColumn*(FRAME_SEPARATOR+230), 10 +numRow*(FRAME_SEPARATOR+145), 230, 145);
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageTapped:)];
[frame addGestureRecognizer:tap];
[tap release];
[scroll addSubView:frame];
The problem is that imageTapped is not being called when tapping over an image.
If I add the gesture recognizer to the scrollview like this:
UITapGestureRecognizer *tap =
[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageTapped:)];
[scroll addGestureRecognizer:tap];
[tap release];
imageTapped is called.
How can I detect the taps over the UIImageViews?
Thanks
Make sure userInteractionEnabled is set to YES on the UIImageView:
frame.userInteractionEnabled = YES;
I'd also recommend using a different name for the UIImageView variable (eg. imageView instead of frame). Otherwise, you can easily confuse it with the view's frame property.