我有多个使用相同枚举的导航路径,以便我能够清除该路径并将用户带回该项目的主选项卡视图。当我使用
navigationLink(value: )
时,这非常有用,但有时我需要等待数据加载才能导航。因此,对于那些需要先加载数据然后导航的情况,我使用视图模型中的 onreceive 。我的问题是,因为我不知道用户如何到达此视图,所以我如何知道将此视图附加到哪个路径?他们可以从我的任何选项卡视图到达这里。在示例中,我将其附加到 feedpath,但如果他们从 profilepath 或任何其他路径到达此视图,则不起作用。
class NavigationManager: ObservableObject {
@Published var feedPath = [FeedNavigation]()
@Published var searchPath = [FeedNavigation]()
@Published var libraryPath = [FeedNavigation]()
@Published var profilePath = [FeedNavigation]()
}
enum FeedNavigation: Hashable, Codable {
case profile(User)
case bookPage(Book)
case notification
case chat
case feedCell(Post)
case chatView(User)
case followView(User, Int)
}
struct ProfileView: View {
@EnvironmentObject var navigationManager: NavigationManager
var body: some View {
VStack {
NavigationLink(value: FeedNavigation.profile(user)) {
KFImage(URL(string: user.profileImageUrl ?? defaultPhoto))
.resizable()
.scaledToFill()
.frame(width: 40, height: 40)
.cornerRadius(6)
}
Button(action: {
viewModel.fetchBookForList(book: book)
}) {
Text("Load data in view model")
}
.onReceive(viewModel.$googleBookFetched) { success in
if success {
if let book = viewModel.googleBook {
navigationManager.feedPath.append(FeedNavigation.bookPage(book))
}
}
}
.navigationDestination(for: FeedNavigation.self) { state in
switch state {
case .profile(let user):
ProfileView(user: user)
case .bookPage(let book):
BookPageView(viewModel: BookPageViewModel(book: book))
case .notification:
NotificationsView()
case .chat:
ConversationsView()
case .feedCell(let post):
ScrollView {
FeedCell(viewModel: FeedCellViewModel(post: post))
}
case .chatView(let user):
ChatView(viewModel: ChatViewModel(user: user))
case .followView(let user, let followTab):
FollowListView(viewModel: FollowListViewModel(user: user), followTab: followTab)
}
}
}
}
}
TabView(selection: $currentTab) {
NavigationStack(path: $navigationManager.feedPath) {
FeedView()
}
.tag(Tabs.feed)
NavigationStack(path: $navigationManager.searchPath) {
SearchView()
}
.tag(Tabs.search)
NavigationStack(path: $navigationManager.libraryPath) {
LibraryView()
}
.tag(Tabs.inbox)
NavigationStack(path: $navigationManager.profilePath) {
ProfileView(user: user)
}
.tag(Tabs.profile)
}
这似乎是一种解决方法,但至少有效。如果有人有更好的答案,仍然愿意接受。
我刚刚在导航管理器中添加了另一个路径来侦听哪个路径处于活动状态,然后在我看来,我根据哪个路径处于活动状态选择要附加到的路径。
// in navigation manager
@Published var activePath = [FeedNavigation]() {
didSet {
// Handle any additional logic when activePath changes
print("Active Path updated: \(activePath)")
}
}
@Published var feedPath = [FeedNavigation]() {
didSet {
activePath = feedPath
}
}
@Published var searchPath = [FeedNavigation]() {
didSet {
activePath = searchPath
}
}
@Published var libraryPath = [FeedNavigation]() {
didSet {
activePath = libraryPath
}
}
@Published var profilePath = [FeedNavigation]() {
didSet {
activePath = profilePath
}
}
// in view
if navigationManager.activePath == navigationManager.feedPath {
navigationManager.feedPath.append(FeedNavigation.profile(user))
} else if navigationManager.activePath == navigationManager.libraryPath {
navigationManager.libraryPath.append(FeedNavigation.profile(user))
} else if navigationManager.activePath == navigationManager.profilePath {
navigationManager.profilePath.append(FeedNavigation.profile(user))
} else if navigationManager.activePath == navigationManager.searchPath {
navigationManager.searchPath.append(FeedNavigation.profile(user))
}
}