SwiftUI - 防止用户在 TextEditor 中添加换行符 (\n)

SwiftUI - Prevent users from adding New Line (\n) in TextEditor

我有一个 TextEditor,我不允许用户在其中添加 New Line (\n)。也就是说,当用户 Enter 时,我关闭键盘。我使用以下代码关闭键盘并阻止用户添加新行。

Enter 时关闭键盘,但不会阻止用户添加新行。当您输入.

extension View {
  func  dismissKeyboard(){
        let keyWindow = UIApplication.shared.connectedScenes
                .filter({[=10=].activationState == .foregroundActive})
                .map({[=10=] as? UIWindowScene})
                .compactMap({[=10=]})
                .first?.windows
                .filter({[=10=].isKeyWindow}).first
        keyWindow?.endEditing(true)
    }
}


struct Editor: View {
    
    @Binding var text: String
        
    var onEditingEnded: () -> ()
    
    var body: some View {
        ZStack(alignment: .leading) {         
            TextEditor(text: $text)
                .onChange(of: text) { value in
                    if value.last == "\n" {
                        self.dismissKeyboard()
                        self.onEditingEnded()
                    }
                }
        }
        .padding(8)
        .font(.body)
    }
}

如何防止用户添加新行?

您可以使用具有 shouldChangeTextIn range 委托函数的 UITextView...

或者,虽然不是我所说的理想,但这可能适合你:

TextEditor(text: $text)
            
    .onChange(of: text) { value in
        if value.last == "\n" {
            text = String(value.dropLast())
            self.dismissKeyboard()
            self.onEditingEnded()
        }
    }

请注意,您只检查字符串中的最后一个字符,因此这不会处理用户在现有文本中间添加换行符的问题。

所以,您可以试试:

TextEditor(text: $text)

    .onChange(of: text) { value in
        if value.contains("\n") {
            text = value.replacingOccurrences(of: "\n", with: "")
            self.dismissKeyboard()
            self.onEditingEnded()
        }
    }

类似于 DonMag 的回答,您也可以使用 Binding() 而不是 .onChange() 来避免事后更改值并在设置之前采取行动:

TextEditor(text: Binding(
    get: {
        return text
    },
    set: { value in
        var newValue = value
        if value.contains("\n") {
            newValue = value.replacingOccurrences(of: "\n", with: "")
            self.dismissKeyboard()
            self.onEditingEnded()
        }
        text = newValue
    }
))