使用子类或委托解决方案集成问题检测文本字段上的退格事件

问题描述 投票:0回答:2

作为前言,这个问题已经使用几种不同的方法解决了 - 我将在此处留下具有解决方案的堆栈溢出帖子text

问题涉及检测何时按下 iOS 键盘上的“删除”或“退格”按钮。我特别希望能够检测何时在空文本字段上按下按钮

我一直坚持集成解决方案,我认为这是由于缺乏对某些中间步骤的理解。

以下是我认为可行的解决方案。

首先是集成这个委托功能:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    if let char = string.cString(using: String.Encoding.utf8) {
        let isBackSpace = strcmp(char, "\\b")
        if (isBackSpace == -92) {
            print("Backspace was pressed") // Or prefrom some operation 
        }
    }
    return true
}

第二个是子类化 UITextfield 类并创建一个覆盖函数:

class MyTextField: UITextField {
    override public func deleteBackward() {
        if text == "" {
             // do something when backspace is tapped/entered in an empty text field
        }
        // do something for every backspace
        super.deleteBackward()
    }
}

我想要实现的具体功能是在内容视图中切换 @FocuState 变量。例如:如果 (Second) TextField().isEmpty 并按下“删除”键,则 FocusStateOne = true。

这是一个带有几个不同文本字段的基本内容视图:

struct ContentView: View {
    @State private var textOne = ""
    @State private var textTwo = ""
    @FocusState private var oneFocus: Bool

    var body: some View {
        VStack {
            TextField("",text: $textOne)
  
                .padding()
                .focused($oneFocus)

            TextField("",text: $textTwo)
                .padding()

// Detect if TextField is empty and if "delete" is pressed, then @FocusState var oneFocus = true



            Text("Entered text: \(textOne)")
                .padding()
            Text("Entered text: \(textTwo)")
                .padding()
        }
    }
}

我尝试过子类化,这对我来说最有意义,但我不明白子类如何能够符合视图结构并通信/更改该视图中的变量。似乎我必须编写一些其他类型的函数来与内容视图内的变量进行通信,但我不确定。

就委托而言,我了解委托功能的基础知识,但似乎无法弄清楚如何将其实现到基本内容视图中。

大多数时候,我尝试这些解决方案中的任何一个时都会遇到与范围相关的问题,我认为有很多地方我不理解/做得正确。

在这两种解决方案中,就我正在尝试做的事情而言,哪一种更好?我只是对“中间”步骤有点迷失。我是 Swift 的初学者。

swift delegates uitextfield overriding subclass
2个回答
1
投票

下面给出了一个 swiftui 修饰符,当它的值发生变化时我们可以检查并执行任何操作,就像我在下面所做的那样。但关键是只有当价值发生变化时它才会起作用。第一次如果该字段为空并且您按退格键或删除键,它将不起作用,因为值没有变化。因此,您可以将以下修饰符附加到第二个文本字段并为其流程添加文本。

.onChange(of: textTwo) { newValue in
                    if newValue.isEmpty {
                        oneFocus = true
                    }
                }

让我知道这就是您想要的。如果是的话那就好,否则请给我留言,我们可以讨论一下。


0
投票

这是一个非常常见的问题,包装一个自定义的 UITextField 以便我们可以检测何时按下删除键并覆盖 deleteBackward(),然后创建符合 UIViewRepresentable 协议的组件将我们的自定义 UITextField 暴露给 SwiftUI,已被证明是最有效的方法到目前为止我已经发现并且按预期工作。 在这里您可以找到一个简单的用例(带有 4 个文本字段的屏幕,用于输入 4 个字符代码,请参见下图)并且它是完整的实现。希望有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.