格式化文本字段输入出现光标问题

问题描述 投票:0回答:1

嗨,我在下面得到了代码,并尝试动态格式化文本输入,但是当一切看起来都不错时,我会尝试编辑光标跳到看起来很奇怪的末尾,我的问题是我们可以防止这种行为。

下面的 gif 演示了该问题。

import SwiftUI

struct ContentView: View {
    @State private var text = ""
    @State private var error: String?
    
    var body: some View {
        VStack {
            let config = _TextFieldConfig(titleKey: "",
                                          promptText: "Enter text here",
                                          value: $text,
                                          error: $error,
                                          format: ._parseableFormatStyle)
            _TextField(config: config)
        }
        .padding()
    }
}

struct _TextFieldConfig<Format: ParseableFormatStyle> where Format.FormatOutput == String, Format.FormatInput == String, Format.Strategy == _ParseStrategy {
    var titleKey: String
    var promptText: String
    var format: Format
    @Binding var value: String
    @Binding var error: String?
    
    init(titleKey: String = "",
         promptText: String = "",
         value: Binding<String>,
         error: Binding<String?>,
         format: Format) {
        self.titleKey = titleKey
        self.promptText = promptText
        _error = error
        _value = value
        self.format = format
        
    }
}

struct _TextField: View  {
    var config: _TextFieldConfig<_ParseableFormatStyle>
    
    init(config: _TextFieldConfig<_ParseableFormatStyle>) {
        self.config = config
    }
    
    var body: some View {
        VStack {
            TextField(config.titleKey,
                      text: config.$value,
                      prompt: Text(config.promptText))
        }
        .onChange(of: config.value, initial: false) { oldValue, newValue in
            config.value = oldValue.formatted(config.format)
        }
    }
    
    
}

struct _ParseStrategy: ParseStrategy {
    func parse(_ value: String) throws -> String {
        value
    }
}

struct _ParseableFormatStyle: ParseableFormatStyle {
    var parseStrategy: _ParseStrategy { .init() }
    
    func format(_ value: String) -> String {
        value
            .lazy
            .filter { $0 != " " }
            .chunks(ofCount: 2)
            .map { String($0) }
            .joined(separator: " ")
    }
}

extension ParseableFormatStyle where Self == _ParseableFormatStyle {
    static var _parseableFormatStyle: _ParseableFormatStyle { .init() }
}

extension Array {
    func chunks(ofCount chunkCount: Int) -> [[Element]] {
        var result: [[Element]] = []
        for index in stride(from: 0, to: count, by: chunkCount) {
            let lastIdx = Swift.min(count, index + chunkCount)
            result.append(Array(self[index ..< lastIdx]))
        }
        return result
    }
}

不幸的是,我还没有找到任何可以在 SwiftUI 的 TextField 中操作光标的东西,但这也可能不是问题的根源。

swift swiftui cursor textfield
1个回答
0
投票

我写了类似的东西,但当我想一次删除 2 个字母时,它的行为是错误的。有人有想法吗?

func textField(_ textField: UITextField,
               shouldChangeCharactersIn range: NSRange,
               replacementString string: String) -> Bool {
    let currentText = textField.text ?? ""
    let text = (currentText as NSString).replacingCharacters(in: range, with: string)
    let count = text.count
    if !string.isEmpty {
        if count > 13 {
            return false
        }
        
        if string.range(of: " ") != nil {
            return false
        }
        
        if count % 3 == 0 {
            textField.text?.insert(" ", at: String.Index(utf16Offset: count - 1, in: currentText))
        }
        
        return true
    }
    return true
}
© www.soinside.com 2019 - 2024. All rights reserved.