SwiftUI文本框手动触发提交(iOS)

12

我遇到的问题是十进制格式化程序(decimalFormatter)只有在文本字段(textField)触发提交事件(commit event),即按下回车键时才会触发并更新绑定。

因此,我想知道如何手动触发文本字段的提交事件?

以下格式化程序代码将接受任何数字,并确保它始终具有一个小数位(例如--10.5),如果插入了字母字符,则还原输入回到之前的有效输入,这正是我想要的。

import SwiftUI
import Combine

struct StandardRegimen: View {
    @State private var totalDose = 6000.0

    private var decimalFormatter: NumberFormatter = {
        let f = NumberFormatter()
        f.isLenient = true
        f.numberStyle = .none
        f.maximumFractionDigits = 1
        f.minimumFractionDigits = 1
        f.alwaysShowsDecimalSeparator = true
        return f
    }()

    var body: some View{
       return
       VStack(alignment:.center,spacing:10){
            TextField("?", value:$totalDose, formatter: self.decimalFormatter, onCommit: {
               print("COMMITED!");
            }).font(.system(size: 25.0))
            .textFieldStyle(RoundedBorderTextFieldStyle())
            .keyboardType(.decimalPad)
       }
    }

如果您删除修改器代码.keyboardType(.decimalPad)并在键盘上按回车键,它将触发COMMITED消息并关闭键盘。

然而,如果您保留小数点修改器,则没有办法触发提交,因为小数点没有返回键。

我在这里写了一个答案,解释如何通过点击开放空间区域来让键盘消失(How to hide keyboard when using SwiftUI?

我研究过使用绑定到字符串和使用文本字段的text初始化参数而不是值的其他解决方案,因为这将与绑定值正常工作,但这会导致一些非常奇怪的结果,因为它在每次按键时更新(例如——用户很难输入和编辑错误),而我希望它仅在提交后运行格式化程序,我想在用户点击以关闭键盘时进行提交,因为在小数键盘上我没有返回键选项。

欢迎提供任何有关解决此问题的方法。


我也遇到了同样的挑战。Joseph,你解决这个问题了吗? - damirstuhec
1
据我所知,目前还没有解决这个问题的方法,不幸的是在此之前我无法使用SwiftUI,因此现在只能使用界面构建器进行编码。 - Joseph Astrahan
1个回答

5
这可能有点晚了,但我已经想到了一种解决方案,可以使用其他键盘类型与TextField一起使用:我使用onEditingChanged事件而不是onCommit事件,并检查传递到方法中的Bool值。如果该值为false,则会复制onCommit方法的行为。这是您的代码,但格式化以使用我的方法:
import SwiftUI
import Combine

struct StandardRegimen: View {
    @State private var totalDose = 6000.0

    private var decimalFormatter: NumberFormatter = {
        let f = NumberFormatter()
        f.isLenient = true
        f.numberStyle = .none
        f.maximumFractionDigits = 1
        f.minimumFractionDigits = 1
        f.alwaysShowsDecimalSeparator = true
        return f
    }()

    var body: some View{
       VStack(alignment:.center,spacing:10){
            TextField("?", value:$totalDose, formatter: self.decimalFormatter, onEditingChanged: { edit in
                // Editing has finished
                if !edit {
                    print("COMMITED!");
                }
            }).font(.system(size: 25.0))
            .textFieldStyle(RoundedBorderTextFieldStyle())
            .keyboardType(.decimalPad)
       }
    }
}

这个解决方案适用于所有键盘类型(我只测试了普通键盘和数字小键盘)。


这个很棒!遗憾的是,除非苹果真的想让我们使用花哨的选择器,否则onCommit与其他键盘并没有被清除。 - got2jam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接