SwiftUi how to display a keyboard with numpad in the side

I need to display a full keyboard in my app with a numpad in the side, like the one I screenshot from a Boeing App.

I try the .keyboardType(.numberPad) and many other Modifiers, but I could not get the same keyboard as the App from Boeing mentioned before.

Any thoughts?

Thanks

Keyboard I'm looking for


Solution 1:

The basic Apple keyboard includes numbers on the second page. I would just use that if you need characters and numbers, or use the .numberPad if you need only numbers. Unless you're using this keyboard for fullscreen iOS or the iPad, your screenshot looks too wide too for the UI to work. Additionally, building a keyboard would be a lot of work for any benefits your custom keyboard might provide.

Here's a working example of a custom keyboard to get you started. Obviously you'll need to work on the appearance and adding some more buttons, but this will illustrate the basic structure of what you want.

struct CustomKeybaord: View {

    @State var text: String = ""

    let topCharacters: [String] = ["Q", "W", "E", "R", "T", "Y", "U", "I","O", "P"]
    let topMiddleCharacters: [String] = ["A", "S", "D", "F", "G", "H", "J", "K", "L"]
    let bottomMiddleCharacters: [String] = ["Z", "X", "C", "V", "B", "N", "M"]

    func keyboardTap(character: String) {
        self.text += character
    }
                                    
    var body: some View {
        VStack {
            Text(text)
            HStack {
                ForEach(topCharacters, id: \.self) { character in
                    KeyboardButton(character: character, color: .white, function: keyboardTap)
                        .padding(5)
                }
            }
        
            HStack {
                ForEach(topMiddleCharacters, id: \.self) { character in
                    KeyboardButton(character: character, color: .white, function: keyboardTap)
                        .padding(5)
                }
            }
            .padding(.horizontal, 50)
        
            HStack {
                ForEach(bottomMiddleCharacters, id: \.self) { character in
                    KeyboardButton(character: character, color: .white, function: keyboardTap)
                        .padding(5)
                }
            
            }
            .padding(.horizontal, 75)
        }
        .background(Color.init(white: 0.9))
        .frame(height: 100)
    }
 }

struct KeyboardButton: View {
    let character: String
    let color: Color
    var function: (String) -> Void
    var body: some View {
        Button {
            function(character)
        } label: {
            Text(character)
                .padding()
                .frame(maxWidth: .infinity, maxHeight: .infinity)
                .background(color)
                .foregroundColor(.black)
        }
    }
}

You'll also want to abstract away the HStacked ForEachs into an intermediate view.

The hardest thing left for you to do is find a way to calculate the key button sizes responsibly. Unless you want them to be a fixed size (which would be a bad idea, because it wouldn't work for any but one iPad size) you'll have figure out a way to calculate a universal button size based on the overall screen width using GeometryReader. In my example I use frame(maxWidth: .infinity, maxHeight: .infinity) to give each each button in a row the same size, but this doesn't ensure that buttons on different rows will be the same size.