如何限制字符数,同时只允许 TextField 中的字符子集?

Posted

技术标签:

【中文标题】如何限制字符数,同时只允许 TextField 中的字符子集?【英文标题】:How to limit the number of characters while also allowing only a subset of characters in a TextField? 【发布时间】:2020-08-10 03:48:33 【问题描述】:

我一直在尝试限制我可以在 SwiftUI 中的 TextField 上输入的字符数,同时只允许数字。

我尝试了基于this和this的混合解决方案

.onReceive(Just(viewModel.myString))  newValue in
    let filtered = newValue.filter  "0123456789".contains($0) 
    if filtered != newValue 
        self.viewModel.myString = filtered
    

过滤字符以及

@Published var myString: String = "" 
    willSet 
        if newValue.count > Constants.maxLimit 
            myString = String(newValue.prefix(Constants.maxLimit))
        
    

限制字符数。

但是通过这种方法,我仍然可以添加多个Constants.maxLimit 并添加数字以外的字符。

如果我尝试将这两个逻辑与视图模型中的 willSet/didSet 或文本字段中的 onReceive 结合起来,则会因堆栈溢出而导致崩溃。

我还是 SwiftUI 的新手,所以我不确定自定义 Publisher 是否有助于解决我的问题。

【问题讨论】:

你不能这样做吗? :.onReceive(Just(viewModel.myString)) newValue in let filtered = newValue.filter "0123456789".contains($0) if filtered != newValue, filtered.count <= Constants.maxLimit self.viewModel.myString = filtered 【参考方案1】:

您可以简单地过滤所有整数字符并获取结果字符串的前 10 个字符。您还需要检查字符串是否为空并将值设置回零:


import SwiftUI
import Combine

struct ContentView: View 
    @State private var text = "0"
    let maxLength = 10
    var body: some View 
        TextField("", text: $text)
            .keyboardType(.numberPad)
            .onReceive(Just(text)) 
                guard !$0.isEmpty else 
                    self.text = "0"
                    return
                
                if let value = Int($0.filter(\.isWholeNumber).prefix(maxLength)) 
                    self.text = String(value)
                
        
    

【讨论】:

是的,这对我有用。有没有办法将此逻辑移至视图模型?

以上是关于如何限制字符数,同时只允许 TextField 中的字符子集?的主要内容,如果未能解决你的问题,请参考以下文章

flutter TextField 限制只允许输入数字 小数点

flutter TextField 限制只允许输入数字 小数点

如何使用maskRe限制ExtJs Textfield仅接受数字。 (应接受正数,负数,整数和十进制数。)

如何限制 UIAlertView UITextField 中的字符输入

[Flutter] TextField 中只允许输入合法的小数

限制两个特定文本字段中的字符数