问题描述
如果您有普通的 UITextView
,其中包含大量文本,则可以上下滑动:
If you have a normal UITextView
with loads of text in it you can swipe up and down:
- 如果以非常水平的方向向左或向右滑动,则不会发生
- 如果以很小的角度向左或向右滑动,则将向上滑动或down
因此,显然存在某种类定义,它告诉 UITextView
何时对滑动做出反应,何时不做出响应。我猜是类似maximumVariance常数。
So there is obviously some kind of class definition which tells the UITextView
when to react to a swipe and when not to. Something like a maximumVariance constant, I guess.
我的问题是我试图将 UITextView
子类化为启用向左/向右滑动。但是,您将需要沿相当大的直线滑动,否则,您将向上或向下滑动。所以我的问题是,是否有某种方法可以重新定义UITextView的标准方差变量?
My problem is that I'm trying to subclass an UITextView
to enable left/right swipe. However, you will need to swipe in a pretty straight line, otherwise, you'll get an up or down swipe. So my question is if there is someway to re-define the standard variance variable of an UITextView?
这是我的子类.m文件。请注意, kMaximumVariance
并没有任何实际作用,因为标准 UITextView
类提供的任何方差都会覆盖此内容:
Here is my subclass .m file. Note that the kMaximumVariance
doesn't really have any effect as this is overwritten by whatever variance the standard UITextView
class provides:
//
// SwipeTextView.m
// Swipes
//
#import "SwipeTextView.h"
#import "PageView.h"
#define kMinimumGestureLength 15
#define kMaximumVariance 100
@implementation SwipeTextView
@synthesize delegate, gestureStartPoint;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
UITouch *touch =[touches anyObject];
gestureStartPoint = [touch locationInView:self];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesMoved:touches withEvent:event];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesEnded:touches withEvent:event];
[self resignFirstResponder]; // this hides keyboard if horizonal swipe
UITouch *touch = [touches anyObject];
CGPoint currentPosition = [touch locationInView:self];
CGFloat deltaXX = (gestureStartPoint.x - currentPosition.x); // positive = left, negative = right
CGFloat deltaYY = (gestureStartPoint.y - currentPosition.y); // positive = up, negative = down
CGFloat deltaX = fabsf(gestureStartPoint.x - currentPosition.x); // will always be positive
CGFloat deltaY = fabsf(gestureStartPoint.y - currentPosition.y); // will always be positive
NSLog(@"deltaXX (%.1f) deltaYY (%.1f) deltaX (%.1f) deltaY (%.1f)",deltaXX, deltaYY, deltaX, deltaY);
if (deltaX >= kMinimumGestureLength && deltaY <= kMaximumVariance) {
if (deltaXX > 0) {
NSLog(@"Horizontal Left swipe - FINISHED detected");
}
else {
NSLog(@"Horizontal Right swipe - FINISHED detected");
}
}
}
@end
编辑:
建议取消达到 UITextView
的触摸(见下文):
Suggestion to cancel touches reaching UITextView
(see below):
// Prevent recognizing touches
- (BOOL)gestureRecognizer:(UISwipeGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if ([gestureRecognizer direction] == UISwipeGestureRecognizerDirectionLeft) {
// Left swipe: I want to handle this
return YES;
}
if ([gestureRecognizer direction] == UISwipeGestureRecognizerDirectionRight) {
// Right swipe: I want to handle this
return YES;
}
if ([gestureRecognizer direction] == UISwipeGestureRecognizerDirectionUp) {
// Up swipe: textView needs to handle this
return NO;
}
if ([gestureRecognizer direction] == UISwipeGestureRecognizerDirectionDown) {
// Down swipe: textView needs to handle this
return NO;
} else
return YES;
}
-(void)viewDidLoad
{
UITapGestureRecognizer *GesRec = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doSomething:)];
[GesRec setCancelsTouchesInView:NO];
[self addGestureRecognizer:GesRec];
[GesRec release];
}
-(void)doSomething
{
NSLog(@"doSomething");
}
推荐答案
尝试添加到视图并设置设置为false,以免滑动手势通过。
Try adding an UISwipeGestureRecognizer
to the view and set cancelsTouchesInView
to false so the swipe gesture is not passed through. This should let you detect left and right motion more accurately.
如果这样做不能解决问题,请实现自己的 UIGestureRecognizer子类
If this doesn't do the trick, implement your own subclass of UIGestureRecognizer
and add that instead.
编辑
您添加控制器的 viewDidLoad
方法中的 UITextView
的手势识别器。
You add the gesture recognizer to the UITextView
in your controller's viewDidLoad
method.
在您的委托方法中,您不能在 gestureRecognizer:shouldReceiveTouch中返回
,因为这意味着手势识别器不会检查传入的触摸对象。在您的情况下,您想在水平滑动时返回 NO
。 YES
,否则返回 NO
,因此,垂直滑动会在水平滑动已由您处理。
In your delegate methods, you can't return NO
in gestureRecognizer:shouldReceiveTouch:
because it means the gesture recognizer won't examine the incoming touch object. In your case you want to return YES
when the swipe is horizontal and NO
otherwise, so vertical swipes are passed through while horizontal swipe is completed handled by you.
这篇关于定义UITextView的最大方差的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!