Is there a way to get the UITouch
objects associated with a gesture? UIGestureRecognizer
doesn't seem to have any methods for this.
问题:
回答1:
Jay's right... you'll want a subclass. Try this one for size, it's from one of my projects. In DragGestureRecognizer.h:
@interface DragGestureRecognizer : UILongPressGestureRecognizer {
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
@end
@protocol DragGestureRecognizerDelegate <UIGestureRecognizerDelegate>
- (void) gestureRecognizer:(UIGestureRecognizer *)gr movedWithTouches:(NSSet*)touches andEvent:(UIEvent *)event;
@end
And in DragGestureRecognizer.m:
#import "DragGestureRecognizer.h"
@implementation DragGestureRecognizer
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesMoved:touches withEvent:event];
if ([self.delegate respondsToSelector:@selector(gestureRecognizer:movedWithTouches:andEvent:)]) {
[(id)self.delegate gestureRecognizer:self movedWithTouches:touches andEvent:event];
}
}
@end
Of course, you'll need to implement the
- (void) gestureRecognizer:(UIGestureRecognizer *)gr movedWithTouches:(NSSet*)touches andEvent:(UIEvent *)event;
method in your delegate -- for example:
DragGestureRecognizer * gr = [[DragGestureRecognizer alloc] initWithTarget:self action:@selector(pressed:)];
gr.minimumPressDuration = 0.15;
gr.delegate = self;
[self.view addGestureRecognizer:gr];
[gr release];
- (void) gestureRecognizer:(UIGestureRecognizer *)gr movedWithTouches:(NSSet*)touches andEvent:(UIEvent *)event{
UITouch * touch = [touches anyObject];
self.mTouchPoint = [touch locationInView:self.view];
self.mFingerCount = [touches count];
}
回答2:
If it is just the location you are interested in, you do not have to subclass, you will be notified of location changes of the tap from the UIGestureRecognizer.
Initialize with target:
self.longPressGestureRecognizer = [[[UILongPressGestureRecognizer alloc] initWithTarget: self action: @selector(handleGesture:)] autorelease];
[self.tableView addGestureRecognizer: longPressGestureRecognizer];
Handle UIGestureRecognizerStateChanged to get location changes:
- (void)handleGesture: (UIGestureRecognizer *)theGestureRecognizer {
switch (theGestureRecognizer.state) {
case UIGestureRecognizerStateBegan:
case UIGestureRecognizerStateChanged:
{
CGPoint location = [theGestureRecognizer locationInView: self.tableView];
[self infoForLocation: location];
break;
}
case UIGestureRecognizerStateEnded:
{
NSLog(@"Ended");
break;
}
default:
break;
}
}
回答3:
If you only need to find out the location of the gesture, you can call either locationInView: or locationOfTouch:inView: on the UIGestureRecognizer object. However if you want to do anything else, then you'll need to subclass.
回答4:
If you're writing your own UIGestureRecognizer you can get the touch objects overriding:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
or the equivalent moved, ended or canceled
The Apple docs has lots of info on subclassing
回答5:
Here is a method to get a long press added to an arbitrary UIView.
This lets you run longpress on any number of UIViews. In this example I restrict access to the UIView method through tags but you could use isKindOfClass as well.
(From what I found you have to use touchesMoved for LongPress because touchesBegan fires before the LongPress becomes active)
subclass - .h
#import <UIKit/UIKit.h>
#import <UIKit/UIGestureRecognizerSubclass.h>
@interface MyLongPressGestureRecognizer : UILongPressGestureRecognizer
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
@property (nonatomic) CGPoint touchPoint;
@property (strong, nonatomic) UIView* touchView;
@end
subclass - .m
#import "MyLongPress.h"
@implementation MyLongPressGestureRecognizer
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
{
UITouch * touch = [touches anyObject];
self.touchPoint = [touch locationInView:self.view];
self.touchView = [self.view hitTest:[touch locationInView:self.view] withEvent:event];
}
#pragma mark - Setters
-(void) setTouchPoint:(CGPoint)touchPoint
{
_touchPoint =touchPoint;
}
-(void) setTouchView:(UIView*)touchView
{
_touchView=touchView;
}
@end
viewcontroller - .h
//nothing special here
viewcontroller - .m
#import "ViewController.h"
//LOAD
#import "MyLongPress.h"
@interface ViewController ()
//lOAD
@property (strong, nonatomic) MyLongPressGestureRecognizer* longPressGesture;
@end
@implementation PDViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//LOAD
self.longPressGesture =[[MyLongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressHandler:)];
self.longPressGesture.minimumPressDuration = 1.2;
[[self view] addGestureRecognizer:self.longPressGesture];
}
//LOAD
-(void) setLongPressGesture:(MyLongPressGestureRecognizer *)longPressGesture {
_longPressGesture = longPressGesture;
}
- (void)longPressHandler:(MyLongPressGestureRecognizer *)recognizer {
if (self.longPressGesture.touchView.tag >= 100) /* arbitrary method for limiting tap */
{
//code goes here
}
}
回答6:
Simple and fast:
NSArray *touches = [recognizer valueForKey:@"touches"];
Where recognizer is your UIGestureRecognizer