SwiftUI – 在特定条件下添加导航栏按钮

huangapple go评论75阅读模式
英文:

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

}

这将产生一个如下所示的视图,这是预期的:

SwiftUI – 在特定条件下添加导航栏按钮

要向导航栏添加一个按钮,可以使用以下代码:

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

SwiftUI – 在特定条件下添加导航栏按钮

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")
		}
	}
)

huangapple
  • 本文由 发表于 2020年1月3日 17:12:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/59575789.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定