You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI:异步任务(async/await)完成后跳转新视图的实现方法

解决方案

因为你的视图已经嵌入父级NavigationView,可以用两种方式实现异步获取数据后的跳转:


方法1:利用selection绑定的隐藏NavigationLink(兼容iOS 15及以下)

你已经定义了selection变量,只需要在FollowersView的视图层级中添加一个隐藏的NavigationLink,绑定这个selection并指定跳转目标视图即可。

修改后的代码如下:

import SwiftUI

struct FollowersView: View {
    @State var followers: [Follower]
    @State var user: User?
    @State private var selection: String? = nil
    @StateObject private var viewModel = GitHubUsersViewModel()
    
    let columns = [
        GridItem(.flexible(minimum: 150, maximum: 175)),
        GridItem(.flexible(minimum: 150, maximum: 175)),
    ]
    
    var body: some View {
        ScrollView {
            LazyVGrid(columns: columns, spacing: 20) {
                ForEach(followers, id: \.self) { follower in
                    FollowerCardView(follower: follower)
                        .onTapGesture {
                            Task {
                                do {
                                    self.user = try await self.viewModel.manager.getUser(for: follower.login)
                                    self.selection = NavigationTags.userFound
                                } catch {
                                    // 可添加错误处理逻辑,比如提示用户获取失败
                                    print("获取用户信息失败:\(error)")
                                }
                            }
                        }
                }
            }
            .padding(.horizontal)
        }
        .frame(maxHeight: .infinity)
        // 添加隐藏的NavigationLink
        .background(
            NavigationLink(
                destination: UserDetailView(user: user!), // 替换为你的目标视图
                tag: NavigationTags.userFound,
                selection: $selection
            ) {
                EmptyView()
            }
            .hidden()
        )
    }
}

// 假设你的NavigationTags定义如下
enum NavigationTags: String {
    case userFound = "userFound"
}

// 示例目标视图
struct UserDetailView: View {
    let user: User
    var body: some View {
        Text(user.login) // 根据User模型展示对应内容
            .navigationTitle(user.login)
    }
}

注意事项:

  • 必须在Task的do-catch块中处理错误,避免user!强制解包导致崩溃
  • NavigationLink放在.background里并用.hidden()隐藏,不会影响原有布局

方法2:使用navigationDestination(iOS 16+推荐)

iOS 16及以后,Apple推出了更简洁的navigationDestination修饰符,无需隐藏的NavigationLink,直接绑定跳转条件和目标视图即可。

修改后的代码:

import SwiftUI

struct FollowersView: View {
    @State var followers: [Follower]
    @State var user: User?
    @StateObject private var viewModel = GitHubUsersViewModel()
    
    let columns = [
        GridItem(.flexible(minimum: 150, maximum: 175)),
        GridItem(.flexible(minimum: 150, maximum: 175)),
    ]
    
    var body: some View {
        ScrollView {
            LazyVGrid(columns: columns, spacing: 20) {
                ForEach(followers, id: \.self) { follower in
                    FollowerCardView(follower: follower)
                        .onTapGesture {
                            Task {
                                do {
                                    self.user = try await self.viewModel.manager.getUser(for: follower.login)
                                    // 无需设置selection,user非nil时自动触发跳转
                                } catch {
                                    print("获取用户信息失败:\(error)")
                                }
                            }
                        }
                }
            }
            .padding(.horizontal)
        }
        .frame(maxHeight: .infinity)
        // 添加navigationDestination
        .navigationDestination(item: $user) { user in
            UserDetailView(user: user)
        }
    }
}

// 示例目标视图
struct UserDetailView: View {
    let user: User
    var body: some View {
        Text(user.login)
            .navigationTitle(user.login)
    }
}

// 注意:User模型需要遵循Identifiable协议,或在navigationDestination中指定id路径
extension User: Identifiable {
    var id: String { login } // 假设login是用户唯一标识
}

注意事项:

  • 目标对象user需要遵循Identifiable协议,或者在navigationDestination中通过id: \.login指定唯一标识路径
  • 当user从nil变为非nil时自动触发跳转;若需重置user,可在目标视图的onDisappear回调中处理

内容的提问来源于stack exchange,提问作者JFortYork

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 10:56:06