我有一个简单的TabView:
TabView {
NavigationView {
VStack {
NavigationLink(destination: Text("Detail")) {
Text("Go to detail")
}
}
}
.tabItem { Text("First") }
.tag(0)
Text("Second View")
.tabItem { Text("Second") }
.tag(1)
}
Run Code Online (Sandbox Code Playgroud)
当我转到选项卡1上的详细信息视图时,切换到选项卡2,然后再切换回选项卡1,我假设将返回到详细信息视图(iOS中随处可见的基本UX)。而是重置为选项卡1的根视图。
由于SwiftUI并不希望立即提供支持,因此该如何解决呢?
这里不太明显的解决方案是实际上不使用SwiftUI。为了获得UIKit的行为,我将UIKit包裹UITabBarController
在SwiftUI UIViewControllerRepresentable
中,例如以下示例:https : //developer.apple.com/tutorials/swiftui/interface-with-uikit。
我在这里展示了一个基本的实现。完整的最新实现在github上:https : //gist.github.com/Amzd/2eb5b941865e8c5cccf149e6e07c8810
将UIKit UITabBarController包装在SwiftUI视图中:
struct UIKitTabView: View {
var viewControllers: [UIHostingController<AnyView>]
init(_ tabs: [Tab]) {
self.viewControllers = tabs.map {
let host = UIHostingController(rootView: $0.view)
host.tabBarItem = $0.barItem
return host
}
}
var body: some View {
TabBarController(controllers: viewControllers)
.edgesIgnoringSafeArea(.all)
}
struct Tab {
var view: AnyView
var barItem: UITabBarItem
init<V: View>(view: V, barItem: UITabBarItem) {
self.view = AnyView(view)
self.barItem = barItem
}
}
}
Run Code Online (Sandbox Code Playgroud)
struct TabBarController: UIViewControllerRepresentable {
var controllers: [UIViewController]
func makeUIViewController(context: Context) -> UITabBarController {
let tabBarController = UITabBarController()
tabBarController.viewControllers = controllers
return tabBarController
}
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
struct ExampleView: View {
@State var text: String = ""
var body: some View {
UIKitTabView([
UIKitTabView.Tab(
view: NavView(),
barItem: UITabBarItem(title: "First", image: nil, selectedImage: nil)
),
UIKitTabView.Tab(
view: Text("Second View"),
barItem: UITabBarItem(title: "Second", image: nil, selectedImage: nil)
)
])
}
}
struct NavView: View {
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: Text("This page stays when you switch back and forth between tabs (as expected on iOS)")) {
Text("Go to detail")
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个简单的示例,说明如何使用根目录下的项目列表保留导航堆栈的状态:
struct ContentView: View {
var body: some View {
TabView {
Text("First tab")
.tabItem { Image(systemName: "1.square.fill"); Text("First") }
.tag(0)
SecondTabView()
.tabItem { Image(systemName: "2.square.fill"); Text("Second") }
.tag(1)
}
}
}
struct SecondTabView: View {
private struct ListItem: Identifiable {
var id = UUID()
let title: String
}
private let items = (1...10).map { ListItem(title: "Item #\($0)") }
@State var selectedItemIndex: Int? = nil
var body: some View {
NavigationView {
List(self.items.indices) { index in
NavigationLink(destination: Text(self.items[index].title),
tag: index,
selection: self.$selectedItemIndex) {
Text(self.items[index].title)
}
}
.navigationBarTitle("Second tab", displayMode: .inline)
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
657 次 |
最近记录: |