Switching to custom keyboard size glitches

I've created a custom keyboard and implemented the:

class KeyboardViewController: UIInputViewController

The imlementation looks like this:

    override func viewDidLoad() {
        super.viewDidLoad()

        var stack = UIStackView()
        stack.axis = .vertical
        stack.spacing = 8
        stack.translatesAutoresizingMaskIntoConstraints = false
        stack.distribution = .fill
        stack.heightAnchor.constraint(equalToConstant: 200).isActive = true
        
        ....

        view.addSubview(stack)
        NSLayoutConstraint.activate([
            stack.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
            stack.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
            stack.topAnchor.constraint(equalTo: view.topAnchor, constant: 10),
            stack.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -10)
        ])

The problem is that the keyboard seems to start showing in the size (I've printed the parent frame):

Optional(<UIView: 0x101008480; frame = (0 0; 390 844); autoresize = W+H; layer = <CALayer: 0x600000207b80>>)

and than resizes to my given height. But it's not fast enough so that I can see some glitches whenever I switch from another keyboard to my custom keyboard.

Is there a way to prevent this resizing or start the keyboard in a given size? This is just not the best user experience.

I’m having the exact same issue.

my setup

  - UIInputViewController subclass

  - A UIHostingController wrapping our SwiftUI view, added as a child view controller

  - The hosting controller's view is pinned to self.view with Auto Layout constraints (leading, trailing, top, bottom)

  - The SwiftUI view has a fixed .frame(height: 260)

  - No custom UIInputView, no allowsSelfSizing

I’ve tried:

explicit frames, height constraints, UIInputView vs direct self.view, disabling UIHostingController keyboard avoidance, runtime overrides of _UIHostingView notification handlers).

None had any effect.

Hello,

This is an issue we're aware of, but we're not aware of any recommended workaround so far. If you find something that helps you avoid the issue, please share it with the community by posting it here.

Even though we're aware of this issue, we still encourage you to open a bug report, and post the FB number here once you do. The specific info you include your bug report might help our investigation, and filing the bug report you to get notified when it is resolved.

Bug Reporting: How and Why? explains how you can open a bug report.

Thank you for your patience,

Richard Yeh  Developer Technical Support

Hey guys, here is what worked for me:

import UIKit

final class KeyboardViewController: UIInputViewController {
    private var heightConstraint: NSLayoutConstraint?
    private var viewWillAppearWasCalled = false

    override func viewDidLoad() {
        super.viewDidLoad()

        // Create early, but do NOT activate yet
        heightConstraint = inputView?.heightAnchor.constraint(equalToConstant: preferredKeyboardHeight())
        // Important: use required - 1 to avoid fighting UIKit's own host constraints.
        heightConstraint?.priority = UILayoutPriority.required - 1
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        viewWillAppearWasCalled = true
    }

    override func updateViewConstraints() {
        super.updateViewConstraints()

        // Important: activate height constraint after viewWillAppear

        guard viewWillAppearWasCalled,
              let inputView,
              let heightConstraint
        else {
            return
        }
        
        heightConstraint.constant = preferredKeyboardHeight(for: inputView.bounds.size)
        if !heightConstraint.isActive {
          heightConstraint.isActive = true
        }
    }

    private func preferredKeyboardHeight(for size: CGSize? = nil) -> CGFloat {
        guard let size else {
          // In viewDidLoad size is nil
          return 256 // Some initial value
        }
        return 256 // Some custom value depending on size
    }
}

Hope that helps :)

Switching to custom keyboard size glitches
 
 
Q