在 TabView 中重置 NagivationView 堆栈
Reset NagivationView stack in TabView
我有一个带有两个选项卡(选项卡 A 和 B)的选项卡视图。
单击选项卡 A 打开主视图。在该主视图中,有一个导航 link 到第 1 页。在第 1 页中,还有一个 link 到第 2 页。
当用户在第 1 页或第 2 页时,我点击选项卡 A,它不会恢复到主视图。类似地,如果用户再次单击选项卡 B,然后再次单击选项卡 A,它 returns 到页面 1 或 2(无论用户在哪个页面上),而不是主视图。
如何在这两种情况下重置导航堆栈?
谢谢!
那是因为视图不会被重新渲染。这是实现您的行为的可能方法:
您可以使用 TabView 的 ProxyBinding 来检测更改,然后通过更改内部 State 变量来重置 NavigationLink。
struct ContentView: View {
@State var activeView: Int = 0
@State var showNavigation: Bool = false
var body: some View {
TabView(selection: Binding<Int>(
get: {
activeView
}, set: {
activeView = [=10=]
showNavigation = false //<< when pressing Tab Bar Reset Navigation View
}))
{
NavigationView {
NavigationLink("Click", destination: Text("Page A"), isActive: $showNavigation)
}
.tabItem {
Image(systemName: "1.circle")
Text("First")
}
.tag(0)
Text("Second View")
.padding()
.tabItem {
Image(systemName: "2.circle")
Text("Second")
}
.tag(1)
}
}
}
您可以使用 MainView
创建 RootView
import SwiftUI
struct RootView: View {
@ObservedObject var viewModel = RootViewModel()
init(){
viewModel.prepare()
}
var body: some View {
MainView(tab: viewModel.mainTab)
.id(UUID().uuidString)
}
}
创建 RootViewModel 并监听屏幕更新
import SwiftUI
class RootViewModel: ObservableObject{
@Published var mainTab: SelectedTab = .firstTab
let mainScreenNotification = NSNotification.Name("mainScreenNotification")
private var observerMain: Any?
func prepare(){
observerMain = NotificationCenter.default.addObserver(forName: mainScreenNotification, object: nil, queue: nil, using: { [unowned self] notification in
self.mainTab = (notification.userInfo?["selectedTab"])! as! SelectedTab
})
}
}
enum SelectedTab {
case firstTab, secondTab
}
运行 从子选项卡扩展新选项卡屏幕:
NotificationCenter.default.post(name:
NSNotification.Name("mainScreenNotification"),
object: nil,
userInfo: ["selectedTab": SelectedTab.firstTab]
)
我有一个带有两个选项卡(选项卡 A 和 B)的选项卡视图。
单击选项卡 A 打开主视图。在该主视图中,有一个导航 link 到第 1 页。在第 1 页中,还有一个 link 到第 2 页。 当用户在第 1 页或第 2 页时,我点击选项卡 A,它不会恢复到主视图。类似地,如果用户再次单击选项卡 B,然后再次单击选项卡 A,它 returns 到页面 1 或 2(无论用户在哪个页面上),而不是主视图。
如何在这两种情况下重置导航堆栈?
谢谢!
那是因为视图不会被重新渲染。这是实现您的行为的可能方法:
您可以使用 TabView 的 ProxyBinding 来检测更改,然后通过更改内部 State 变量来重置 NavigationLink。
struct ContentView: View {
@State var activeView: Int = 0
@State var showNavigation: Bool = false
var body: some View {
TabView(selection: Binding<Int>(
get: {
activeView
}, set: {
activeView = [=10=]
showNavigation = false //<< when pressing Tab Bar Reset Navigation View
}))
{
NavigationView {
NavigationLink("Click", destination: Text("Page A"), isActive: $showNavigation)
}
.tabItem {
Image(systemName: "1.circle")
Text("First")
}
.tag(0)
Text("Second View")
.padding()
.tabItem {
Image(systemName: "2.circle")
Text("Second")
}
.tag(1)
}
}
}
您可以使用 MainView
创建 RootView
import SwiftUI
struct RootView: View {
@ObservedObject var viewModel = RootViewModel()
init(){
viewModel.prepare()
}
var body: some View {
MainView(tab: viewModel.mainTab)
.id(UUID().uuidString)
}
}
创建 RootViewModel 并监听屏幕更新
import SwiftUI
class RootViewModel: ObservableObject{
@Published var mainTab: SelectedTab = .firstTab
let mainScreenNotification = NSNotification.Name("mainScreenNotification")
private var observerMain: Any?
func prepare(){
observerMain = NotificationCenter.default.addObserver(forName: mainScreenNotification, object: nil, queue: nil, using: { [unowned self] notification in
self.mainTab = (notification.userInfo?["selectedTab"])! as! SelectedTab
})
}
}
enum SelectedTab {
case firstTab, secondTab
}
运行 从子选项卡扩展新选项卡屏幕:
NotificationCenter.default.post(name:
NSNotification.Name("mainScreenNotification"),
object: nil,
userInfo: ["selectedTab": SelectedTab.firstTab]
)