在主视图上添加UIPinchGestureRecognizer并检测子视图上的触摸

时间:2013-07-11 09:22:45

标签: ios hittest subviews uipinchgesturerecognizer

我在主UITextView([自我展示])上添加了一些子视图(UIView)来缩放/捏合并在屏幕上拖动它们。对于带有标记的一个subview,一切正常(mytextview1.tag = 1)。

但是如何告诉UIPinchGestureRecognizer有多个subview? 换句话说:如何检测当前触及的subview并给它一个标记值? 某种最热门的测试(单指触摸@ subview)?

出于可用性原因,我想使用主视图。我可以在每个subview附加这两个手指的手势,但它们可以小到缩放...

以下是带有标记的一个subview的代码:

UIPinchGestureRecognizer *twoFingerPinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(twoFingerPinch:)];
[[self view] addGestureRecognizer:twoFingerPinch];


- (void)twoFingerPinch:(UIPinchGestureRecognizer *)recognizer
{
    NSLog(@"Pinch scale: %f", recognizer.scale);

    mytextview1.tag = 1; // please give an idea to detect current touched subview
    UITextView *myViewWithTag = (UITextView *)[self.view viewWithTag:1];

    UITextView *myViewWithTag = (UITextView *)recognizer.view;
    CGPoint location = [recognizer locationInView:recognizer.view];
    NSLog(@"location: %@", NSStringFromCGPoint(location));

    UIFont *font = [myViewWithTag font];
    CGFloat pointSize = [font pointSize];
    NSString *fontName = [font fontName];

    pointSize = ((recognizer.velocity > 0) ? 1.0 : -1.0) * 1 + pointSize;
    if (pointSize < 13) pointSize = 13;
    if (pointSize > 120) pointSize = 120;

    [myViewWithTag  setFont:[UIFont fontWithName:fontName size:pointSize]];

    CGRect frame = myViewWithTag.frame;
    frame.size.height = myViewWithTag.contentSize.height;
    myViewWithTag.frame = frame;
}

3 个答案:

答案 0 :(得分:1)

twoFingerPinch:中,您可以查看手势识别器的state

如果state为UIGestureRecognizerStateBegan,那么您可以通过hitTest:withEvent:或自定义例程检测基础视图并将其存储在某处(比如像UIView * _draggingView这样的ivar)。

如果状态为UIGestureRecognizerStateEndedUIGestureRecognizerStateCancelled,则会忘记存储的视图(_draggingView = nil)。

如果state is other,则缩放存储的视图(_draggingView)。

- (void)twoFingerPinch:(UIPinchGestureRecognizer *)recognizer
{
    switch([recognizer state])
    {
        case UIGestureRecognizerStateBegan:
        {
            CGPoint location = [recognizer locationInView:recognizer.view];
            UIView* view = [recognizer.view hitTest:location withEvent:nil];
            if(%view is fine to use%)
            {
                _draggingView = view;
            }

        break;
        }


        case UIGestureRecognizerStateEnded:
        case UIGestureRecognizerStateChanged:
        {
            _draggingView = nil;

        break;
        }
    }    

    if(_draggingView)
    {
        // scale _draggingView
    }
}

答案 1 :(得分:0)

使用

hitTest:withEvent:

返回包含指定点的视图层次结构(包括其自身)中接收器的最远后代。

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

首先从Gesture识别器对象

获取触摸点
- (void)twoFingerPinch:(UIPinchGestureRecognizer *)recognizer
{
   CGPoint touchPoint = [recognizer locationInView:self.view];
   UIView *touchView = [self.view hitTest:touchPoint withEvent:nil];
   if(touhView isKindOfClass:[UITextView class])
{
}
}

PS:我希望我没有写错语法。这是我写的没有Mac。

答案 2 :(得分:0)

<强>好!

我必须清理代码,但可行。 一件事:由于某种原因,它不会以UIGestureRecognizerStateEnded结束...... 标签值为0,这很好......但backgroundcolor不是alpha:0.0 这是代码:

    UIPinchGestureRecognizer *twoFingerPinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(twoFingerPinch:)];
twoFingerPinch.cancelsTouchesInView = FALSE;
twoFingerPinch.delaysTouchesEnded = TRUE; // <---- this line is essential
[[self view] addGestureRecognizer:twoFingerPinch];

//某个开关和viewWithTag是我的朋友; - )

- (void) twoFingerPinch:(UIPinchGestureRecognizer *) recognizer {
NSLog(@"Detected a pinch gesture");

CGPoint touchPoint = [recognizer locationInView:self.view];
NSLog(@"touchPoint: %@", NSStringFromCGPoint(touchPoint));
UIView *touchView = [self.view hitTest:touchPoint withEvent:nil];

switch (recognizer.state) {

    case UIGestureRecognizerStateBegan:
        NSLog(@"began");

        if([touchView isKindOfClass:[UITextView class]]) {
            touchView.tag = 1;
            NSLog(@"touchView: %ld", (long)touchView.tag);
            touchView.backgroundColor =[UIColor colorWithRed: 0.0 green: 0.0 blue: 0.0 alpha: 0.5];
        }
    break;

    case UIGestureRecognizerStateChanged:
        NSLog(@"changed");
    break;

    case UIGestureRecognizerStateCancelled:
        NSLog(@"cancelled");
        touchView.tag = 0;
        touchView.backgroundColor =[UIColor colorWithRed: 0.0 green: 0.0 blue: 0.0 alpha: 0.0];
    break;

    case UIGestureRecognizerStateFailed:
        NSLog(@"failed");
        touchView.tag = 0;
        touchView.backgroundColor =[UIColor colorWithRed: 0.0 green: 0.0 blue: 0.0 alpha: 0.0];
    break;

    case UIGestureRecognizerStateEnded:
        NSLog(@"ended");
        touchView.tag = 0;
        NSLog(@"touchView: %ld", (long)touchView.tag);
        touchView.backgroundColor =[UIColor colorWithRed: 0.0 green: 0.0 blue: 0.0 alpha: 0.0];

    break;

    default:

        touchView.tag = 0;
        touchView.backgroundColor =[UIColor colorWithRed: 0.0 green: 0.0 blue: 0.0 alpha: 0.0];

    break;
}
    UITextView *myViewWithTag = (UITextView *)[self.view viewWithTag:1];
    // UITextView *myViewWithTag = (UITextView *)recognizer.view;

    UIFont *font = [myViewWithTag font];
    CGFloat pointSize = [font pointSize];
    NSString *fontName = [font fontName];

    pointSize = ((recognizer.velocity > 0) ? 1.0 : -1.0) * 1 + pointSize;
    if (pointSize < 13) pointSize = 13;
    if (pointSize > 120) pointSize = 120;

    [myViewWithTag  setFont:[UIFont fontWithName:fontName size:pointSize]];

    CGRect frame = myViewWithTag.frame;
    frame.size.height = myViewWithTag.contentSize.height;
    myViewWithTag.frame = frame;

}