Question

I added some subviews (UITextView) on main UIView ([self view]) to scale/pinch and dragging them around the screen. Everything works fine for ONE subview with a tag (mytextview1.tag = 1).

But how to tell the UIPinchGestureRecognizer that there is more than one subview? In other words: How to detect the current touched subview and give it a tag value? Some kind of hittest (one finger touch @ subview)?

I want to use the main view for usability reasons. I could attach this two finger gestue on every subview but they can be to small for scaling...

Here the code for ONE subview with a tag:

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;
}
Was it helpful?

Solution

In twoFingerPinch: you may check the state of the gesture recognizer:

If state is UIGestureRecognizerStateBegan then you detect via hitTest:withEvent: or custom routine the underlying view and store it somewhere (say ivar like UIView* _draggingView).

If state is UIGestureRecognizerStateEnded or UIGestureRecognizerStateCancelled you forget that stored view (_draggingView = nil).

If state is other then above you scale stored view (_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
    }
}

OTHER TIPS

Use

hitTest:withEvent:

Returns the farthest descendant of the receiver in the view hierarchy (including itself) that contains a specified point.

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

First get the touch Point from Gesture recogniser Object

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

PS: I hope I have not written wrong syntax. This i am writing without Mac.

Okay!

I have to clean up the code but it works. One thing: For some reason it doesn't realy end with UIGestureRecognizerStateEnded... The tag value is 0 that's fine... but the backgroundcolor doesn't alpha: 0.0 Here is the code:

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

// some switch and the viewWithTag is my friend ;-)

- (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;

}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top