SwiftUI - 如何根据条件添加导航栏按钮

13
假设我有以下视图...
@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){
  show button
}
else {
 don't show button
}

2
TabView 嵌套在 NavigationView 中不是一个好的选择。相反,TabView 中的每个选项卡都应该有自己的 NavigationView。例如,如果有三个选项卡,并且每个选项卡都需要其自己的导航层次结构,则应该有三个 NavigationView - nayem
5个回答

20

由于将来的iOS版本中,.navigationBarItems 将被弃用,因此最好使用.toolbar(_:)

视图修饰符。

.toolbar {
    ToolbarItemGroup(placement: .navigationBarTrailing) {
        if tabIndex == 2 {
            // show button
        }
    }
}

2
这应该是新的被接受的答案。 - inreflection7
不需要使用 AnyView - Abhinav Mathur
我的代码中没有定义navigationBarTrailing。 - aehlke

17

以下是可能的方法

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

body 标签下方的某个地方

var trailingButton: some View {
  Button(action: {print("Button was tapped")}) {
   Image(systemName: "plus")
    .resizable().frame(width: 20, height: 20)
  }
}

1
我很好奇为什么你不直接将按钮放在相关视图下的选项卡上?有必要将它放在TabView上吗? - Rillieux

5

如果您不想使用 AnyView,您也可以使用 GroupOpacity

.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)
)

2
我知道这个问题有一个被接受的答案,并且我在自己的解决方案中使用了它,但是这是我的做法:
var doneButton:AnyView {
    if !fromPreferences {
        return AnyView(Button(action: self.doneAction) {
            Text("Done")
        })
    }
    return AnyView(EmptyView())
}

我在正文中如何使用它:

.navigationBarItems(trailing: doneButton)

今日免费次数已满, 请开通会员/明日再来

1

以下是我使用的方法,即使我的条件为false也不会返回任何内容(bar项目正确地没有显示,没有错误)。我认为这比挤入三元运算符更简洁。

.navigationBarItems(
    trailing: Button(
        action: {
            print("My Action")
        }
    ) {
        if myBool {
            Text("My Button")
        }
    }
)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接