Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI - Add a Navigation Bar Button on Condition

Given i have a view like this..

@State var tabIndex: Int = 0
           
 var body: some View {

  TabView(selection: $tabIndex)
  {
   Text("Tab 1").tabItem({
    Image(systemName: "message")
   }).tag(0)           
                
   Text("Tab 2").tabItem({
    Image(systemName: "arkit")
   }).tag(1)             
          
   Text("Tab 3").tabItem({
    Image(systemName: "battery.100")
   }).tag(2)
  }.navigationBarTitle("Tabbed View")
            
 }

This produces a view like this which is what is expected:

enter image description here

to add a navigation button to the bar i can use

 .navigationBarItems(trailing:
  Button(action: {print("Button was tapped")}) {
   Image(systemName: "plus")
    .resizable().frame(width: 20, height: 20)
  })

Which adds the button as expected

Is there any way to only add (or show) the button based on a condition?

if (self.tabIndex == 1){
  show button
}
else {
 don't show button
}
like image 350
Scott Crowther Avatar asked Jan 03 '20 09:01

Scott Crowther


People also ask

How do I add a navigation bar button in Swift?

You need to open the storyboard, delete the view controller that you have, press cmd , shift , l , and then search for navigation controller . Drag that onto the storyboard. You now need to click on the navigation controller and set it to be the is initial view controller under the attributes inspector .

How do I add a button to the navigation bar on storyboard?

Drop a button on the right-hand side of the navigation bar, then switch to the assistant editor so we can connect it to some code. Ctrl-drag from your new bar button item into your source code, and when you release your mouse button change Connection from “Outlet” to “Action”.


Video Answer


4 Answers

As .navigationBarItems will be deprecated in a future version of iOS it's better to use .toolbar(_:) View Modifier.

.toolbar {
    ToolbarItemGroup(placement: .navigationBarTrailing) {
        if tabIndex == 2 {
            // show button
        }
    }
}
like image 145
saltwat5r Avatar answered Oct 13 '22 16:10

saltwat5r


Here is possible approach

.navigationBarItems(trailing: self.tabIndex == 1 ? 
    AnyView(self.trailingButton) : AnyView(EmptyView()))

somewhere below body

var trailingButton: some View {
  Button(action: {print("Button was tapped")}) {
   Image(systemName: "plus")
    .resizable().frame(width: 20, height: 20)
  }
}
like image 39
Asperi Avatar answered Oct 13 '22 16:10

Asperi


If you don't want to use AnyView, you could also use Group or Opacity too.

.navigationBarItems(trailing: Group {
  if self.tabIndex == 1 {
    Button(action: {print("Button was tapped")}) {
     Image(systemName: "plus")
      .resizable().frame(width: 20, height: 20)
    }
  }
})
.navigationBarItems(trailing: 
    Button(action: {print("Button was tapped")}) {
     Image(systemName: "plus")
      .resizable().frame(width: 20, height: 20)
    }.opacity(self.tabIndex == 1 ? 1 : 0)
)
like image 5
user12208004 Avatar answered Oct 13 '22 17:10

user12208004


I know this question has an accepted answer and I used it in my own solution but here's what I did:

var doneButton:AnyView {
    if !fromPreferences {
        return AnyView(Button(action: self.doneAction) {
            Text("Done")
        })
    }
    return AnyView(EmptyView())
}

and how I used it in the body:

.navigationBarItems(trailing: doneButton)

thanks @Asperi for the solution!

like image 2
Chucky Avatar answered Oct 13 '22 15:10

Chucky