在SwiftUI中限制字符数或为TextField提供输入验证。

huangapple go评论108阅读模式
英文:

Limit characters or provide validation for input in TextField in SwiftUI

问题

目标: 我想通过将 SwiftUI TextField 输入限制为最多 3 个字符来实现。

结果: 由于某种原因,可以在 TextField 中输入超过 3 个字符。

步骤:

  1. 在文本字段中输入“123”。
  2. 多次开始输入“4”。
  3. 您会看到每第三次输入时,文本字段中会出现“1234”。

附加信息

  • gettersetter 打印的输出不会打印“1234”,这真的很奇怪。
  • 请查看下面的 GIF。

问题: 如何限制/验证 SwiftUI TextField 的输入,以符合给定示例?

在SwiftUI中限制字符数或为TextField提供输入验证。

Playground 代码:

import SwiftUI
import PlaygroundSupport
import Combine

struct ContentView: View {
    @State var inputValue: String = ""
    @State var previousValue: String = ""

    func getter() -> String {
        print("getter called with ", inputValue)
        return inputValue
    }

    func setter(_ newValue: String) {
        print("setter called with ", inputValue)
        if newValue.count > 3 {
            inputValue = previousValue
        } else {
            inputValue = newValue
            previousValue = inputValue
        }
    }

    var body: some View {
        TextField("", text: .init(get: getter, set: setter))
            .frame(minWidth: 100)
    }
}

PlaygroundPage.current.setLiveView(ContentView())

此外,即使您将 TextField 的定义更新为:

var body: some View {
    TextField("", text: .init(get: { "test "}, set: { _ in }))
        .frame(minWidth: 100)
}

强制始终使用“test”值,您仍然能够在每三次尝试中输入额外的字符。

英文:

Goal: I would like to limit SwiftUI TextField input by having 3 characters maximum.

Result: For some reason there is a way to input more than 3 characters into TextField

Steps:

  1. Enter "123" to text field
  2. Start typing multiple times "4"
  3. You'll see that for the each third input there will be "1234" inside the textfield

Additional info

  • print from getter and setter doesn't print "1234" output which is really weird
  • please check below gif

Question: How to limit/validate SwiftUI TextField input for given example?

在SwiftUI中限制字符数或为TextField提供输入验证。

Playground code:

import SwiftUI
import PlaygroundSupport
import Combine

struct ContentView: View {
    @State var inputValue: String = ""
    @State var previousValue: String = ""

    func getter() -> String {
        print("getter called with ", inputValue)
        return inputValue
    }

    func setter(_ newValue: String) {
        print("setter called with ", inputValue)
        if newValue.count > 3 {
            inputValue = previousValue
        } else {
            inputValue = newValue
            previousValue = inputValue
        }
    }

    var body: some View {
        TextField("", text: .init(get: getter, set: setter))
            .frame(minWidth: 100)
    }
}


PlaygroundPage.current.setLiveView(ContentView())

Also, even if you update the TextField definition like:

    var body: some View {
        TextField("", text: .init(get: { "test "}, set: { _ in }))
            .frame(minWidth: 100)
    }

to force "test" value always you still be able to input in every third attempt the additional character

答案1

得分: 2

这可以使用.onChange视图修饰符来处理。如果我的语法有点问题,很抱歉,我目前没有我的IDE可用。

在SwiftUI中,你真的不应该直接使用getter和setter。

@State var yourText = ""

var body: some View {
    VStack {
        // 使用@State绑定的文本
    }
    .onChange(of: yourText) { newValue in 
        // 在这里处理你的约束条件。
        // 检查你的值,如果超过了3个字符的限制
        // 将其重置回限制值。
    }
}
英文:

This can be handled with .onChange view modifier. Apologies if my syntax is a bit off, don't have my IDE immediately available.

In SwiftUI, you should never really use direct getters and setters.

  @State var yourText = ""

  var body: some View {
      VStack {
          // Your Text w/ @State Binding
      }
      .onChange(of: yourText) { newValue in 
          // Handle your constraints here. 
          // Check your value, if it exceeds your 3 char
          // reset it back to the limit. 
      }
  }

huangapple
  • 本文由 发表于 2023年7月31日 22:48:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/76804768.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定