英文:
SwiftUI - Add a Navigation Bar Button on Condition
问题
给定我有一个像这样的视图:
@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")
}
这将产生一个如下所示的视图,这是预期的:

要向导航栏添加一个按钮,可以使用以下代码:
.navigationBarItems(trailing:
    Button(action: {print("Button was tapped")}) {
        Image(systemName: "plus")
            .resizable().frame(width: 20, height: 20)
    })
这将添加按钮,如预期所示。
是否有一种方式只根据条件添加(或显示)按钮?
if (self.tabIndex == 1){
  显示按钮
}
else {
  不显示按钮
}
英文:
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:
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
}
答案1
得分: 18
.navigationBarItems将在iOS的未来版本中被弃用,最好使用.toolbar(_:)视图修饰符。
.toolbar {
	ToolbarItemGroup(placement: .navigationBarTrailing) {
		if tabIndex == 2 {
            // 显示按钮
		}
	}
}
英文:
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
		}
	}
}
答案2
得分: 17
以下是可能的方法:
.navigationBarItems(trailing: self.tabIndex == 1 ? 
    AnyView(self.trailingButton) : AnyView(EmptyView()))
在body之下的某处:
var trailingButton: some View {
    Button(action: {print("按钮被点击了")}) {
        Image(systemName: "plus")
            .resizable().frame(width: 20, height: 20)
    }
}
英文:
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)
  }
}
答案3
得分: 5
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("按钮被点击")}) {
     Image(systemName: "plus")
      .resizable().frame(width: 20, height: 20)
    }
  }
})
.navigationBarItems(trailing: 
    Button(action: {print("按钮被点击")}) {
     Image(systemName: "plus")
      .resizable().frame(width: 20, height: 20)
    }.opacity(self.tabIndex == 1 ? 1 : 0)
)
英文:
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)
)
答案4
得分: 2
以下是已翻译的内容:
我知道这个问题有一个被接受的答案,我在我的解决方案中使用了它,但这是我所做的:
var doneButton: AnyView {
    if !fromPreferences {
        return AnyView(Button(action: self.doneAction) {
            Text("Done")
        })
    }
    return AnyView(EmptyView())
}
以及我在正文中如何使用它:
.navigationBarItems(trailing: doneButton)
感谢@Asperi提供的解决方案!
英文:
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!
答案5
得分: 1
以下是我为您翻译的内容:
这是对我有效的内容,即使我的条件为false,导致没有返回任何内容(工具栏项正确地未显示,没有错误)。我觉得这比挤入三元运算符更清晰一些。
.navigationBarItems(
    trailing: Button(
        action: {
            print("我的操作")
        }
    ) {
        if myBool {
            Text("我的按钮")
        }
    }
)
英文:
Here is what worked for me, even when my condition was false which resulted in nothing being returned (the bar item correctly did not show, without errors). I find it a little cleaner than squeezing in a ternary operator.
.navigationBarItems(
	trailing: Button(
		action: {
			print("My Action")
		}
	) {
		if myBool {
			Text("My Button")
		}
	}
)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论