面白いことを聞きたい。カスタムの組み合わせジェスチャが発生したときにアプリが動作できるようにしたい。例: ユーザーが画面上で指を離さずに左、上、左にスワイプすると、アクション (/メソッド) が呼び出されます。このカスタム ジェスチャを作成するにはどうすればよいですか?
2 つ目の質問は、左上 (「 / 」のようにこの方向) にスワイプしてもいいですか? このジェスチャーの作り方は?
誰でも私を助けることができますか?お願いします!ありがとう
概念的には、UIGestureRecognizer をサブクラス化し、位置の追跡を行いUIGestureRecognizerSubclass.h
、ジェスチャをインポートした後に状態プロパティが読み取り/書き込み可能になるという事実を利用して、自分の周りのすべてのギアを動かす必要があります。例として、私がずっと前に構築しようとした斜めのジェスチャーの基本的なプロトタイプを含めます。(いくつかのねじれを解決する必要がありますが、全体としては機能します。)
.H
#import <UIKit/UIKit.h>
#import <UIKit/UIGestureRecognizerSubclass.h>
@interface MMDiagnoalSwipeGestureRecognizer : UIGestureRecognizer
@property (nonatomic, readwrite) BOOL shouldReverseYDelta;
@property (nonatomic, readwrite) CGFloat tolerance;
@property (nonatomic, readonly) CGFloat angleOfSwipe;
@end
.M
#import "MMDiagnoalSwipeGestureRecognizer.h"
@interface MMDiagnoalSwipeGestureRecognizer ()
@property (nonatomic, readwrite) CGPoint startingPoint;
@end
@implementation MMDiagnoalSwipeGestureRecognizer
- (id)initWithTarget:(id)target action:(SEL)action {
self = [super initWithTarget:target action:action];
if (self) {
_shouldReverseYDelta = NO;
_tolerance = 30.0f;
}
return self;
}
- (CGFloat)angleOfGestureFromPoint:(CGPoint)start toEndPoint:(CGPoint)end {
CGFloat deltaY = (_shouldReverseYDelta) ? end.y - start.y : start.y - end.y;
CGFloat deltaX = end.x - start.x;
_angleOfSwipe = atan2f(deltaY, deltaX) * 180.0f / M_PI;
return _angleOfSwipe;
}
- (CGFloat)diagonalDistanceFromPoint:(CGPoint)start toEndPoint:(CGPoint)end {
CGFloat deltaX = fabsf(start.x - end.x);
CGFloat deltaY = fabsf(start.y - end.y);
CGFloat hypotenuse = powf(deltaX, 2.0f) + powf(deltaY, 2.0f);
return sqrtf(hypotenuse);
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (touches.count > 1) {
if (self.state == UIGestureRecognizerStatePossible) {
self.state = UIGestureRecognizerStateFailed;
}
}else{
[touches enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
UITouch *touch = (UITouch *)obj;
_startingPoint = [touch locationInView:self.view];
}];
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[touches enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
UITouch *touch = (UITouch *)obj;
CGPoint endPoint = [touch locationInView:self.view];
CGFloat angle = [self angleOfGestureFromPoint:_startingPoint toEndPoint:endPoint];
if (self.state == UIGestureRecognizerStatePossible) {
if ([self angleIsWithinDiagonalTolerance:angle] == YES) {
if ([self diagonalDistanceFromPoint:_startingPoint toEndPoint:endPoint] >= 20.0f) {
self.state = UIGestureRecognizerStateRecognized;
}
}else{
self.state = UIGestureRecognizerStateFailed;
}
}
}];
}
- (BOOL)angleIsWithinDiagonalTolerance:(CGFloat)angle
{
// NSLog(@"%s",__PRETTY_FUNCTION__);
NSAssert1(_tolerance < 45.0f, @"DiagonalSwipeGestureRecognizer Error: tolerance property must be set to a value less than 45.0f. Otherwise, the gesture will be detected at any angle. If you don't care and want the swipe to be recognized at any angle, remove the NSAssert call from - %s.", __PRETTY_FUNCTION__);
// NSAssert(_tolerance < 45.0f, @"DiagonalSwipeGestureRecognizer Error: tolerance property must be set to a value less than 45.0f. Otherwise, the gesture will be detected at any angle. If you don't care and want the swipe to be recognized at any angle, remove the NSAssert call from -[MMDiagnoalGestureRecognizer angleIsWithinDiagonalTolerance:].");
if (angle >= 45.0f - _tolerance && angle <= 45.0f + _tolerance) {
return YES;
}else if (angle <= - (45.0f - _tolerance) && angle >= - (45.0f + _tolerance)) {
return YES;
}else if (angle >= 135.0f - _tolerance && angle <= 135.0f + _tolerance) {
return YES;
}else if (angle <= - (135.0f - _tolerance) && angle >= - (135.0f + _tolerance)) {
return YES;
}else{
return NO;
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[self touchesEnded:touches withEvent:event];
self.state = UIGestureRecognizerStateChanged;
}
- (void)reset {
//don't call, will be called automatically.
}
@end