Adjusting your layout with keyboard layout guide
Respond dynamically to keyboard movement by using the tracking features of the keyboard layout guide.
Overview
When your app presents a keyboard, you want it to integrate well into your layout. This sample code project demonstrates how to configure constraints when you set followsUndockedKeyboard to true on the keyboardLayoutGuide property in UIView to adapt your layout to the movement of the floating keyboard onscreen. The sample illustrates several concepts, such as handling when the keyboard is close to the top of the screen, and adapting the layout when the additional views don’t have constraints with a direct relationship to the keyboardLayoutGuide.
When you use keyboardLayoutGuide and leave followsUndockedKeyboard set to the default value of false, the guide matches the keyboard when it docks. When the keyboard isn’t onscreen, the guide is at the bottom of the window and has a height equal to the bottom of the current safeAreaInsets. By default, when the keyboard undocks, the guide behaves the same as when you dismiss the keyboard or the keyboard isn’t visible. You can use the guide like any other layout guide.
view.keyboardLayoutGuide.topAnchor.constraint(
equalToSystemSpacingBelow: textView.bottomAnchor, multiplier: 1.0).isActive = trueSee UILayoutGuide for more information about layout guides.
Follow the undocked keyboard
For more precise layout responses to the undocked keyboard, the sample sets followsUndockedKeyboard to true and then creates tracking constraints that activate and deactivate when the keyboard approaches or leaves an edge. Tracking constraints only apply when followsUndockedKeyboard is true.
// This is necessary to allow the various edge constraints to engage.
view.keyboardLayoutGuide.followsUndockedKeyboard = trueEnable tracking constraints
The sample shows how the UITrackingLayoutGuide activates or deactivates constraints when the keyboardLayoutGuide approaches or leaves an edge. The sample code passes an array of constraints to the keyboardLayoutGuide, and indicates which edges trigger the change. The sample configures an array of constraints to activate when awayFrom the leading and trailing edges, so the constraints activate when the keyboard docks or when the floating keyboard is in the middle area of the screen. Conversely, the constraints deactivate when the floating keyboard approaches either the leading or trailing edge.
The following example shows how to pin a view to the top of the keyboardLayoutGuide when the guide is awayFrom the top edge, and to the bottom of the view’s safeAreaLayoutGuide when it’s near the top edge:
// When the keyboard isn't near the top, tie the edit view to the keyboard layout guide (it
// deactivates when near the top).
let editViewOnKeyboard = view.keyboardLayoutGuide.topAnchor.constraint(equalTo: editView.bottomAnchor)
editViewOnKeyboard.identifier = "editViewOnKeyboard"
view.keyboardLayoutGuide.setConstraints([editViewOnKeyboard], activeWhenAwayFrom: .top)
// When the keyboard is near the top, tie the edit view to the bottom anchor of the safeAreaLayoutGuide, so that it doesn't go offscreen.
let editViewOnBottom = view.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: editView.bottomAnchor)
editViewOnBottom.identifier = "editViewOnBottom"
view.keyboardLayoutGuide.setConstraints([editViewOnBottom], activeWhenNearEdge: .top)The sample demonstrates that it isn’t necessary to pin views to the keyboardLayoutGuide to affect their constraints when the keyboard approaches an edge. The guide can take any array of constraints in the layout and activate and deactivate them when necessary. For example, the following code shows an imageView with no constraint relationships to the keyboardLayoutGuide itself, but the image moves to the opposite side of the screen from the keyboard to stay visible as the keyboard moves around:
let centeredImage = imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor)
centeredImage.identifier = "centeredImage"
view.keyboardLayoutGuide.setConstraints([centeredImage], activeWhenAwayFrom: [.leading, .trailing])
let imageViewToLeading = imageView.leadingAnchor.constraint(
equalToSystemSpacingAfter: view.safeAreaLayoutGuide.leadingAnchor, multiplier: 1.0)
imageViewToLeading.identifier = "imageViewToLeading"
let nearTrailingConstraints = [ editViewToUndockedKeyboardTrailing, imageViewToLeading ]
view.keyboardLayoutGuide.setConstraints(nearTrailingConstraints, activeWhenNearEdge: .trailing)
let imageViewToTrailing = view.safeAreaLayoutGuide.trailingAnchor.constraint(
equalToSystemSpacingAfter: imageView.trailingAnchor, multiplier: 1.0)
imageViewToTrailing.identifier = "imageViewToTrailing"
let nearLeadingConstraints = [ editViewToKeyboardLeading, imageViewToTrailing ]
view.keyboardLayoutGuide.setConstraints(nearLeadingConstraints, activeWhenNearEdge: .leading)Account for keyboard types
The following list describes which edges the system reports the keyboardLayoutGuide is near and awayFrom when different types of keyboards are active:
Docked keyboards:
Are always
awayFromleading, trailing, and top edgesAre always
nearthe bottom edge
Split and undocked keyboards:
Are always
awayFromleading, trailing, and bottom edgesCan be
nearthe top edge
Floating keyboards:
Can be
awayFromall edgesCan be
nearany edge or any two adjacent edges
The shortcuts bar (available with an external attached keyboard):
Is always
awayFromthe top edge andnearthe bottom edgeCan be
nearthe leading or trailing edge when in a collapsed state
When the app is in 1/3 split view mode, the keyboardLayoutGuide is awayFrom leading and trailing edges, near the bottom edge if docked, and can be near the top edge if floating or undocked.
Handle edge combinations
The sample shows constraints that are active when near or awayFrom multiple edges. The system activates or deactivates the constraints only when the position of the keyboard meets all edge requirements. Because a docked keyboard is awayFrom leading and trailing edges, but near the bottom edge, the constraint in the example below only activates when the keyboard undocks and is awayFrom the leading and trailing edges. This situation happens with undocked full or split keyboards, and with a floating keyboard in the horizontal middle of the screen.
let editCenterXToKeyboard = view.keyboardLayoutGuide.centerXAnchor.constraint(equalTo: editView.centerXAnchor)
editCenterXToKeyboard.identifier = "editCenterXToKeyboard"
view.keyboardLayoutGuide.setConstraints([editCenterXToKeyboard], activeWhenAwayFrom: [.leading, .trailing, .bottom])