Alex92
Alex92

Reputation: 49

SwiftUI TextEditor how Hide Keyboard

I have à problem with TextEditor, I cannot hide the Keyboard after editing my text on the Texteditor.

    @State var monTexte: String = "
var body: some View {
        VStack {
            Spacer()
                .frame(height :15)
                .clipped()
            Text("Project ")
                .font(Font.system(size: 39.00))              
               .fontWeight(.black)
                .foregroundColor(Color.white)
                .multilineTextAlignment(.center)
                .padding(.all, 16.0)
                .clipped()
            
            TextEditor(text: $monTexte)
                .keyboardType(.alphabet)
                .font(.subheadline)
                .padding(.horizontal)
                .font(Font.system(size: 38.00))
                .frame(minWidth: 10, maxWidth: .infinity, minHeight: 10, maxHeight: 200, alignment: .topLeading)
                .border(Color.black)
                .clipped()
}
}
} 

I’ve found a method to hide the keyboard using a textfield but not using a TextEditor Coule you help me please

Upvotes: 1

Views: 6084

Answers (4)

ej5607
ej5607

Reputation: 397

Like protspace, I prefer to allow the user to create new lines in the text editor. Here's a solution to this problem:

extension View {
    func hideKeyboard() {
        let resign = #selector(UIResponder.resignFirstResponder)
        UIApplication.shared.sendAction(resign, to: nil, from: nil, for: nil)
    }
}

And then attach this to the relevant part of your view (after the end of a Form {}, for example):

.toolbar {
     ToolbarItemGroup(placement: .keyboard) {
         Button("Dismiss keyboard") {
             hideKeyboard()
         }
         .buttonStyle(.borderedProminent)
      } // keyboard "Dismiss keyboard" button
} // End of toolbar

Upvotes: -1

protspace
protspace

Reputation: 2147

I prefer to use toolbar. This way you won't break new line logic. Suppose you have 2 TextEditors:

VStack {
    TextEditor(text: $subjectText)
       .focused($focusField, equals: .subject)
     TextEditor(text: $messageText)
       .focused($focusField, equals: .message)
}
  .toolbar {
      ToolbarItemGroup(placement: .keyboard) {
         Spacer()
         Button(focusField == .subject ? "Next" : "Done") {
            if focusField == .subject {
               focusField = .message
            } else {
               UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
               focusField = nil
            }
         }
      }
   }

Where

@FocusState private var focusField: Field?
enum Field: Hashable {
    case subject
    case message
}

Upvotes: 2

tiritea
tiritea

Reputation: 1279

I found this worked adequately for me. It's pure SwiftUI, without having to resort to UIKit.

struct TestView: View {
    @State private var response = ""
    @FocusState private var responseIsFocussed: Bool // dismiss response editor keyboard when hit Return

    var body: some View {
        TextEditor(text: $response)
            .focused($responseIsFocussed)
            .onReceive(response.publisher.last()) {
                if ($0 as Character).asciiValue == 10 { // ASCII 10 = newline
                    responseIsFocussed = false // unfocus TextEditor to dismiss keyboard
                    response.removeLast() // remove newline at end to prevent retriggering...
                }
            }
    }
}

The .focused() modifier on the view triggers attaches a trigger to the TextEditor to enable you to programmatically focus (show) or unfocus (dismiss) the keyboard. And the .onReceive() captures key entry; it checks whether the last char entered in the string is a newline (ASCII 10), and if so triggers the unfocus. Its important to immediately remove this Return/newline from the end of the string, otherwise it can keep triggering...

Caveat: this only triggers off the last char; if you edit the string and move the cursor midway and hit Return, nothing will happen (which actually behaves somewhat intuitively, IMO...)

Upvotes: 3

Alex92
Alex92

Reputation: 49

Thank you "Asperi" it's works using the code below :

var body: some View {
        VStack {
            Spacer()
                .frame(height :15)
                .clipped()
            Text("Project ")
                .font(Font.system(size: 39.00))              
               .fontWeight(.black)
                .foregroundColor(Color.white)
                .multilineTextAlignment(.center)
                .padding(.all, 16.0)
                .clipped()
                        HStack {
                Spacer()
                Button("Close Keyboard") {
                    UIApplication.shared.endEditing()

                }.font(Font.system(size: 20))
                .foregroundColor(Color.blue)
                
            }.clipped()
            TextEditor(text: $monTexte)
                .keyboardType(.alphabet)
                .font(.subheadline)
                .padding(.horizontal)
                .font(Font.system(size: 38.00))
                .frame(minWidth: 10, maxWidth: .infinity, minHeight: 10, maxHeight: 200, alignment: .topLeading)
                .border(Color.black)
                .clipped()
}
}
} 

//----------------------------------------------------//
// Masquer le clavier
//----------------------------------------------------//
extension UIApplication {
    func endEditing() {
        sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
    }
}```

Upvotes: 2

Related Questions