UITextField EditingDidBegin 在 IOS 14.4 上触发了两次

Posted

技术标签:

【中文标题】UITextField EditingDidBegin 在 IOS 14.4 上触发了两次【英文标题】:UITextField EditingDidBegin triggered twice on IOS 14.4 【发布时间】:2021-04-26 08:31:19 【问题描述】:

我有两个文本字段。我想在点击第一个文本字段时打开一个底页。另一个文本字段定期接受用户输入。

这是我在produklistrikDropdown 文本字段与edittingDidBegin 时的触发器。

produkListrikDropDown.rx.controlEvent(.editingDidBegin)
            .subscribe(onNext:
                self.dismissKeyboard()
                print("produk Listrik Field did begin")
                self.viewModel.showProdukListrik()
            )
            .disposed(by: disposeBag)

在我从底部表格中选择产品后,它只需将字段的文本更改为我选择的文本。

viewModel.currentProdukListBehaviorSubject
            .map$0?.rawValue
            .subscribe(onNext:  [unowned self] in
                if produkListrikDropDown.text != $0 
                    produkListrikDropDown.text = $0
                
            )
            .disposed(by: disposeBag)

这是我的第二个文本字段配置。只是一个接收用户输入的常规文本字段。

idPelangganField.rx.text
            .bind(to: viewModel.currentIdPelangganBehaviorSubject)
            .disposed(by: disposeBag)

发生了什么

当我点击第一个文本字段并选择一个产品时,它的表现还不错。 但是当我点击第二个文本字段并返回第一个文本字段时,第一个文本字段上的 edittingDidBegin 触发了两次。这在 ios 12.4 上不会发生。

您可以克隆此 repo 以重现问题 https://github.com/Bobbyphtr/TextfieldDidEdittingProblem/tree/master

【问题讨论】:

你把代码放在什么函数里?你知道文本字段有一个inputView吗?您可能可以使用它来使您的代码更简单。 @DanielT。感谢您的建议,我会考虑使用inputView 进行进一步的实施。但是,即使我使用了inputView,我认为它们会被触发两次,与所述问题相同。 你把代码放在什么函数里? @DanielT。我把上面的所有代码都放在viewDidLoad 函数中。如果这不是您要找的答案,请详细说明,以便我提供更多所需的代码。 @DanielT。感谢您告诉我,我正在尝试重新创建此问题并将其上传到 github,以便您尝试找出答案。 【参考方案1】:

问题是您在textFieldShouldBeginEditing(_:) 中执行副作用。操作系统可以随意调用此函数,因为该函数的唯一用途是确定 SDK 是否应允许开始编辑文本字段。

阅读Command-Query Separation(不仅仅是***的文章。进行互联网搜索并阅读其他有关它的文章。)

它指出每个方法都应该是执行的命令 将数据返回给调用者的操作或查询,但不能同时返回两者。 换句话说,问一个问题不应该改变答案。1 更正式地说,方法应该返回一个值,如果它们是 引用透明,因此没有副作用。

解决您的问题的方法是使用带有轻击手势识别器的 UILabel,而不是文本字段。确保将标签的 isInteractionEnabled 设置为 true。


我在您的代码中也发现了第二个问题。 showBottomSheetPicker(selectionList:) 返回的 Observable 永远不会完成。确保在发送下一个事件后致电observer.onCompleted()

【讨论】:

所以这是否意味着我应该避免覆盖textFieldShouldBeginEditting,因为我可能会导致副作用?因为函数应该被认为是query 对吧?非常感谢你这篇有用的文章,我现在学到了新东西哈哈哈【参考方案2】:

我找到了一种更好的方法,而不会牺牲文本字段的使用。就像@Daniel T. 所说,我们可以在上面使用轻击手势识别器。我为 UITextField 放置了一个标记手势识别器并将其设置为接收touch down 事件。它消除了textFieldShouldBeginEditting(_:) 的任何副作用,并且不使用任何 RxSwift 进行调用。

【讨论】:

以上是关于UITextField EditingDidBegin 在 IOS 14.4 上触发了两次的主要内容,如果未能解决你的问题,请参考以下文章

在 UITextField 操作中将 UITextField 字符串转换为 Double

如何调整 UITextField 占位符文本以适合 UITextField 宽度?

如果添加了新的 UITextField,如何向下移动许多 UITextField

如果 UITextField 已经创建,不要在 Tap 上重新创建 UITextField

使用未声明类型的 UITextfield

猫猫学iOS之UITextField右边设置图片,以及UITextField全解