Enable Keyboard in Xcode Preview

Viewed 5286

how can I enable keyboard when tapping a Textfield in Xcode preview. I somehow activated it and clicked some keys and then I accidentally typed a shortcut on my Mac and it disappeared.

How can I enable it again?

3 Answers

This might be a bug, I tried running preview in debug mode in several cases and noticed that when a text field is tapped, console throws errors about some constraints that are not satisfied and there's no access to them.

I also enabled "Show View Frames" from Xcode's "Debug" menu, the keyboard frame actually appears on the screen but is not shown for some reason. In rare cases, the constraints error was gone for no reason and the keyboard was successfully displayed but simply restarting the preview caused it to disappear again. So this might be a bug and if so, hope this gets fixed in next releases.

It turns out this setting is (very subtly) tied to the "Connect Hardware Keyboard" preference in the iOS Simulator app (found in the menu bar as I/O → Keyboard → Connect Hardware Keyboard). The keyboard will only appear in "Live Preview" mode and with this setting disabled, and Xcode will instantly reset the setting as soon as it detects any direct keyboard input while the preview has focus (and the Simulator app will not reflect this reset, so to do it again you'll have to toggle it twice). Worse, flipping the setting in the Simulator app is not enough by itself; you have to force the preview to fully reload the underlying simulator it's using. The easiest way to do this is to restart Xcode or to switch to a different simulated device (such as from iPhone 11 to iPhone 12). You can also try executing this command in a terminal:

xcrun simctl --set ~/Library/Developer/Xcode/UserData/Previews/Simulator\ Devices shutdown all

This command will not affect any simulators running in the iOS Simulator app, but will cause all previews to stop working until Xcode relaunches the simulated devices, and may cause Xcode's UI to temporarily behave strangely (or at least the effects were temporary when I tried it in Xcode 12.4).

Once the setting is in effect, focusing on a text input field will cause the software keyboard area to appear. The area is responsive to clicks and all the keys work, but the keyboard itself does not seem to render. It is obviously not intended that this works, and it may stop working at any time in the future.

Workaround for Live Preview running in Xcode Previews app on physical iPhone device

  1. Send the Xcode Previews app into the background (such as by swiping up from the bottom of the screen to view the App Switcher).
  2. Bring the Xcode Previews app back into the foreground.

How often will you probably need to use the above workaround?

After every full-build, but probably not after every partial re-build, of the SwiftUI Live Preview.

Tested On:

  • MacBook Pro (Retina, 13-inch, Late 2013) running macOS Big Sur Version 11.6
  • Xcode Version 13.0
  • iPhone X running iOS 15.0.1

Edit: I've discovered a closely related bug

There's a closely related bug which prevents the value of the SwiftUI View's @FocusState property (if it has one) from correctly updating in response to its TextField being tapped - even when the above workaround is successfully used to make the on-screen keyboard show when that TextField is tapped - providing that that SwiftUI View is the top-level View in the Preview.

Please see below for a demonstration of this bug, and an example of how to workaround it:

    struct MyForm: View {
      @FocusState private var isFocused: Bool
      @State private var text = ""
    
      var body: some View {
        VStack {
          Text("isFocused: \(isFocused ? "true" : "false")")
          Form {
            TextField("Enter text here", text: $text)
              .focused($isFocused)
          }
        }
      }
    }
    
    struct Bad_MyForm_Previews: PreviewProvider {
      static var previews: some View {
        /*
         * Due to another bug, paired with the fact that MyForm is the top-level
         * SwiftUI View in this Preview, the value of MyForm's `@FocusState`
         * property won't update in response to its TextField being tapped.
         * This is the case, regardless of if this Preview is being run as:
         *   1. A "Live Preview" in the Canvas in Xcode,
         *   2. Or as a "Preview on Device" via the "Xcode Previews" app on a
         *    physical iPhone - even if the keyboard shows.
         */
        MyForm()
      }
    }
    
    struct Good_MyForm_Previews: PreviewProvider {
      static var previews: some View {
        /*
         * But the bug mentioned above that prevents the value of `MyForm`'s
         * `@FocusState` property from correctly updating in response to its
         * TextField being tapped, *won't* affect *this* Preview, as in *this*
         * Preview, `MyForm` is *not* the top-level SwiftUI View.
         */
        ZStack {
          MyForm()
        }
      }
    }
Related