定义UITextView的最大方差

时间:2011-09-29 13:18:42

标签: iphone objective-c cocoa-touch uitextview swipe

如果您有正常的UITextView,其中包含大量文字,您可以上下滑动:

  • 如果您在非常水平的线上向左或向右滑动,则不会发生任何事情
  • 如果您以非常小的角度向左或向右滑动,则会向上或向下滑动

所以显然有某种类定义告诉UITextView何时对滑动作出反应以及何时不作出反应。有点像maximumVariance常数,我猜。

我的问题是我正在尝试将UITextView子类化以启用左/右滑动。但是,您需要在相当直线上滑动,否则,您将进行向上或向下滑动。所以我的问题是,是否有一些重新定义UITextView的标准方差变量?

这是我的子类.m文件。请注意,kMaximumVariance实际上没有任何影响,因为标准UITextView类提供的任何差异都会覆盖它:

//
//  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的触摸(见下文):

// 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");
}

2 个答案:

答案 0 :(得分:1)

尝试向视图添加UISwipeGestureRecognizer并将cancelsTouchesInView设置为false,以便不会传递滑动手势。这样可以让您更准确地检测左右运动。

如果这不能解决问题,请实现自己的UIGestureRecognizer子类并添加它。

修改

您可以将手势识别器添加到控制器的UITextView方法中的viewDidLoad

在您的委托方法中,您无法在NO中返回gestureRecognizer:shouldReceiveTouch:,因为这意味着手势识别器不会检查传入的触摸对象。在您的情况下,您希望在滑动水平时返回YES,否则返回NO,因此在您完成水平滑动完成时会传递垂直滑动。

答案 1 :(得分:1)

不需要子类。将textView.userInteractionEnabled设置为NO,然后将透明的UIView放在textView上。无论如何处理你想要的UIView上的触摸和手势,并使textView以编程方式响应这些。