I use ToolbarItem(placement: .keyboard)
to provide a button over the keyboard. However, it cannot achieve the full screen of the iPhone in landscape orientation. As shown in the screenshot below, it is really ugly...
Below is a sample code snippet, or you can try the DEMO Project:
struct ContentView: View {
@State private var text: String = ""
@FocusState private var isTextFieldFocused: Bool
var body: some View {
VStack {
Text("A Text Field Below.")
TextField("Enter text here.", text: $text)
.frame(height: 44)
.textFieldStyle(.roundedBorder)
.focused($isTextFieldFocused)
}
.onAppear {
self.isTextFieldFocused = true
}
.toolbar {
ToolbarItem(placement: .keyboard) {
_keyboardDismissButton()
}
}
}
@ViewBuilder
private func _keyboardDismissButton() -> some View {
Button {
self.isTextFieldFocused = false
} label: {
Image(systemName: "keyboard.chevron.compact.down")
.foregroundColor(.secondary)
.frame(height: 44)
.frame(maxWidth: .infinity)
.contentShape(Rectangle())
}
.buttonStyle(.plain)
}
}
I tried .ignoresSafeArea(.all, edges: .horizontal)
or related combinations without any luck. Any modifiers on the button had no effect.
I know we can implement it in UIKit, just wondering if there is any workaround to handle it in SwiftUI. Or is this a known issue? I don't think this is the intended design...
Environment:
Xcode 15.0 (15A240d)
iOS 17.0
I tried looking for some kind of native and standard solution but it seems there is some kind of limitation drawing things over that area except forcing it with offsets... This is based on my research and I hope someone proves me wrong, I'm still learning nonetheless.
So, what I did was the following:
I've created a custom
Rectangle
component which takes in aboolean
to indicate whether this is going to be placed left or right:Then I used it like this in the already present
toolbar
:One of the issues of going this way is that I did not know the exact color of the toolbar button there, and using
.secondary
created a dark grey Rectangle. If you know what the right color is I think it will be indistinguishable from the real button.Here's the result I get:
Let me know what you think about this!