检测 iOS8 中 UITextField 中的退格键

2023-11-27

为了检测退格键,我已经覆盖了DeleteBackward方法(适用于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");
    }
}

当我按“退格”按钮时,什么也没有发生。我预计应该出现“DeleteBackward”消息

环境:iOS8、Xamarin

Edit: 0

Objective-c 上的类似问题:检测 UITextField 中的退格键

我已经做了额外的检查。DeleteBackward方法来自UI按键输入协议,所以我检查了insertText方法,这个方法效果很好。

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

我查过deleteBackward在 Objective-C 上它也运行得很好。

您对如何在 iOS8 中的 UITextField 中检测退格键有什么想法吗?

您能否解释一下为什么DeleteBackward方法没有被调用?

Edit: 1

我已经向 Xamarin 提交了同样的问题forum。看起来像是 iOS 8 + xamarin 中的一个错误,因为在 iOS 7.1 中工作得很好。

这是一个错误。这是details


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

这段代码稍微位于私有 API 的红线之前,但是您使用它应该没有问题。我的带有此代码的应用程序位于应用程序商店中。

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

- (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;
}

解释一下,我们调用此方法的超级实现以避免丢失继承的代码。之后我们要打电话-deleteBackward如果没有文字并且iOS版本在8-8.2之间。

EDIT: 2015 年 1 月 28 日

对子类 UITextField 的 -deleteBackward 方法进行子类化也可能会有所帮助。这修复了一些条件错误。其中之一是如果您使用自定义键盘。这是该方法的一个示例。

- (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:@""];
        }
    }
}

EDIT:答案翻译为 Xamarin,因为原始问题是针对 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 上验证

EDIT: 2015 年 4 月 14 日

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

EDIT: 2015 年 7 月 24 日

正如 @nischalhada 评论的那样,存在一种状态,其中文本字段-textField:shouldChangeCharactersInRange:replacementString:被调用两次。使用自定义键盘时,iOS >= 8.3 上存在此问题。我的解决方案并不理想,但它可以完成工作,我不确定是否还有其他方法。由于对此方法的两次调用都是在同一个运行循环上执行的,因此我们将使用 bool 来跟踪何时执行代码,并使用调度异步来重置 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;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

检测 iOS8 中 UITextField 中的退格键 的相关文章

