Bartek
Bartek

Reputation: 93

Keyboard always on top in SwiftUI View

I try to develop a Quiz App in SwiftUI. For that I would like the keyboard to be always activated.

The problem now is, that when I hit return on the keyboard, it disappears and I have to click on the Textfield again.

How can I modify the textfield that after clicking it, it won't disappear or that the keyboard is always activated in this view.

I use the following versions:

Xcode: Version 12.4 (12D4e) / iOS-Version: 14.4

Some example code from the needed view:

struct Practice: View {

    @Binding var Alpha: Array<String>
    @State private var inputdesc: String = "Answer"
    @State private var placeholder: String = ""
    @State var new = 0
    
var body: some View {


        
            ZStack {
                Color("Background").ignoresSafeArea()

VStack {
            Text(Alpha[new])
                .font(.system(size: 160))

            TextField(inputdesc, text: $placeholder, onCommit: {
    
                               new = Int.random(in: 0..<Alpha.count)
                               placeholder = ""

                            })
                    }
                .font(.system(size: 50))
                .autocapitalization(.none)
                .disableAutocorrection(true)
                .multilineTextAlignment(.center)
                .foregroundColor(Color("BackgroundInverse"))
                }
}
}

Upvotes: 0

Views: 454

Answers (1)

Raja Kishan
Raja Kishan

Reputation: 19014

You need to use UIKit delegate.

Here is the demo version code.

struct NoneDismissTextField: ViewModifier {

    @ObservedObject var coordinator: Coordinator
    private var onCommit: ()->Void
    
    init(onCommit: @escaping ()->Void) {
        self.onCommit = onCommit
        coordinator = Coordinator(onCommit: onCommit)
    }
    
    public struct TextFieldView: UIViewRepresentable {
        
        var configure: (UITextField) -> Void
        
        public func makeUIView(context: UIViewRepresentableContext<TextFieldView>) -> UIView {
            let view = UIView(frame: .zero)
            DispatchQueue.main.async {
                if let textField = view.superview?.superview?.subviews[1].subviews[0] as? UITextField {
                    configure(textField)
                }
            }
            return view
        }
        
        public func updateUIView(_ uiView: UIView,
                                 context: UIViewRepresentableContext<TextFieldView>) {
            
        }
    }
    
    func body(content: Content) -> some View {

        return content
            .background(TextFieldView(configure: { (textField) in
                textField.delegate = self.coordinator
            }))
    }

    class Coordinator: NSObject, ObservableObject, UITextFieldDelegate {
        
        private var onCommit: () -> Void
         
        init(onCommit: @escaping ()->Void) {
            self.onCommit = onCommit
        }
        
        func textFieldShouldReturn(_ textField: UITextField) -> Bool {
            onCommit()
            return false
        }
    }
}

Usage

TextField(inputdesc, text: $placeholder)
    .modifier(NoneDismissTextField(onCommit: {
        new = Int.random(in: 0..<Alpha.count)
        placeholder = ""
    }))

Tested: XCode 12.3, iOS 14.3

enter image description here

Upvotes: 1

Related Questions