SwiftUI:再次点击所选选项卡时弹出到根视图 [英] SwiftUI: Pop to root view when selected tab is tapped again
问题描述
起点是 TabView 中的 NavigationView.当再次点击所选选项卡时,我正在努力寻找 SwiftUI 解决方案以弹出导航堆栈中的根视图.在 SwiftUI 之前,这很简单:
Starting point is a NavigationView within a TabView. I'm struggling with finding a SwiftUI solution to pop to the root view within the navigation stack when the selected tab is tapped again. In the pre-SwiftUI times, this was as simple as the following:
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
let navController = viewController as! UINavigationController
navController.popViewController(animated: true)
}
您知道如何在 SwiftUI 中实现相同的功能吗?
Do you know how the same thing can be achieved in SwiftUI?
目前,我使用以下依赖于 UIKit 的解决方法:
Currently, I use the following workaround that relies on UIKit:
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
let navigationController = UINavigationController(rootViewController: UIHostingController(rootView:
MyCustomView() // -> this is a normal SwiftUI file
.environment(\.managedObjectContext, context)
))
navigationController.tabBarItem = UITabBarItem(title: "My View 1", image: nil, selectedImage: nil)
// add more controllers that are part of tab bar controller
let tabBarController = UITabBarController()
tabBarController.viewControllers = [navigationController /*, additional controllers */]
window.rootViewController = tabBarController // UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
推荐答案
这里是可能的方法.对于 TabView
,它提供与点击另一个选项卡并返回相同的行为,因此提供持久的外观和感觉.
Here is possible approach. For TabView
it gives the same behaviour as tapping to the another tab and back, so gives persistent look & feel.
经过测试适用于 Xcode 11.2/iOS 13.2
Tested & works with Xcode 11.2 / iOS 13.2
完整模块代码:
import SwiftUI
struct TestPopToRootInTab: View {
@State private var selection = 0
@State private var resetNavigationID = UUID()
var body: some View {
let selectable = Binding( // << proxy binding to catch tab tap
get: { self.selection },
set: { self.selection = $0
// set new ID to recreate NavigationView, so put it
// in root state, same as is on change tab and back
self.resetNavigationID = UUID()
})
return TabView(selection: selectable) {
self.tab1()
.tabItem {
Image(systemName: "1.circle")
}.tag(0)
self.tab2()
.tabItem {
Image(systemName: "2.circle")
}.tag(1)
}
}
private func tab1() -> some View {
NavigationView {
NavigationLink(destination: TabChildView()) {
Text("Tab1 - Initial")
}
}.id(self.resetNavigationID) // << making id modifiable
}
private func tab2() -> some View {
Text("Tab2")
}
}
struct TabChildView: View {
var number = 1
var body: some View {
NavigationLink("Child \(number)",
destination: TabChildView(number: number + 1))
}
}
struct TestPopToRootInTab_Previews: PreviewProvider {
static var previews: some View {
TestPopToRootInTab()
}
}
这篇关于SwiftUI:再次点击所选选项卡时弹出到根视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!