随机推荐

  • 解析Java源代码

    我被要求开发一个软件 它应该能够创建输入Java源代码的流程图 控制流 于是我开始研究并得出以下解决方案 要创建流程图 控制流 我必须识别给定源代码中的控制语句和函数调用现在我有两种识别方法 通过编写我自己的语法来解析源代码 我认为这是一个
  • 如何从外部软件调用证明助手Coq

    如何从外部软件调用证明助手Coq Coq 有一些 API 吗 Coq 命令行界面是否足够丰富 可以在文件中传递参数并在文件中接收响应 我对 Java 或 C 桥感兴趣 这是合理的问题 Coq 并不是一种常见的商业软件 人们可以从中获得开发人
  • 如何将匿名类型作为参数传递?

    如何将匿名类型作为参数传递给其他函数 考虑这个例子 var query from employee in employees select new Name employee Name Id employee Id LogEmployees
  • 全局 var 与共享实例 swift

    Swift 中的全局变量和共享实例有什么区别 它们各自的使用领域是什么 任何人都可以根据 Swift 澄清他们的概念吗 全局变量是在文件顶层声明的变量 所以如果我们有一个名为Bar 您可以存储对实例的引用Bar在这样的全局变量中 var b
  • 为什么材质 FAB 在禁用时不改变颜色?

    我正在禁用材质浮动操作按钮 但当禁用设置为 true 时 颜色不会改变 我认为 Material 有一个 FAB 主题 禁用后它应该变成浅灰色 我不想在每次启用 禁用背景时添加代码来更改背景 我目前使用的材料版本 1 1 0 在代码中我只是
  • Java JMenuItem 动作监听器

    我的 JMenuBar 上的 ActionListener 需要一些帮助 没有错误 但是 每次我单击 JMenuItem 时 它都会触发与 JMenuItem 关联的所有操作 我的问题是 我在 ActionListener 代码中做得正确吗
  • Crashlytics:“我们缺少一个 dSYM 来处理崩溃”[关闭]

    Closed 这个问题需要细节或清晰度 目前不接受答案 Crashlytics 说 我们缺少 dSYM 来处理崩溃 当我尝试从 Xcode 7 1 下载 dSYM 时 我得到 没有可供下载的 dsym 我今天遇到了同样的问题 iTunes
  • 获取字典的随机样本[重复]

    这个问题在这里已经有答案了 我正在使用一本大字典 由于某种原因 我还需要处理该字典中的小随机样本 我怎样才能得到这个小样本 例如长度为2 这是一个玩具模型 dy a 1 b 2 c 3 d 4 e 5 我需要在 dy 上执行一些涉及所有条目
  • 通过 buildForm() 中的 $options 访问变量

    我想传递一个布尔值给我的DogForm dogForm new DogForm null array has cats gt this gt getUser gt hasCats form this gt createForm dogFor
  • mysql 按日期选择总和组

    快速提问 我有下表 total o date 35 01 11 2009 19 32 44 41 5 01 12 2009 22 33 49 61 5 01 23 2009 22 08 24 66 02 01 2009 22 33 57 2
  • 获取 HTML5 范围滑块手柄的偏移位置

    有什么办法可以得到pixelHTML5 范围输入的滑块手柄的位置
  • Python 3.7 安装无法在 openSUSE Leap 42.3 上运行

    在 openSUSE Leap 42 3 上从源代码构建和安装 Python 3 7 0 时 安装到 usr local 的默认 configure 会出现严重的 python 错误 openSUSE Leap 42 3 Python3 软
  • 如何在没有嵌入的情况下使用tensorflow seq2seq?

    我一直在研究使用张量流进行时间序列预测的 LSTM 现在 我想尝试序列到序列 seq2seq 在官方网站上有一个教程 展示了带有嵌入的 NMT 那么 如何在没有嵌入的情况下使用这个新的 seq2seq 模块呢 直接使用时间序列 序列 1 E
  • matplotlib轮廓可以匹配像素边缘吗?

    如何勾画像素边界matplotlib 例如 对于如下所示的半随机数据集 the code block that follows is irrelevant import numpy as np k for s in 2103 1936 22
  • 为什么我可以匿名子类化枚举而不是最终类?

    这段代码 public class Sandbox public enum E VALUE Override public String toString return I m the value Override public Strin
  • jQuery 动画透明

    block li hover function this animate backgroundColor 000 function this animate backgroundColor fff 需要改变 fff到没有颜色 动画应该发生于
  • 使用 Typescript 时,es6 Map() 不会编译为 es5

    我刚刚开始第一次在项目中使用 Typescript 我真的很想使用 Map 来组织一小组键值对 不幸的是 当打字稿被编译 使用 gulp 和 gulp typescript 为普通 ES5 JavaScript 时 Map 仍然存在 我需要
  • 在 ASP.NET 中,获取请求的基本 URl 的最快方法是什么?

    在 ASP NET 中是否有快速获取方案 主机 端口 仅当不是 80 时 和应用程序路径的方法 据我所知 我需要组装以下部分 请求 Url 方案 Request Url SchemeDelimiter Request Url Authori
  • Rails 模型调用控制器操作

    我需要从模型内部的方法调用控制器内部的操作 这是我在其他语言中经常做的事情 当使用 MVC 框架时 但是 我从未见过在 ruby on Rails 中这样做 该操作不会渲染任何内容 它只是更新会话变量 这实际上并不是您在 MVC 模式中通常
  • 检测 iOS8 中 UITextField 中的退格键

    为了检测退格键 我已经覆盖了DeleteBackward方法 适用于iOS5 var input new BackspaceTextField RectangleF Empty etc input BecomeFirstResponder