0

I have a UILabel that I have attached a touch, pinch, and rotate gesture to. The problem I am having is that there are only a few characters in it which can make it hard to rotate/pinch/touch. Is there a way that I can add a margin to the UILabel or add some area around the UILabel that will fire the rotate/pinch/touch action to make it easier to manipulate?

Here is an example of the method:

- (IBAction)handlePinch:(UIPinchGestureRecognizer *)recognizer {
    recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, recognizer.scale);
    currentAction = TEXT_STRETCHING;
    recognizer.scale = 1;
}
Tyler Hilbert
  • 2,107
  • 7
  • 35
  • 55
  • 1
    You could attach your gesture to your view that contains the label instead of attaching it to the label. Then you could check if the gesture is within the margin you want and forward the gesture to the label (or just handle it in the view). – keithbhunter Oct 10 '16 at 19:10
  • very simple these days: https://stackoverflow.com/a/58052952/294884 – Fattie Feb 07 '23 at 21:04

1 Answers1

2

There are a number of solutions for your issue:

  1. Add gesture to another, bigger view.
  2. If your label text is centered you can make the label itself wider and the appearance will remain as it was.
  3. You can subclass UILabel and override hitTest method. This way you can increase the area of gesture recognition for your custom view:

CustomLabel.m:

@implementation CustomLabel: UILabel 

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    CGRect bigRect = CGRectInset(self.bounds, -10, -10);
    return CGRectContainsPoint(bigRect, point);
}

@end

You can obviously customize the inset values for dx and dy to suit your needs.

More details about this method here: https://developer.apple.com/reference/uikit/uiview/1622533-pointinside?language=objc

Storyboard/xib

Set CustomLabel class instead of UILabel

ViewController.m:

Leave everything as is. Your handlePinch: method is just fine.

P.S. Perhaps it would be better to stick with UIButton instead of UILabel, but this technique may still be helpful.

alexburtnik
  • 7,661
  • 4
  • 32
  • 70
  • For option 3, would I replace the "return self" with the code I want to run? – Tyler Hilbert Oct 10 '16 at 21:00
  • No, just add it as is. This method implementation has nothing to do with the action you want to do when user interacts with the label. But with this override your custom view will catch all touches in a bigger frame than it acually have ("margin" value in all four directions) – alexburtnik Oct 10 '16 at 21:05
  • So with option 3 you still have to add your gesture recognizer as you did before – alexburtnik Oct 10 '16 at 21:06
  • Alright I added an example of what the code looks like to the question, how would I override that? PS it is in the method is currently in the ViewController. – Tyler Hilbert Oct 10 '16 at 21:14
  • @TylerHilbert I missed that you're using obj-c. Please have a look at the updated answer. I also replaced `hitTest` with `pointInside` method, because it is clearer and will have the same effect. In fact default implementation of hitTest calls pointInside. – alexburtnik Oct 10 '16 at 21:31
  • 1
    strongly suggest idea 1 – danh Oct 11 '16 at 01:46