开发者

UITapGestureRecognizer and auto correction

开发者 https://www.devze.com 2023-03-23 19:23 出处:网络
I have the following code: - (void)viewDidLoad { UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self

I have the following code:

- (void)viewDidLoad
{
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self 
                        开发者_C百科            action:@selector(dismissKeyboard)];
    [self.view addGestureRecognizer:tap];
    tap.cancelsTouchesInView = NO;
    tap.delegate = self;
    [tap release];
}

-(void)dismissKeyboard {
    [self.textField resignFirstResponder];
}

The textField has a clearButton and the auto correction is enabled. When I click on the clearButton, everything works fine and the keyboard still appears after the UITextField is cleared. However, when I don't want to accept the suggested auto correction, the keyboard disappears and my text is replaced by the suggested one.

I need the UITapGestureRecognizer because I have the UITextField inside a UITableView, so when the user clicks outside the UITextField, I want to resign the keyboard.

How can I fix this, so that it is possible to reject the auto correction, when the user wants, and the keyboard is still active? Why does this work properly with the clearButton, but not when rejecting the auto correction?

EDIT: It works properly with the clearButton because it is inside the UITextField. Thus, the gesture isn't fired. But when clicking on the suggested text correction, it is fired... Is there a way to check if the user clicked on the suggested text correction?


Here is the gesture delegate method I've implemented to solve the issue when tapping a blue autocorrected text :

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    BOOL handleTouch = NO;
    UIView *v = [self.view hitTest:p withEvent:nil];
    Class autocorrectionCancelClass = NSClassFromString(@"UIAutocorrectInlinePrompt");
    if( ![v isKindOfClass:UIControl.class] && ![v isKindOfClass:autocorrectionCancelClass]  && ![v isDescendantOfView:currentlyEditedTextView] )
    {
        handleTouch = YES;
    }

    return handleTouch;
}

On a tap of the autocorrection cancel button, v is a view of private SDK class UIAutocorrectInlinePrompt, but it is also a subview of the edited UITextField/UITtextView.

Edit : check on the class is better because for a UITextField, the UIAutocorrectInlinePrompt view is not a descendant of the field (tested on iOS 4.3 & 5.0). The issue is that this class can be renamed as it's a private one.


kenji's solution works nicely, except for excluding UIControl-s. Here is a cleaner and simpler version of his solution:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    return ![touch.view isKindOfClass:NSClassFromString(@"UIAutocorrectInlinePrompt")];
}
0

精彩评论

暂无评论...
验证码 换一张
取 消