Add UITapGestureRecognizer to UITextView without b

2019-01-17 23:33发布

问题:

How can I add a UITapGestureRecognizer to a UITextView but still have the touches getting through to the UITextView as normal?

Currently as soon as I add a custom gesture to my textView it blocks the tap for UITextView default actions like positioning the cursor.

var tapTerm:UITapGestureRecognizer = UITapGestureRecognizer()

override func viewDidLoad() {
    tapTerm = UITapGestureRecognizer(target: self, action: "tapTextView:")
    textView.addGestureRecognizer(tapTerm)
}

func tapTextView(sender:UITapGestureRecognizer) {
    println("tapped term – but blocking the tap for textView :-/")
…
}

How can I process taps but keep any textView behaviour like cursor positioning as is?

回答1:

To do that make your view controller adopt to UIGestureRecognizerDelegate and override should recognize simultaneously with gesture recognizer method like:

override func viewDidLoad() {
    tapTerm = UITapGestureRecognizer(target: self, action: "tapTextView:")
    tapTerm.delegate = self
    textView.addGestureRecognizer(tapTerm)
}

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {

    return true
}


回答2:

In case anyone came here looking for @Zell B.'s answer in Objective C, here's the code:

- (void)viewDidLoad {
    [super viewDidLoad];

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(textViewTapped:)];
    tap.delegate = self; 
    tap.numberOfTapsRequired = 1; 
   [self.textView addGestureRecognizer:tap];
}   

- (void)textViewTapped:(UITapGestureRecognizer *)tap {
    //DO SOMTHING 
}

#pragma mark - Gesture recognizer delegate

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES; 
}

PS: Don't forget < UIGestureRecognizerDelegate >



回答3:

Swift 4.2
The following steps allows me to escape a full-screen UITextView with a tap, whilst allowing to scroll the contents of the UITextView:

  1. Disconnected the UIGestureRecognizer from the UITableView.
  2. Made a CustomTextView: UITextView.
  3. Added a 'sender' var to the particular UIViewController with the CustomTextView.
  4. Trap for 'Touches Ended...'
  5. Call for an excape function within the sender UIViewController.

class CustomTextView: UITextView {
    var sender: DocViewController?

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let controller = sender {
            controller.handleSwipeGesture()
        }
    }
}

I can either scroll the contents of the UITextView or merely tap to exit.
The 'sender' is set from the hosting UIViewController at creation.