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 HStack
ed ForEach
s 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.