DEV Community

Thomas Step
Thomas Step

Posted on • Edited on • Originally published at thomasstep.com

1 1

Hiding a Keyboard in Swift

I've been working on developing an iOS 14 app in my free time lately, and the other day I wanted to create a TextField to receive input from the user. I needed a number, so I changed the keyboardType to numberPad and added some validation logic. Everything was fairly easy to set up especially considering I have never developed on iOS before or written code in objective C. Then came the doozy. Whenever I tapped on something other than the TextField, nothing happened. I expected the keyboard to go away but it didn't want to budge. Every app I have ever used had this behavior, so I assumed that it was the built-in default behavior. I was wrong. I went down rabbit hole after rabbit hole trying to figure out how to hide the keyboard. Most of the problems I encountered were due to blog posts and StackOverflow answers referring to earlier versions of iOS, and since I was developing for iOS 14, all of my code and views were written differently. (Again, I have never developed for iOS before. It is very well possible that I am completely wrong and I could have solved this much quicker with any of the other snippets out on the internet.) It turns out that the behavior of hiding a keyboard when a TextField becomes unfocused is not natively built into Swift. The alternative that I ended up going with was extending View with a function that sends an action to resignFirstResponder. Then I added onTapGesture to a view that encompassed the screen where the keyboard showed up and called the function as a result. The whole process is still a little weird to me, but it has started to make more sense the more I look at it. Here's an example of the code.

#if canImport(UIKit)
extension View {
    func hideKeyboard() -> Void {
        UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
    }
}
#endif

struct ContentView: View {
  @State private var myInput : String = ""

  var body: some View {
    ScrollView {
      TextField("Demo text field", text: $myInput)
          .multilineTextAlignment(.center)
          .textFieldStyle(RoundedBorderTextFieldStyle())
          .keyboardType(.numberPad)
    }
    .onTapGesture(count: 1, perform: self.hideKeyboard)
  }
}
Enter fullscreen mode Exit fullscreen mode

I think the key here for me is that ScrollView takes up the entire screen of my app, so when I added the listener, if the user tapped anywhere else on the screen, they would experience the desired behavior. Since this is not natively built into Swift, I have to assume that there is no standard way of doing this. Not using this behavior as a default seems like a huge oversight to me, and I wish there was an Apple-approved way of writing in this behavior.

AWS GenAI LIVE image

Real challenges. Real solutions. Real talk.

From technical discussions to philosophical debates, AWS and AWS Partners examine the impact and evolution of gen AI.

Learn more

Top comments (0)

Billboard image

📊 A side-by-side product comparison between Sentry and Crashlytics

A free guide pointing out the differences between Sentry and Crashlytics, that’s it. See which is best for your mobile crash reporting needs.

See Comparison

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay