繁体   English   中英

如何让 SwiftUI TextField 显示数字但也接受空值

[英]How to get SwiftUI TextField to show numbers but also accept an empty value

我正在尝试获取一个仅接受数字但也接受空值的文本字段(即它是一个可选字段)。 这是文本字段的样子:

TextField("Phone Number", value: $phoneNumber, formatter: numberFormatter)
    .disableAutocorrection(true)
    .autocapitalization(.none)

我的数字格式化程序如下所示:

@State private var numberFormatter: NumberFormatter = {
    var nf = NumberFormatter()
    nf.numberStyle = .none
    nf.zeroSymbol = ""    
    return nf
}()

我尝试了两种不同的解决方案,但都有问题。 第一个解决方案是将phoneNumber定义为可选整数Int? 以便TextField将接受空白输入:

@State var phoneNumber: Int? = nil

但是,这与TextField混淆了,因此当我通过应用程序更改其值时,更改不会更新实际变量phoneNumber 所以,当我去发送我的数据时, phoneNumber仍然保持在nil 我认为这与numberFormatter以及它如何不接受nil变量有关。

所以,我的第二个解决方案是将phoneNumber初始化为Int ,如下所示:

@State var phoneNumber: Int = 0

当我更改TextField中的文本时,此解决方案会更新phoneNumber 但是,当我输入 0 时,它只会在TextField框中显示一个空格(因为我在.zeroSymbol中定义了numberFormatter )。 当我尝试只放置一个空格(即删除所有文本)然后单击TextField时,它只是恢复为之前的数字。 当我在字段中输入一个非数字条目时也会发生同样的事情,我可以接受,因为它应该只接受数字,但我仍然希望允许用户包含一个空白条目。

我正在使用 XCode 并创建一个 iOS 应用程序。 感谢您的任何帮助。

一种可能的解决方案是通过代理绑定拦截输入/输出,并执行所需的额外验证/处理。

演示

使用 Xcode 13.3 / iOS 15.4 测试

这是主要部分:

TextField("Phone Number", value: Binding(
    get: { phoneNumber ?? 0},
    set: { phoneNumber = phoneNumber == $0 ? nil : $0 }
    ), formatter: numberFormatter)

项目中完整的测试模块

我发现的另一个解决方案是将phoneNumber设为默认为""的字符串。 然后,尝试通过Int(phoneNumber)将其转换为Int来验证它。 如果Int(phoneNumber) == nil ,则引发错误。 否则,您现在有一个新的可选整数,可以是 nil 或提供的整数:

var intPhoneNumber: Int?
        if phoneNumber == "" {
            intPhoneNumber = nil
        } else {
            intPhoneNumber = Int(phoneNumber)
            if intPhoneNumber == nil {
                completion(.failure(.custom(errorMessage: "Please enter a valid phone number. Try again.")))
                return
            } else if intPhoneNumber! < 0 {
                completion(.failure(.custom(errorMessage: "Invalid Phone Number. Please enter a valid 10 digit phone number.")))
                return
            } else if numberOfDigits(in: intPhoneNumber!) != 10 {
                completion(.failure(.custom(errorMessage: "Invalid Phone Number. Please enter a valid 10 digit phone number.")))
                return
            }
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM