这就是你如何按照Apple Fruta app 示例设置你的 iPhone、iPad 和 mac 应用程序,使用 Xcode12,iOS14 和 macOS11 作为最低目标。
使用这种实现 SwiftUI 的方式,您将拥有 iPad 和 mac 使用的拆分视图。关于 iPhone,您将拥有经典的标签栏。
这是一个可以使用的代码,所以如果你不需要mac应用程序,只需删除#else和#end之间的部分即可。我实现了它以防其他人觉得它很方便,因为它非常适合多平台应用程序项目。 #if os(iOS) 和 #else 之间的代码适用于 iPhone 和 iPad。
查找我在代码中添加的 cmets,这些 cmets 解释了创建拆分视图的时间点。
根据设备保存导航类型的 ContentView:
struct ContentView: View {
#if os(iOS)
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
#endif
@ViewBuilder
var body: some View {
#if os(iOS)
if horizontalSizeClass == .compact {
TabBarNavigationView() // For iPhone
}
else {
SidebarNavigationView() // For iPad
}
#else
SidebarNavigationView() // For mac
.frame(minWidth: 900, maxWidth: .infinity, minHeight: 500, maxHeight: .infinity)
#endif
}
}
然后,使用您的标签枚举来声明经典的 iPhone 标签栏
(HomeView 可以替换为您的任何 SwiftUI 视图):
enum TabItem {
case home
}
struct TabBarNavigationView: View {
@State private var selection: TabItem = .home
var body: some View {
TabView(selection: $selection) {
NavigationView {
HomeView() // Create a SwiftUI HomeView or add your view
}
.tabItem {
Image(systemName: "house")
.font(.headline)
.imageScale(.medium) }
.tag(TabItem.home)
}
}
}
这就是 iPad 和 mac 经典拆分视图的视图。当 iPad 处于纵向模式时,您的视图将作为导航,而在横向添加时,您的视图将被拆分。
struct SidebarNavigationView: View {
@SceneStorage("selection")
var selection: String?
var content: some View {
List(selection: $selection) {
NavigationLink(destination: HomeView()) {
Label(title: { Text("Home") },
icon: { Image(systemName: "house")
.font(.headline)
.imageScale(.medium) })
}
.tag(NavigationItem.home)
}
.listStyle(SidebarListStyle())
}
var body: some View {
NavigationView {
#if os(iOS)
content
#else
content
.frame(minWidth: 200, idealWidth: 200, maxWidth: 200, maxHeight: .infinity)
.toolbar {
ToolbarItem(placement: .navigation) {
Button(action: toggleSidebar ) {
Image(systemName: "sidebar.left")
.foregroundColor(.blue)
}
}
}
#endif
// This is the part where the magic happens for the split view.
// Instead of the Text, add any view you want in place.
// Play here to see what fits best for you.
Text("Content List")
.frame(maxWidth: .infinity, maxHeight: .infinity)
#if os(iOS)
Text("Split view for iPad")
.frame(maxWidth: .infinity, maxHeight: .infinity)
#else
Text("Split view for macOS")
.frame(maxWidth: .infinity, maxHeight: .infinity)
.toolbar { Spacer() }
#endif
}
}
}
extension SidebarNavigationView {
/// Show or hide the sidebar list in macOS.
///
/// Needed for when the sidebar is hidden from the user
/// action as there is a bug in this version of SwiftUI
/// that block the user to show the sidebar again without
/// this hack.
func toggleSidebar() {
#if os(macOS)
NSApp
.keyWindow?
.firstResponder?
.tryToPerform(#selector(NSSplitViewController.toggleSidebar(_:)),
with: nil)
#endif
}
}