在 SwiftUI 中将选取器更改为文本字段

Posted

技术标签:

【中文标题】在 SwiftUI 中将选取器更改为文本字段【英文标题】:Changing A Picker to a TextField in SwiftUI 【发布时间】:2021-05-06 14:56:55 【问题描述】:

我是一个自学 ios 开发的新手(Paul Hudson 的 100DaysOfSwiftUI,项目 1),目前我遇到了一个我还没有解决的问题。最初,numberOfPeople 部分有一个带有以下代码的选择器,我试图将其更改为文本字段。首先将其 @State 属性 (@State private var numberOfPeople = 2) 从 2 更改为空字符串,并尝试为人数创建另一个计算属性。当人数文本字段留空时,当我运行项目时,模拟器上每人数量部分的默认值不会显示为 0,而是显示为 NaN,如下面的屏幕截图所示。 (这让我想知道 numberOfPeople 是否通过 nil 合并成功转换为 Integer,如下所示)。只有当我在人数文本字段中输入值时,项目才能正常运行。我不能 100% 确定我哪里出了问题,但我们将不胜感激!

struct ContentView: View 
    @State private var checkAmount = ""
    @State private var numberOfPeople = ""
    @State private var tipPercentage = 2
    
    let tipPercentages = [10,15,20,25,0]
    let allPeople = 2...100

    var totalPerPerson: Double 
        let peopleCount = Double(numberOfPeople) ?? 0
        let tipSelection = Double(tipPercentages[tipPercentage])
        let orderAmount = Double(checkAmount) ?? 0
        
        let tipValue = orderAmount / 100 * tipSelection
        let grandTotal = orderAmount + tipValue
        let amountPerPerson = grandTotal / peopleCount

        return amountPerPerson
    
    
    var grandTotal: Double 
        let tipSelection = Double(tipPercentages[tipPercentage])
        let orderAmount = Double(checkAmount) ?? 0
        
        let tipValue = orderAmount / 100 * tipSelection
        let totalAmount = orderAmount + tipValue
        
        return totalAmount
    
    
    var body: some View 
        NavigationView 
            Form 
                Section 
                    TextField("Amount", text: $checkAmount)
                        .keyboardType(.decimalPad)
                    
                    TextField("Number of people", text: $numberOfPeople)
                        .keyboardType(.numberPad)
                
                
                Section(header: Text("How much tip do you want to leave?")) 
                    Picker("Tip percentage", selection: $tipPercentage) 
                        ForEach(0 ..< tipPercentages.count) 
                            Text("\(self.tipPercentages[$0])%")
                        
                    
                    .pickerStyle(SegmentedPickerStyle())
                
                
                Section (header: Text("Total Amount"))
                    Text("$\(grandTotal, specifier: "%.2f")")
                
                
                Section (header: Text("Amount Per Person"))
                    Text("$\(totalPerPerson, specifier: "%.2f")")
                
            
            .navigationBarTitle("WeSplit")
        
    


struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ContentView()
    


(Original code for picker)
Picker("Number of people", selection: $numberOfPeople) 
        ForEach(2 ..< 100) 
            Text("\($0) people")

(Original code for people count)
let peopleCount = Double(numberOfPeople + 2)

project simulator

【问题讨论】:

问题是你不能除以 0。人数为 0 但你需要检查人数是否为 0 并返回 0 可能使用保护语句 【参考方案1】:

您看到的是尝试除以零的结果。如果peopleCount0,您可以通过从您的totalPerPerson 函数返回0 来避免该计算,然后再使用以下方法进行除法:

var totalPerPerson: Double 
    let peopleCount = Double(numberOfPeople) ?? 0
    let tipSelection = Double(tipPercentages[tipPercentage])
    let orderAmount = Double(checkAmount) ?? 0
    
    guard peopleCount > 0 else 
        return 0
    
    
    let tipValue = orderAmount / 100 * tipSelection
    let grandTotal = orderAmount + tipValue
    let amountPerPerson = grandTotal / peopleCount

    return amountPerPerson

请记住,对于您的新 TextField,与选择器相反,即使您指定了 .decimalPad.numberPad,用户也有仍然方式输入非这些字段中的数值,因此如果发生这种情况,您可能希望提出错误(或者,在 SO 上搜索有关仅接受数字的字段的解决方案)。 在 solution

中指定了此类 TextField 的示例

【讨论】:

非常感谢您的帮助,我按照您所说的插入了保护声明,并且效果很好。如此快速的解决方案让我永远无法弄清楚。非常感谢!

以上是关于在 SwiftUI 中将选取器更改为文本字段的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SQL Select 语句中将文本字段更改为日期字段

textFieldShouldReturn 无法在 swift 3 中将焦点从一个文本字段更改为另一个文本字段

在 SwiftUI 中向 TextField/SecureField 添加图像,向占位符文本添加填充

如何在 SwiftUI 中将 LocalizedStringKey 更改为 String

选择器中的 SwiftUI 和枚举

无法将包管理器更改为纱线