4

Steps to reproduce:

  1. Open anything with selectable text, e.g. any question.
  2. Hold down on some regular (non-editable) question text to select it.

Expected behavior: text is selected and the action menu pops up above it (containing Copy/Define/etc. actions).

Actual behavior: text is selected, but the action menu does not pop up. The usual iOS behavior is that tapping on the selected text should also/again trigger the menu; it does not.

nogo

Actual necessary steps to open the menu: tap elsewhere to deselect the text, select again, menu works as expected now.

go

  • App Version: 1.4.3.7
  • Device: iPhone 5c (Global)
  • OS Version: Version 9.2.1 (Build 13D15)
3

This will be fixed in 1.4.4.2, shipping in mid-February.

I used a variation of this fix and am actually astonished at how many apps exhibit this problem that I've never noticed before.

Fix is as follows:

  1. Create a UIWebView subclass that overrides canBecomeFirstResponder to always be true.

  2. Add a long press gesture recognizer to that view (or a parent view).

  3. Have that gesture recognizer simultaneously recognize with all other gesture recognizers.

  4. When recognized, if a child view isn't first responder, become first responder. If you always try becoming first responder on long press, you will break reselection, so it needs a quick recursive check.

That this looks like in practice:

// Part 1 from https://stackoverflow.com/a/33077990/860000
@interface _SEHTMLWebView : UIWebView
@end

@implementation _SEHTMLWebView

- (BOOL)canBecomeFirstResponder
{
    return YES;
}

@end

...

// Part 2 from https://stackoverflow.com/a/33077990/860000
- (void)addLongPressGestureRecognizer
{
    UIGestureRecognizer *longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressGestureRecognizer:)];
    longPressGestureRecognizer.delegate = self;
    [self addGestureRecognizer:longPressGestureRecognizer];
}

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

- (void)longPressGestureRecognizer:(UILongPressGestureRecognizer *)gestureRecognizer
{
    if (gestureRecognizer.state == UIGestureRecognizerStateRecognized) {
        if (![self.webView SE_findFirstResponderInSubviews]) {
            [self.webView becomeFirstResponder];
        }
    }
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .