keyboard can't be popped up in live preview mode

In the simulator, everything is ok. However, in live preview mode of canvas, no keyboard pops up when I tap in the textfield. Did I miss anything? Or need more codes in preview?Thanks in advance.

Accepted Answer

There is apparently a workaround for getting the on-screen keyboard to open in the Live Preview in the Canvas in Xcode (I remember reading about it somewhere on StackOverflow a long time ago). That workaround involved doing something like running your app in the Simulator app, clicking on a Text-Input-View and toggling on the on-screen keyboard if it isn't already toggled on, via the I/O -> Keyboard -> Toggle Software Keyboard Menu Item found inside the Menu Bar for the Simulator app, or alternatively, by hitting Command+K. But I don't know that this workaround ever worked for me - however, it may have indeed worked for me, but where I just didn't notice that it had, as even if you manage to get the on-screen keyboard to open for you in the Live Preview in the Canvas in Xcode, you'll probably find like I have, that it will be invisible whilst it's open!

By the way, fortunately, any keyboard toolbar you add to your app, will be visible in the preview - at least providing that you succeed in getting the on-screen keyboard to open for you in the preview.

Providing that you can get the on-screen keyboard to open for you in the preview, then to make it easier to type text into Text-Input-View's, you could do something like the following:

  1. Run your application in the Simulator app for a matching device to the one you'd be using when previewing your SwiftUI View, and get the on-screen keyboard to visibly open up in the Simulator.

  2. Then take a screenshot of it, and crop that screenshot-image down to just the on-screen keyboard portion of it.

  3. Create and use a ViewModifier that will display that cropped-screenshot-image of the on-screen keyboard for that device, at the bottom of the preview, whenever the on-screen keyboard is open.

    3.1. By the way, you could hook into keyboard notifications that are automatically posted to the NotificationCenter whenever the on-screen keyboard opens and closes, to automatically set a boolean flag to false or true to represent this, and then use that flag to control when the ViewModifier you write does and does not display the image.

     3.1.1. Alternatively, you could take the following approach that would make the implementation of the ViewModifier you write simpler, but make it more complex and verbose to **use**:
    
     3.1.2. You could provide to the ViewModifier at the call-site, an `FocusState.Binding` instance or a `Bool` instance which you could set based on whether or not the `FocusState.Binding` instance's `wrappedValue` is currently equal to `nil`, to teach the ViewModifier when it should and should not display the screenshot-image of the on-screen keyboard.
    

    3.2. A more complex solution that might work, would be programmatically finding the UIWindowScene that contains the actual on-screen keyboard (when it's known that the on-screen keyboard has been opened-up) and use the relevant UIKit-provided API's to create a snapshot view of its UIView Hierarchy, which you could then get your ViewModifier to render at the bottom of the preview using a struct you create that conforms to the UIViewRepresentable protocol, as I'm guessing this would make those UIViews actually become visible.

     3.2.1. Also, if you head down this route, you might manage to figure out a workaround for the bug itself that causes the on-screen keyboard to be invisible whilst open in the Live Preview in the Canvas in Xcode, in such a way that you could make the actual on-screen keyboard become visible in such previews. However I _did_ head down this route a little while ago, and found no success myself at making the on-screen keyboard's keys become visible. Although, I did manage to make the region of the on-screen keyboard display a solid color, by setting the `backgroundColor` of the `UIView`'s to a `UIColor`.
    

Also, for me at least, I've found that I'm unable to use my Mac's physical keyboard to type into Text-Input-Views in the Live Preview in the Canvas in Xcode, even when the on-screen keyboard is open, despite the fact that in the Simulator app, I have the "Connect Hardware Keyboard" Menu Item checked, which is a Menu Item found under the I/O -> Keyboard Sub-Menu in the Menu Bar for the Simulator app.

Obviously, all of this would be a lot of work to do, so if you can bare just typing in gibberish when typing into Text-Input-Views in the preview, and you manage to get the on-screen keyboard to open but it remains invisible for you, I recommend you just randomly click in the region in which it would normally be visible, to type random characters into the Text-Input-View.

  • Thank you so much for your exhaustive answer.

  • I give up. Maybe the simulator is a better way for this case. :-)

Add a Comment

Answers

It might be a bug in xcode.

  1. Check it I/O → Keyboard → Connect Hardware Keyboard. Need to be disabled.
  2. If there is okay. Try to use different simulated device or Reopen preview.
  3. Try to create another text input on another screen. Maybe the problem is in your text input
  4. Try to clean project , remove derive data and restart Xcode

a) You can remove derived data via terminal: xcrun simctl --set ~/Library/Developer/Xcode/UserData/Previews/Simulator\ Devices shutdown all

b) Or in Xcode -> preferences -> Locations -> Derived data arrow (small button) -> remove project folder

  • I have tried 4 methods above one by one:

    Disabling "Connect Hardware Keyboard" seems only to affect the behavior of simulators, but not the canvas.I switch to different simulators, include iPhone & iPad. But the problem is still there.I add a new swiftui view and make it to have the simplest code. But it is still no go.

    struct TextFieldPopupView: View {     @State private var text = ""     var body: some View {         TextField("Hello", text: $text)             .textFieldStyle(RoundedBorderTextFieldStyle())     } } struct TextFieldPopupView_Previews: PreviewProvider {     static var previews: some View {         TextFieldPopupView()     } } 4. Removing derived data has no effect yet.

    Thank you all the same.

Add a Comment

I have tried 4 methods above one by one.

  1. Disabling "Connect Hardware Keyboard" seems only to affect the behavior of simulators, but not the canvas.
  2. I switch to different simulators, including iPhone & iPad. But the problem is still there.
  3. I add a brand new swiftui view and make it to be the simplest codes. But it is still no go.
struct TextFieldPopupView: View {
    @State private var text = ""
    var body: some View {
        TextField("Hello", text: $text)
            .textFieldStyle(RoundedBorderTextFieldStyle())
    }
}
struct TextFieldPopupView_Previews: PreviewProvider {
    static var previews: some View {
        TextFieldPopupView()
    }
}
  1. Removing derived data and restarting has no effect yet.

Thank you all the same.

I'm just reposting the content of my StackOverflow answer here: https://stackoverflow.com/questions/56613157/enable-keyboard-in-xcode-preview/69431429#69431429 .

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.

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
  • @jeremy-dev Thanks for your answer. :-) Is there any workaround for "Live Preview" in the Canvas in Xcode?

  • @test1229, you're welcome. Please see my new answer below.

Add a Comment

I just discovered an additional bug that's related to this 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()
    }
  }
}
  • Thanks a ton!! Saved my day!!

Add a Comment

There is apparently a workaround for getting the on-screen keyboard to open in the Live Preview in the Canvas in Xcode (I remember reading about it somewhere on StackOverflow a long time ago). That workaround involved doing something like running your app in the Simulator app, clicking on a Text-Input-View and toggling on the on-screen keyboard if it isn't already toggled on, via the I/O -> Keyboard -> Toggle Software Keyboard Menu Item found inside the Menu Bar for the Simulator app, or alternatively, by hitting Command+K. But I don't know that this workaround ever worked for me - however, it may have indeed worked for me, but where I just didn't notice that it had, as even if you manage to get the on-screen keyboard to open for you in the Live Preview in the Canvas in Xcode, you'll probably find like I have, that it will be invisible whilst it's open!

By the way, fortunately, any keyboard toolbar you add to your app, will be visible in the preview - at least providing that you succeed in getting the on-screen keyboard to open for you in the preview.

Providing that you can get the on-screen keyboard to open for you in the preview, then to make it easier to type text into Text-Input-View's, you could do something like the following:

  1. Run your application in the Simulator app for a matching device to the one you'd be using when previewing your SwiftUI View, and get the on-screen keyboard to visibly open up in the Simulator.

  2. Then take a screenshot of it, and crop that screenshot-image down to just the on-screen keyboard portion of it.

  3. Create and use a ViewModifier that will display that cropped-screenshot-image of the on-screen keyboard for that device, at the bottom of the preview, whenever the on-screen keyboard is open.

    3.1. By the way, you could hook into keyboard notifications that are automatically posted to the NotificationCenter whenever the on-screen keyboard opens and closes, to automatically set a boolean flag to false or true to represent this, and then use that flag to control when the ViewModifier you write does and does not display the image.

     3.1.1. Alternatively, you could take the following approach that would make the implementation of the ViewModifier you write simpler, but make it more complex and verbose to **use**:
    
     3.1.2. You could provide to the ViewModifier at the call-site, an `FocusState.Binding` instance or a `Bool` instance which you could set based on whether or not the `FocusState.Binding` instance's `wrappedValue` is currently equal to `nil`, to teach the ViewModifier when it should and should not display the screenshot-image of the on-screen keyboard.
    

    3.2. A more complex solution that might work, would be programmatically finding the UIWindowScene that contains the actual on-screen keyboard (when it's known that the on-screen keyboard has been opened-up) and use the relevant UIKit-provided API's to create a snapshot view of its UIView Hierarchy, which you could then get your ViewModifier to render at the bottom of the preview using a struct you create that conforms to the UIViewRepresentable protocol, as I'm guessing this would make those UIViews actually become visible.

     3.2.1. Also, if you head down this route, you might manage to figure out a workaround for the bug itself that causes the on-screen keyboard to be invisible whilst open in the Live Preview in the Canvas in Xcode, in such a way that you could make the actual on-screen keyboard become visible in such previews. However I _did_ head down this route a little while ago, and found no success myself at making the on-screen keyboard's keys become visible. Although, I did manage to make the region of the on-screen keyboard display a solid color, by setting the `backgroundColor` of the `UIView`'s to a `UIColor`.
    

Also, for me at least, I've found that I'm unable to use my Mac's physical keyboard to type into Text-Input-Views in the Live Preview in the Canvas in Xcode, even when the on-screen keyboard is open, despite the fact that in the Simulator app, I have the "Connect Hardware Keyboard" Menu Item checked, which is a Menu Item found under the I/O -> Keyboard Sub-Menu in the Menu Bar for the Simulator app.

Obviously, all of this would be a lot of work to do, so if you can bare just typing in gibberish when typing into Text-Input-Views in the preview, and you manage to get the on-screen keyboard to open but it remains invisible for you, I recommend you just randomly click in the region in which it would normally be visible, to type random characters into the Text-Input-View.

  • Thank you so much for your exhaustive answer.

  • I give up. Maybe the simulator is a better way for this case. :-)

Add a Comment

The same problem happens to me for a long time, I submitted an issue, and Apple recommend to download Xcode 13.3.1, and macOs 12.4 Beta, now is working perfect, I can enter values with the physical keyboard in any TextField preview. I don't know if downloading only Xcode 13.3.1 will resolve the problem, I had before 13.2.1 I think