在iOS8中检测UITextField中的退格 [英] Detect backspace in UITextField in iOS8

查看:252
本文介绍了在iOS8中检测UITextField中的退格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了检测Backspace,我覆盖了 DeleteBackward 方法(应该适用于iOS5 +)

For detecting the Backspace, I've overridden DeleteBackward method (should work with iOS5+)

var input = new BackspaceTextField(RectangleF.Empty);
etc
input.BecomeFirstResponder();

这是代码

public sealed class BackspaceTextField : UITextField
{
    public BackspaceTextField(RectangleF frame) : base(frame)
    {
    }

    public override void DeleteBackward ()
    {
        Console.WriteLine ("DeleteBackward");
    }
}

当我按Backspace按钮时没有任何反应。我希望应该出现DeleteBackward消息

When I press "Backspace" button nothing happens. I expect "DeleteBackward" message should appear

环境:iOS8,xamarin

Environment: iOS8, xamarin

编辑:0

关于objective-c的类似问题:在UITextField中检测退格

Similar question on objective-c: Detect backspace in UITextField

我已经完成了额外的检查。 DeleteBackward 是来自 UIKeyInput 协议,所以我检查 insertText 方法,这种方法可以正常工作。

I've done additional check. DeleteBackwardis method from UIKeyInput protocol, so I've check insertText method, this method works perfactly.

public override void InsertText (string text)
{
   base.InsertText(text);
}

我已经检查过 deleteBackward 在objective-c上它也很完美。

I've checked deleteBackward on objective-c and it works perfectly too.

您是否有任何想法如何在iOS8中的UITextField中检测退格?

Do you have any ideas how to detect backspace in UITextField in iOS8?

您能澄清一下为什么 DeleteBackward 方法未被调用?

Could you please clarify why the DeleteBackward method was not called?

编辑:1

我已经向Xamarin提交了同样的问题论坛。看起来像iOS8 + xamarin中的一个错误,因为在iOS 7.1中可以正常工作。

I've submitted the same question to the Xamarin's forum. Looks like a bug in iOS8 + xamarin, because in iOS 7.1 works perfactly.

这是一个错误。这是详情

推荐答案

很多人都说这是一个错误,但由于这个问题在GM中仍然存在,我开始认为它可能是逻辑上的变化。话虽如此,我为我的应用程序编写了这段代码,并在iOS 7-8上进行了测试。

A lot of people have been saying this is a bug, but being that this problem still exists in the GM I'm starting to think it might be a change in logic. With that said, I wrote this bit of code for my app and have tested it on iOS 7-8.

此代码稍微超出私有API的红线,但是使用它应该没问题。我的应用程序使用此代码在应用商店中。

This code is slightly before the red line of private API's, however you should have no problem using it. My app with this code is in the app store.

将以下方法添加到 UITextField 子类。

Add the following method to your UITextField subclass.

- (BOOL)keyboardInputShouldDelete:(UITextField *)textField {
    BOOL shouldDelete = YES;

    if ([UITextField instancesRespondToSelector:_cmd]) {
        BOOL (*keyboardInputShouldDelete)(id, SEL, UITextField *) = (BOOL (*)(id, SEL, UITextField *))[UITextField instanceMethodForSelector:_cmd];

        if (keyboardInputShouldDelete) {
            shouldDelete = keyboardInputShouldDelete(self, _cmd, textField);
        }
    }

    BOOL isIos8 = ([[[UIDevice currentDevice] systemVersion] intValue] == 8);
    BOOL isLessThanIos8_3 = ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.3f);

    if (![textField.text length] && isIos8 && isLessThanIos8_3) {
        [self deleteBackward];
    }

    return shouldDelete;
}

为了解释一下,调用super的实现方法以避免丢失继承的代码。如果没有文字且iOS版本在8-8.2之间,打算打电话给 -deleteBackward

To explain a little, were calling the super's implementation of this method to avoid losing inherited code. After were going to call -deleteBackward if there is no text and the iOS version is between 8-8.2.

编辑:1/28/15

将子类UITextField的-deleteBackward方法子类化也可能会有所帮助。这修复了一些有条件的错误。一种是如果你使用自定义键盘。下面是该方法的一个示例。

It also might be helpful to subclass the -deleteBackward method of your subclassed UITextField. This fixes a few conditional bugs. One being if you use a custom keyboard. Heres an example of the method.

- (void)deleteBackward {
    BOOL shouldDismiss = [self.text length] == 0;

    [super deleteBackward];

    if (shouldDismiss) {
        if ([self.delegate respondsToSelector:@selector(textField:shouldChangeCharactersInRange:replacementString:)]) {
            [self.delegate textField:self shouldChangeCharactersInRange:NSMakeRange(0, 0) replacementString:@""];
        }
    }
}

编辑:答案翻译成Xamarin,因为最初的问题是为Xamarin问这个。

EDIT: answer translated to Xamarin, as the original question asked this for Xamarin.

    [Preserve]
    [Export("keyboardInputShouldDelete:")]
    private bool KeyboardInputShouldDelete(UITextField textField)
    {
        var shouldDelete = true;

        if(RespondsToSelector(new Selector("_cmd")))
        {
            //Call base class
            shouldDelete = Messaging.bool_objc_msgSend_IntPtr(Handle, Selector.GetHandle("_cmd"), textField.Handle);
        }

        //ios8 "bug": always call DeleteBackward even if the field is empty
        if(Utils.IsIos8)
        {
            DeleteBackward();
            return false;
        }

        return shouldDelete;
    }

在ios 7.1和8.1上验证

Verified on ios 7.1 and 8.1

编辑:4/14/15

自iOS 8.3起,此问题已修复。 Objective-C代码已更新以反映更改。

As of iOS 8.3 this issue has been fixed. The Objective-C code has been updated to reflect the changes.

编辑:7/24/15

正如@nischalhada所评论的那样,存在一个状态,其中文本字段 -textField:shouldChangeCharactersInRange:replacementString:被调用两次。使用自定义键盘时,iOS> = 8.3时存在问题。我的解决方案并不理想,但是它完成了工作,我不确定是否还有其他办法。由于对此方法的两次调用都是在同一个运行循环中执行的,因此我们将使用bool来跟踪何时执行代码以及调度async以重置bool。

As @nischalhada commented, a state exists where the text fields -textField:shouldChangeCharactersInRange:replacementString: is called twice. The problem exists on iOS >= 8.3 while using a custom keyboard. My solution is not ideal but it does the job and I'm not sure if there's any other way. Since both calls to this method are performed on the same run loop we'll use a bool to keep track of when to execute the code and a dispatch async to reset the bool.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    BOOL toReturn = NO;

    if (!self.shouldTextFieldPreventChange) {
        self.shouldTextFieldPreventChange = YES;

        dispatch_async(dispatch_get_main_queue(), ^{
            // iOS8.3 custom keyboards might call this method along with internal iOS
            // code. Allowing changes on the next run loop helps avoid this issue.
            self.shouldTextFieldPreventChange = NO;
        });

        // do work...
    }

    return toReturn;
}

这篇关于在iOS8中检测UITextField中的退格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