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

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

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

.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 } }

标签: ios swift swiftui textfield


【解决方案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)
                }
        }
    }
}

【讨论】:

  • 是的,这对我有用。有没有办法将此逻辑移至视图模型?
猜你喜欢
  • 1970-01-01
  • 2019-12-15
  • 2022-01-05
  • 2019-02-23
  • 1970-01-01
  • 1970-01-01
  • 2011-11-24
相关资源
最近更新 更多