首页 > 解决方案 > 如何限制字符数,同时只允许 TextField 中的字符子集?

问题描述

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

我已经尝试了基于这个这个的混合解决方案

.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 是否有助于解决我的问题。

标签: iosswiftswiftuitextfield

解决方案


您可以简单地过滤所有整数字符并获取结果字符串的前 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)
                }
        }
    }
}

推荐阅读