【问题标题】:Limit TextField to x amount of characters using SwiftUI使用 SwiftUI 将 TextField 限制为 x 个字符
【发布时间】:2019-11-02 16:00:03
【问题描述】:

使用 iOS13.2、Swift-5.1.2、Xcode-11.2,我尝试以下方法:

我想使用 TextField。用户只能在 TextField 中输入 x 个字符。

我的代码如下:

import Combine
import SwiftUI

class Entry: ObservableObject {

  @Published var entry = "" {
    didSet {
        entry = String(entry.prefix(6)) // trying to limit to 6 characters
    }
  }
}

并且在上面的代码中,已经有异常行了。

我可以看到didSet{...} 是错误的(因为我们最终陷入了无限循环设置/didSetting 一次又一次)...

将 TextField 限制为 x 个字符的更好方法是什么?

下面是剩下的代码:

struct NumberView: View {
    var body: some View {

        Group {
            HStack {
                Spacer()
                NumberIcon(number: 1)
                NumberIcon(number: 2)
                NumberIcon(number: 3)
                NumberIcon(number: 4)
                NumberIcon(number: 5)
                NumberIcon(number: 6)
                Spacer()
            }
         }
    }
}
struct NumberIcon: View {
    @ObservedObject private var entry = Entry()
    var number: Int = 0
    var body: some View {
        TextField(" ", text: $entry.entry, onEditingChanged: { editing in
            print(editing)
            print(self.$entry)
        })
            .padding()
            .foregroundColor(Color.black)
            .background(Color.green)
            .font(.largeTitle)
            .lineLimit(1)
            .cornerRadius(16.0)
            .clipped()
            .keyboardType(.numberPad)
    }
}

struct NumberView_Previews: PreviewProvider {
    static var previews: some View {
        NumberView()
    }
}

我知道 UIKit 包装器可以使用 UITextFieldDelegate 中的老式 shouldChangeCharactersIn 委托方法 - 但我想纯粹使用 SwiftUI 来实现字符限制(没有 UIKit 代码)。我该怎么做?

【问题讨论】:

    标签: swift textfield swiftui combine


    【解决方案1】:

    感谢this answer here,我找到了解决办法:

    Entry 类可以重写:

    class Entry: ObservableObject {
    
        let characterLimit = 6   // limiting to 6 characters
        @Published var entry = "" {
            didSet {
                if entry.count > characterLimit && oldValue.count <= characterLimit {
                    entry = oldValue
                }
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      你可以用这个:

      .onReceive(variable.publisher.collect()) {
              variable = String($0.prefix(4))
      }
      

      【讨论】:

        【解决方案3】:

        我为这些用例写了一个library

        import DataField
        
        struct ContentView: View {
        
            @State private var text = ""
            private let characterLimit = 6
        
            var body: some View {
                DataField("My Field", data: $text) { text in text.count < 6 } 
            }
        }
        

        【讨论】:

          【解决方案4】:

          在 SwiftUI 中实现这一目标的最简单方法是在达到最大字符数时禁用 TextField:

          struct LimittedTextField: View {
          
              @State private var entry = ""
          
              let characterLimit = 6
          
              var body: some View {
                  TextField("", text: $entry)
                      .disabled(entry.count > (characterLimit - 1))
              }
          }
          

          【讨论】:

          • 谢谢 LuLuGaGa,我喜欢这个解决方案。但是,它会使键盘消失。当用户在第一个 TextField 中键入 x 个字符时,我的最终解决方案会寻找一种跳转到第二个 TextField 的方法。我在这里有一个关于这方面的 stackoverflow 问题:LINK。也许你也有这个问题的解决方案 - 我很感激!
          猜你喜欢
          • 2020-05-06
          • 1970-01-01
          • 1970-01-01
          • 2017-12-17
          • 2015-12-10
          • 2020-07-21
          • 1970-01-01
          • 2016-09-18
          • 2020-06-02
          相关资源
          最近更新 更多