如何弄清楚您来自哪个导航路径以附加到它?

How to figure out what navigationpath you came from to append to it?

提问人:amelia 提问时间:11/13/2023 最后编辑:amelia 更新时间:11/13/2023 访问量:55

问:

我有多个使用相同枚举的导航路径,以便能够清除该路径并将用户带回该项目的主选项卡视图。这在我使用时效果很好,但有时我需要等待数据加载才能导航。因此,对于需要先加载数据然后导航的情况,我使用视图模型的 onreceive 。我的问题是,由于我不知道用户是如何获得此视图的,我怎么知道将此视图附加到哪个路径?他们本可以从我的任何选项卡视图到达这里。在示例中,我将其附加到 feedpath,但如果它们从 profilepath 或任何其他路径访问此视图,则不起作用。navigationLink(value: )

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)
    
}
堆栈 swiftui 导航 路径

评论

0赞 lorem ipsum 11/13/2023
将其注入到每个堆栈环境中
0赞 amelia 11/13/2023
@loremipsum不确定我是否在关注。我有一个可从每个堆栈访问的导航管理器的环境对象,但问题是我不知道他们是否从配置文件路径或搜索路径或源路径到达 profileview,因此据我所知,我无法在那里硬编码路径

答:

0赞 amelia 11/13/2023 #1

这似乎是一种解决方法,但至少是有效的。如果有人有更好的答案,仍然对更好的答案持开放态度。

我刚刚在我的 navigationManager 中添加了另一个路径来侦听哪个路径处于活动状态,然后在我的视图中,我根据哪个路径处于活动状态来选择要追加到的路径。

// 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))
}

}