0

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?

Clifton Labrum
  • 13,053
  • 9
  • 65
  • 128

1 Answers1

0

I guess I was so focused on getting a modifier to work that I didn't think of another obvious option. This works fine:

ToolbarItem(placement: .navigationBarTrailing) {
  if showDone{
    Button(action: {
      hideKeyboard()
    }){
      Text("Hide A")
    }
  }
}
Clifton Labrum
  • 13,053
  • 9
  • 65
  • 128