简体   繁体   English

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

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

I am trying to get a text field that only accepts numbers but will also accept an empty value (ie. it is an optional field).我正在尝试获取一个仅接受数字但也接受空值的文本字段(即它是一个可选字段)。 This is what the textfield looks like:这是文本字段的样子:

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

and my number formatter looks like this:我的数字格式化程序如下所示:

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

I have tried two different solutions yet both have problems.我尝试了两种不同的解决方案,但都有问题。 The first solution is to define phoneNumber as an optional integer Int?第一个解决方案是将phoneNumber定义为可选整数Int? so that the TextField will accept a blank input:以便TextField将接受空白输入:

@State var phoneNumber: Int? = nil

However, this messes with the TextField so that when I change its value via the app the changes don't update the actual variable phoneNumber .但是,这与TextField混淆了,因此当我通过应用程序更改其值时,更改不会更新实际变量phoneNumber So, when I go to send my data in, phoneNumber still stays at nil .所以,当我去发送我的数据时, phoneNumber仍然保持在nil I think this has something to do with the numberFormatter and how it wont't accept nil variables.我认为这与numberFormatter以及它如何不接受nil变量有关。

So, my second solution is to initialize phoneNumber as an Int like so:所以,我的第二个解决方案是将phoneNumber初始化为Int ,如下所示:

@State var phoneNumber: Int = 0

This solution does update phoneNumber when I change the text in the TextField .当我更改TextField中的文本时,此解决方案会更新phoneNumber However, it will only show a blank space in the TextField box when I type in 0 (because of my .zeroSymbol definition in the numberFormatter ).但是,当我输入 0 时,它只会在TextField框中显示一个空格(因为我在.zeroSymbol中定义了numberFormatter )。 When I try to just put a blank space (ie. delete all the text) and then click out of the TextField , it just reverts back to the number that it was before.当我尝试只放置一个空格(即删除所有文本)然后单击TextField时,它只是恢复为之前的数字。 This same thing happens when I put a non-numeric entry into the field, which I am okay with because it should only accept numbers, but I want to still allow the user to include a blank entry.当我在字段中输入一个非数字条目时也会发生同样的事情,我可以接受,因为它应该只接受数字,但我仍然希望允许用户包含一个空白条目。

I am using XCode and creating an iOS app.我正在使用 XCode 并创建一个 iOS 应用程序。 Thank you for any help.感谢您的任何帮助。

A possible solution is to intercept input/output via proxy binding and and perform needed additional validation/processing.一种可能的解决方案是通过代理绑定拦截输入/输出,并执行所需的额外验证/处理。

演示

Tested with Xcode 13.3 / iOS 15.4使用 Xcode 13.3 / iOS 15.4 测试

Here is main part:这是主要部分:

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

Complete test module in project 项目中完整的测试模块

Another solution that I found is just to make phoneNumber a string with default "" .我发现的另一个解决方案是将phoneNumber设为默认为""的字符串。 Then, validate it by trying to convert it to an Int via Int(phoneNumber) .然后,尝试通过Int(phoneNumber)将其转换为Int来验证它。 If Int(phoneNumber) == nil , then raise an error.如果Int(phoneNumber) == nil ,则引发错误。 Otherwise, you now have a new optional integer that can be nil or the integer provided:否则,您现在有一个新的可选整数,可以是 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