My goal is to show a button in the navigation bar of a SwiftUI iOS app when the keyboard is visible, and hide it when the keyboard is not. I can get it to work with a button inside the main body of my view, but anything in the nav bar doesn't respond to my @State
variable.
Here's a sample project:
struct ContentView: View {
@State var showDone = false
@State var text = "Testing"
var body: some View {
ZStack{
NavigationView {
VStack{
ZStack{}
.toolbar{
ToolbarItem(placement: .principal) {
Text("Nav Bar")
}
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: {
hideKeyboard()
}){
Text("Hide A")
}
.opacity(showDone ? 1 : 0) //<-- This doesn't work
}
}
//This is just for showing the keyboard when focused
TextField("", text: $text)
.textFieldStyle(RoundedBorderTextFieldStyle())
//This button works correctly
Button(action: {
hideKeyboard()
}){
Text("Hide B")
}
.opacity(showDone ? 1 : 0)
}
.onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillShowNotification)) { _ in
print("keyboard showing")
showDone = true
}
.onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillHideNotification)) { _ in
print("keyboard hidden")
showDone = false
}
}
}
}
}
I have a global function that hides the keyboard:
//Global function for hiding the keyboard
extension View {
func hideKeyboard() {
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
}
I've tried putting the opacity
modifier on the Text("Hide A")
, on the Button
and on the ToolbarItem
itself and none of them work (and putting it on the ToolbarItem
is not allowed by the compiler).
Has anyone ever encountered navigation bar stuff not responding to @State
variables?