[本文翻译自hackingwithswift,点击链接阅读原文]
当您想要使用SwiftUI显示两个单独的视图时,最简单、最直观的方法是在我们应用程序的底部使用一个选项卡栏。在我们的案例中,这意味着我们将把菜单视图放在一个选项卡中,将活动顺序放在另一个选项卡中。SwiftUI为此为我们提供了一个TabView
,它的工作方式与aUITabBarController非常类似。
按Cmd+N创建一个新的SwiftUI视图,将其称为“MainView”。创建选项卡就像在TabView
的实例中放置不同的视图一样简单,但为了将图像和文本添加到每个视图的选项卡栏项中,我们需要使用tabItem()
修饰符。
在我们编写MainView
代码之前,重要的是要记住在预览环境中添加Order
实例,以便OrderView
可以工作:
struct MainView_Previews: PreviewProvider {
static var previews: some View {
MainView()
.environmentObject(Order())
}
}
现在我们可以继续将MainView
更改为:
struct MainView: View {
var body: some View {
TabView {
ContentView()
.tabItem {
Label("Menu", systemImage: "list.dash")
}
OrderView()
.tabItem {
Label("Order", systemImage: "square.and.pencil")
}
}
}
}
让我们仔细看看我们的观点之一:
TabView {
ContentView()
.tabItem {
Label("Menu", systemImage: "list.dash")
}
这创建了一个ContentView
的实例,但对于其选项卡项目,我们使用了一种名为Label
的新视图类型,该视图类型同时处理显示文本和显示图像。这或多或少与使用单独的Text
和Image
对相同,但Label
增加了一些额外的智能——它确保两者保持相同,即使它们改变大小。
这个标签是表示其在标签栏中视图的东西。图像是使用Label
的systemImage
形式创建的,它允许我们从内置的SF符号图标集中加载图像——这是苹果专门为应用程序设计的2400多个图标。
为了使标签栏栩栩如生,我们需要更改iDineApp.swift,以便它创建一个MainView
而不是aContentView。所以,找到这个代码:
ContentView()
.environmentObject(order)
并用这个替换它:
MainView()
.environmentObject(order)
现在——终于!——您应该能够按Cmd+R来构建和运行您的应用程序,选择一些食物,将其添加到您的订单中,并看到信息自动出现在“Order
”选项卡中。
我喜欢这种方法的原因是,我们没有做真正的繁重的工作来同步用户界面的不同部分——ObservableObject
协议和@EnvironmentObject
属性确保用户界面的所有部分都保持最新状态。因此,一旦ItemDetail
屏幕宣布订单中添加了某些东西,OrderView
屏幕将自动刷新以显示更改。
在后台,任何依赖环境对象的视图在宣布更改时都会刷新。在实践中,这意味着SwiftUI将重新调用body
属性,这反过来又意味着body
内的所有内容都会从环境中读取最新值。
评论区