Chapters

Hide chapters

SwiftUI Cookbook

Live Edition · iOS 16.4 · Swift 5.8.1 · Xcode 14.3.1

Dismiss Keyboard on Scroll in SwiftUI
Written by Team Kodeco

In an interactive application, especially a messaging app where a user scrolls through many messages, managing the software keyboard’s behavior can significantly enhance the user experience. One common pattern is to dismiss the keyboard when the user scrolls through the content.

In SwiftUI, you can accomplish this using the scrollDismissesKeyboard modifier, which lets you specify the keyboard dismissal mode when scrollable content is in use. For instance, you can choose to dismiss the keyboard immediately as soon as the user starts scrolling.

Consider the following example in a hypothetical messaging app:

struct ContentView: View {
  @State private var text = ""
  @State private var messages = (0 ..< 50).map { number in
    "Message \(number)"
  }

  var body: some View {
    NavigationStack {
      VStack {
        ScrollView {
          ForEach(messages.indices, id: \.self) { index in
            Text("\(messages[index])")
              .padding(10)
              .background(index % 2 == 0 ? .green : .blue)
              .foregroundColor(.white)
              .cornerRadius(10)
              .frame(maxWidth: .infinity, alignment: index % 2 == 0 ? .leading : .trailing)
              .padding([.horizontal, .top])
          }
        }
        .scrollDismissesKeyboard(.immediately)

        HStack {
          TextField("Type a message...", text: $text)
            .textFieldStyle(.roundedBorder)
            .padding()

          Button(action: {
            messages.append(text)
            text = ""
          }) {
            Image(systemName: "paperplane.fill")
              .padding()
          }
        }
      }
      .navigationTitle("Chat")
    }
  }
}

Here’s what your preview will look like. To see the keyboard behavior, run this example in the simulator and use Command-K to toggle the software keyboard.

A chat interface with a scrollable list of messages and a text field for entering new messages.
A chat interface with a scrollable list of messages and a text field for entering new messages.

In this example, you have a chat interface that consists of a ScrollView displaying messages and a TextField for writing new messages. The ScrollView is configured with the .scrollDismissesKeyboard(.immediately) modifier, meaning the keyboard will be dismissed as soon as the user starts a scroll drag gesture.

This way, you improve the user experience by ensuring that the keyboard does not obstruct the content when scrolling through the messages.

By default, a TextEditor in SwiftUI is interactive, while other kinds of scrollable content always dismiss the keyboard on a scroll. You can pass .never to the scrollDismissesKeyboard modifier to prevent scrollable content from automatically dismissing the keyboard.

Try scrollDismissesKeyboard and see how it improves the user experience in your app!

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2024 Kodeco Inc.