SWIFTUI:防止在文本字段中按返回键时键盘消失

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

我在 SwiftUI 中使用 TextField。并按回车键键盘自行消失。

有什么方法可以让键盘保持抬起状态,同时仍然保持 TextField 可编辑位置。

谢谢

ios swiftui textfield
2个回答
1
投票

有一种解决方法适用于 iOS 15+,但它仍然会创建键盘的弹跳动画。

如果您有多个文本字段,则可以使用 enum@FocusState 代替 Bool

struct ContentView: View {
    @FocusState var focused: Bool
    @State var text: String = ""

    var body: some View {
        TextField("Text", text: $text)
            .focused($focused)
            .onSubmit {
                focused = true
            }
    }
}

为了在不弹跳键盘的情况下获得更好的解决方案,我建议使用很棒的第三方库Introspect

import Introspect

class TextFieldKeyboardBehavior: UIView, UITextFieldDelegate {
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        return false
    }
}

struct ContentView: View {
    @State var text: String = ""
    var textFieldKeyboardBehavior = TextFieldKeyboardBehavior()
    
    var body: some View {
        TextField("Text", text: $text)
            .introspectTextField { textField in
                textField.delegate = textFieldKeyboardBehavior
            }
    }
}

0
投票

只是想扩展@Ivo 的答案以回应@Barrrdi 的评论。

我的 UITextFieldDelegate 看起来像这样:

class TextFieldDelegate: NSObject, UITextFieldDelegate {
    
    var shouldReturn: (() -> Bool)?
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        
        if let shouldReturn = shouldReturn {
            return shouldReturn()
        }
        else {
            return true
        }
    }
}

那么我的 SwiftUI 视图可能如下所示:

struct TestView: View {
    
    enum FocusedField {
        case username, password
    }
    
    @State private var username: String = ""
    @State private var password: String = ""
    
    var usernameFieldDelegate = TextFieldDelegate()
    var passwordFieldDelegate = TextFieldDelegate()
    
    @FocusState private var focusedField: FocusedField?
    
    var body: some View {
        
        VStack {
            
            TextField(text: $username)
                .focused($focusedField, equals: .username)
                .introspectTextField(customize: { textField in
                    
                    usernameFieldDelegate.shouldReturn = {
                        
                        if usernameIsValid() {
                            focusedField = .password
                        }
                        
                        return false
                    }
                    
                    textField.delegate = usernameFieldDelegate
                })
            
            SecureField(text: $password)
                .focused($focusedField, equals: .password)
                .introspectTextField(customize: { textField in
                    
                    passwordFieldDelegate.shouldReturn = {
                        return false
                    }
                    
                    textField.delegate = passwordFieldDelegate
                })
        }
    }
    
    func usernameIsValid() -> Bool {
        return true
    }
}

避免弹跳的重要一点是 textFieldShouldReturn() 需要返回 false(但是你想实现这一点)。

© www.soinside.com 2019 - 2024. All rights reserved.