SwiftUI 布局:使用两个并排视图
UISplitViewController
是UIKit中最重要的UI组件之一,您会在许多Apple应用程序中看到它,例如 Notes,Mail 等。在iPad上,拆分视图并排显示两个视图,通常在左侧有一个主列表,在右侧有一个详细视图。在iPhone上,拆分视图会自动将两个视图折叠为一个视图,因此您会获得导航视图的 push 和 pop 行为。
SwiftUI没有与拆分视图控制器直接等效的功能,而是通过创造性地使用NavigationView
使相同的功能可用。您已经熟悉NavigationView
的基本用法,它使我们能够创建如下视图:
struct ContentView: View {
var body: some View {
NavigationView {
Text("Hello, World!")
.navigationBarTitle("Primary")
}
}
}
以前,您已经了解了在纵向模式下如何工作,但是在横向模式下会导致白屏。这是由于NavigationView
的分割视图行为:它设计为可用于两个视图而不是一个视图,现在,SwiftUI似乎并不在乎是否仅提供一个。
但是,如果我们确实提供了两个视图,那么我们将获得一些真正有用的行为。尝试将您的视图更改为此:
NavigationView {
Text("Hello, World!")
.navigationBarTitle("Primary")
Text("Secondary")
}
现在启动应用程序时,您看到的的内容取决于您的设备和方向:
- 在竖屏iPhone上,您会看到“Hello, World!”
- 在大尺寸横屏的iPhone(例如iPhone 11 Pro Max)上,您会看到“Secondary”。
- 在竖屏iPad上,您还将看到“Secondary”
- 在横屏iPad上,您会同时看到“Hello,World!”与“Secondary”并列。
在这些组合的第二个和第三个中,您会发现您可以从设备的左边缘滑动以调出另一个视图–“ Hello,World!”将在“ Secondary”的顶部部分滑动,并且可以通过在“ Secondary”视图中的任意位置轻按以将其关闭。具有这样的分割视图是利用iPad额外屏幕空间的好方法,同时也为用户提供了一种浏览内容的更快方法。
SwiftUI自动链接主视图和辅助视图,这意味着如果主视图中有NavigationLink
,它将自动在辅助视图中加载其内容:
NavigationView {
NavigationLink(destination: Text("New secondary")) {
Text("Hello, World!")
}
.navigationBarTitle("Primary")
Text("Secondary")
}
但是,至少现在,所有这些魔术都有一些缺点,我希望可以在以后的SwiftUI更新中修复这些缺点:
- 初始的辅助视图顶部没有导航栏,因此即使您可以设置标题,也不会显示任何内容。
- 后续的详细视图无论是否需要总会得到一个导航栏,因此您需要使用
navigationBarHidden(true)
来隐藏它。 - 即使有足够的空间,也无法使主视图在iPad上保持可见。
- 无法在次视图的导航栏中显示“菜单”按钮,以使主视图更容易被发现。
- 默认情况下,您无法使主视图以横向显示; SwiftUI始终选择详细内容。
我有信心将来会解决这些问题的原因是因为它们都可以在带有UISplitViewController
的UIKit中实现,因此希望在SwiftUI中启用相同功能只是时间问题。
提示:NavigationView
支持一个或两个子视图。尽管您可以在其中放置更多内容,但第三个及后续视图将被忽略。