Search code examples
swiftuiios13ios-navigationview

Toggle a button on Navigation Bar in SwiftUI & have it change appearance


Using SwiftUI, I would like to have the ability to change the button on my NavigationView based upon some Bool value indicating if it should be On or Off.

enter image description here

This would behave similar to how with UIKit you can replace a bar button item on either side of the screen to show a different button & associated action upon clicking.


Solution

  • I am able to get it working with the following code, but I am not certain if this is the best way to accomplish it, so am open to improvement.

    import SwiftUI
    
    struct HomeList: View {
        @State var isOn = true
    
        var body: some View {
            NavigationView {
                List(1 ..< 4) { index in
                    Text("Row \(index)")
                }
                .navigationBarTitle(Text(verbatim: "Title"), displayMode: .inline)
                .navigationBarItems(trailing:
                    Button(action: {
                        self.isOn = !self.isOn
                    }, label: {
                        Text(self.isOn ? "On" : "Off")
                    })
                )
            }
        }
    }
    

    The key pieces being:

    • Using the @State modifier on my isOn variable, which tells my interface to invalidate & re-render upon changes
    • Having my Button action modify isOn &it can also support other actions if I need
    • The ternary operator in my Button label that updates the Text (or an Image if I want) to reflect the correct appearance

    Finally, how it appears in action:

    enter image description here