如何在swiftui中将textField中输入的字符限制为0到9或点(.)?

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

当我输入它收到的字符时,我想从键盘输入字符,但是当我按任意键时,它收到的最后一个字符没有避免特殊字符怎么办

    func digitswithPointOnly(text: Binding<String>) -> some View {
        self.keyboardType(.decimalPad)
            .onChange(of: text.wrappedValue) { newValue in
                var filtered = newValue.filter { "0123456789.".contains($0) } // Allow digits
                
                // Check if the string contains more than one decimal point
                let decimalCount = filtered.reduce(0) { $0 + ($1 == "." ? 1 : 0) }
                
                if decimalCount > 1 {
                    // Remove the last entered decimal point if more than one exists
                    filtered.removeLast()
                } else if let index = filtered.firstIndex(of: ".") {
                    // Allow only two digits after the decimal point
                    let fractionalPart = filtered[filtered.index(after: index)...]
                    if fractionalPart.count > 2 {
                        // Remove digits after the second decimal place
                        let endIndex = filtered.index(index, offsetBy: 2)
                        filtered = String(filtered.prefix(upTo: endIndex))
                    }
                }
                
                text.wrappedValue = filtered
            }
    }
}

我在我的文本字段中使用此扩展

这是我的代码

let measurement = Measurement(measurement: index.id, value: newValue)
if !modifiedMeasurements.contains(measurement) {
 modifiedMeasurements.append(measurement)
}}),prompt: Text(index.desc)) 
.digitswithPointOnly(text: Binding<String>(
get: { userMeasurements[index.id].stringValue },
set: { newValue in

userMeasurements[index.id] = JSON(newValue)
let measurement = Measurement(measurement: index.id, value: newValue)}))```
ios swift xcode swiftui textfield
1个回答
0
投票

你可以这样做:

struct ContentView: View {
    @State private var text: String = ""
    
    var body: some View {
        VStack {
            TextField("placeholder", text: $text)
                .keyboardType(.numbersAndPunctuation)
                .padding(60)
        }
        .padding()
        .onChange(of: text, initial: false) { oldValue, newValue in
            let filtered = filter(text)
            if newValue != filtered {
                self.text = filtered
            }
        }
    }
    
    private func filter(_ text: String) -> String {
        let allowedCharacters = "0123456789" + (Locale().decimalSeparator ?? ",")
        return text.filter { allowedCharacters.contains($0) }
    }
}

但是,仍有一些注意事项:

  • 使用
    onChange
    作为 @State 变量的技术解决方案,其中闭包更改原始值可能会导致无限循环 - 所以,我不推荐它。
  • 用户仍然可以输入无效字符串。
  • 您仍然需要在其他地方执行额外的逻辑才能获得有效的输入。
  • 将逻辑放入视图中很难测试。
  • “TextField”的详细行为在 iOS 17.x 中有点古怪 - 因此您可能会遇到奇怪的行为,但这在 iOS 16.x 上运行良好。
© www.soinside.com 2019 - 2024. All rights reserved.