Managing the appearance and behavior of the keyboard is an essential aspect of creating a seamless user experience in iOS apps. In SwiftUI, while the system manages a lot of this automatically, there are times when you'll want more control.
We've been using all these tips and tricks for our iOS app templates. Let's delve into how you can handle the keyboard in SwiftUI.
1. Introduction to Keyboard Handling
When a user taps on a TextField
in SwiftUI, the system automatically displays the keyboard. However, problems can arise if the keyboard obscures the TextField
or other important elements of your UI.
2. Responding to Keyboard Appearance
To manage the keyboard's appearance and avoid UI obscurations, you can use the keyboardAdaptive()
modifier. But before that, you'll need to observe the keyboard's height.
final class KeyboardResponder: ObservableObject {
@Published var currentHeight: CGFloat = 0
var keyboardWillShowNotification = NotificationCenter.default.publisher(for: UIResponder.keyboardWillShowNotification)
var keyboardWillHideNotification = NotificationCenter.default.publisher(for: UIResponder.keyboardWillHideNotification)
init() {
keyboardWillShowNotification.map { notification in
CGFloat((notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect)?.height ?? 0)
}
.assign(to: \.currentHeight, on: self)
.store(in: &cancellableSet)
keyboardWillHideNotification.map { _ in
CGFloat(0)
}
.assign(to: \.currentHeight, on: self)
.store(in: &cancellableSet)
}
private var cancellableSet: Set<AnyCancellable> = []
}
Here, we use Combine's publisher(for:)
method to listen for keyboardWillShowNotification
and keyboardWillHideNotification
notifications.
Now, let's implement the keyboardAdaptive
modifier.
struct KeyboardAdaptive: ViewModifier {
@ObservedObject private var keyboard = KeyboardResponder()
func body(content: Content) -> some View {
content
.padding(.bottom, keyboard.currentHeight)
.animation(.easeOut(duration: 0.16))
}
}
Usage:
TextField("Enter text", text: $inputText)
.modifier(KeyboardAdaptive())
3. Animating with SwiftUI Keyboard
You noticed we added an animation in the keyboardAdaptive
modifier. This ensures that when the keyboard appears or disappears, the padding adjustment is animated, providing a smooth experience for the user.
4. Dismissing the Keyboard
In some situations, you might want the user to dismiss the keyboard by tapping outside the TextField
or on a "Done" button.
- Tapping Outside:
extension View {
func endEditing() {
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
}
// Usage:
var body: some View {
VStack {
TextField("Enter text", text: $inputText)
}
.onTapGesture {
self.endEditing()
}
}
- Using a Done Button:
var body: some View {
VStack {
TextField("Enter text", text: $inputText)
Button("Done") {
self.endEditing()
}
}
}
5. Keyboard Customization
SwiftUI allows you to customize the keyboard's appearance and behavior by adjusting the TextField
's modifiers.
TextField("Enter email", text: $email)
.keyboardType(.emailAddress) // Sets the keyboard type
.autocapitalization(.none) // Disables auto-capitalization
.disableAutocorrection(true) // Disables auto-correction
Conclusion: Managing the keyboard effectively in SwiftUI ensures your users enjoy a smooth and intuitive experience when interacting with your app. By observing keyboard notifications, animating view adjustments, and incorporating some handy extensions, you can create a polished UI that adapts seamlessly to keyboard events.
For more development articles, check out Dopebase programming tutorials.
I hope this tutorial provides you with a solid foundation for managing keyboards in SwiftUI. Happy coding!
Top comments (1)
Thanks for the content. Just one thing:
.assign(to: \.currentHeight, on: self)
inKeyboardResponder
is causing a retain cycle.Use
assign(to:)
instead ofassign(to: , on:)
to avoid a reference cycle, as mentioned in the docs: developer.apple.com/documentation/...