似乎有一种简单的方法可以使美观的iOS应用程序在iPad空间上运行。一个不涉及重写SwiftUI应用的程序。
基本的SplitView
和SplitViewController
问题似乎...好像是一个思想不周的问题空间...我有一个基本的问题-使用ContentView显示卡-我想要可以在iPad上运行...只是更大的视口...
有任何简单的方法可以使用SwiftUI吗?
答案 0 :(得分:4)
因此,这是遵循Apple Fruta app示例(使用Xcode12来设置iOS,14和macOS11的最低目标)的iPhone,iPad和mac应用程序的方式。
使用这种实现SwiftUI的方法,您将拥有iPad正在使用的以及Mac使用的拆分视图。对于iPhone,您将拥有经典的标签栏。
这是一个随时可以使用的代码,因此,如果不需要Mac应用程序,只需删除#else
和#end
之间的部分。我实施了它,以防其他人发现它很方便。 #if os(iOS)
和#else
之间的代码适用于iPhone和iPad。
查找我在代码中添加的注释,以解释在何时创建拆分视图。
用于保存导航类型(取决于设备)的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置于纵向模式时,视图将作为导航,而将其添加至横向时,视图将被拆分。
enum NavigationItem {
case home
}
struct SidebarNavigationView: View {
@State private var selection: Set<NavigationItem> = [.home]
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 as there is a bug
/// that unable the user to show the sidebar again if this
/// hack is not enabled.
func toggleSidebar() {
#if os(macOS)
NSApp
.keyWindow?
.firstResponder?
.tryToPerform(#selector(NSSplitViewController.toggleSidebar(_:)),
with: nil)
#endif
}
}