Change iOS SwiftUI Keyboard Extension Height

Viewed 168

I have seen potential duplicates of this question but none of them seem to have a minimum reproducible example and have small snippets of code that leave out important context. Additionally, since I'm using SwiftUI I'm not sure that many of the answers apply.

I am using SwiftUI to build an iOS keyboard extension. Here is the relevant code:

import UIKit
import SwiftUI

class KeyboardViewController: UIInputViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let keyboardController = UIHostingController(rootView: KeyboardWrapper())
        keyboardController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        view.addSubview(keyboardController.view)
    }
}

struct KeyboardWrapper: View {
    var body: some View {
        GeometryReader { rect in
            Keyboard(rect: rect)
        }
    }
}

The root of my keyboard extension is at KeyboardViewController, which adds as a subview a UIHostingController that wraps the root of the SwiftUI views, KeyboardWrapper. KeyboardWrapper then creates the Keyboard. This works as a way to set up a keyboard that has the same height as the system keyboard, as shown here:

system-height keyboard

My question is how can I change the height of my keyboard? I have seen the posts around adding constraints but again they lack sufficient context for me to know exactly where to put them in the code.

2 Answers

It's easier to use anchors.

import UIKit
import SwiftUI

class KeyboardViewController: UIInputViewController {    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let keyboardController = UIHostingController(rootView: KeyboardWrapper())
        keyboardController.view.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(keyboardController.view)
        
        keyboardController.view.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
        keyboardController.view.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
        keyboardController.view.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
        keyboardController.view.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor).isActive = true
    }
}

struct KeyboardWrapper: View {
    var body: some View {
        HStack {
            Button(" A ") {
                print("A")
            }
            .background(Color.red)
            .foregroundColor(.white)

            Button(" B ") {
                print("B")
            }
            .background(Color.black)
            .foregroundColor(.white)

            Button(" C ") {
                print("C")
            }
            .background(Color.red)
            .foregroundColor(.white)

            Button(" D ") {
                print("D")
            }
            .background(Color.black)
            .foregroundColor(.white)
        }
    }
}

But I can see that your custom keyboard is embedded in a GeometryReader, which can lead to auto layout constraints not working properly. In that case, you can just fix the height by adding this line below the other constraints:

keyboardController.view.heightAnchor.constraint(equalToConstant: 120).isActive = true

You need a height constraint, and you need to set the priority.

See this snippet:

var expandedHeight : CGFloat = 500

var heightConstraint = NSLayoutConstraint(item: self.view, attribute:.height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 0.0, constant: expandedHeight)

heightConstraint.priority = .init(999)

myKeyboardView.addConstraint(heightConstraint)

Place this in the file that is creating the Keyboard view.

Related