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

如何在API响应返回后,实现按钮点击跳转新视图?

解决API响应后跳转新视图的SwiftUI实现

先修正你代码里的一个小问题:onSubmit方法里的参数fieldTitle应该改为title,对应你定义的@State变量。下面提供几种常用的跳转实现方案,适配不同iOS版本和场景:

方案一:使用NavigationStack(iOS 16+)

这是iOS16及以上的推荐导航方式,通过NavigationPath管理导航栈:

struct FormView: View {
    @StateObject private var vm = MyViewModel(myService: MyService())
    @State private var title: String = ""
    @State private var navigationPath = NavigationPath()
    
    var body: some View {
        NavigationStack(path: $navigationPath) {
            VStack {
                TextField(
                    "Type something",
                    text: $title
                )
                .textFieldStyle(.roundedBorder)
                
                Button(action: onSubmit) {
                    Text("Submit")
                        .padding()
                        .background(.blue)
                        .foregroundColor(.white)
                        .cornerRadius(8)
                }
            }
            .padding()
            // 定义导航目标视图
            .navigationDestination(for: Post.self) { post in
                DetailView(post: post) // 替换成你的目标视图
            }
            .onChange(of: vm.post) { _, newPost in
                if let post = newPost {
                    navigationPath.append(post)
                    // 跳转后清空vm.post,避免重复触发跳转
                    vm.post = nil
                }
            }
        }
    }
    
    func onSubmit() {
        vm.submit(title: title)
    }
}

// 示例模型和目标视图
struct Post: Identifiable {
    let id = UUID()
    let title: String
}

struct DetailView: View {
    let post: Post
    var body: some View {
        Text("Post Content: \(post.title)")
            .navigationTitle("Detail")
    }
}

方案二:使用NavigationView(iOS 13-15)

如果需要兼容旧版本iOS,用隐藏的NavigationLink配合状态变量控制:

struct FormView: View {
    @StateObject private var vm = MyViewModel(myService: MyService())
    @State private var title: String = ""
    @State private var shouldNavigate = false
    
    var body: some View {
        NavigationView {
            VStack {
                TextField(
                    "Type something",
                    text: $title
                )
                .textFieldStyle(.roundedBorder)
                
                Button(action: onSubmit) {
                    Text("Submit")
                        .padding()
                        .background(.blue)
                        .foregroundColor(.white)
                        .cornerRadius(8)
                }
                // 隐藏的导航链接,通过状态控制激活
                .background(
                    NavigationLink(
                        destination: DetailView(post: vm.post!),
                        isActive: $shouldNavigate,
                        label: { EmptyView() }
                    )
                )
            }
            .padding()
            .onChange(of: vm.post) { _, newPost in
                shouldNavigate = newPost != nil
                // 跳转后重置状态,避免重复触发
                if shouldNavigate {
                    DispatchQueue.main.async {
                        vm.post = nil
                    }
                }
            }
        }
    }
    
    func onSubmit() {
        vm.submit(title: title)
    }
}

方案三:使用Sheet弹出视图

如果需要以弹出层形式展示新视图,用sheet实现:

struct FormView: View {
    @StateObject private var vm = MyViewModel(myService: MyService())
    @State private var title: String = ""
    @State private var showDetailSheet = false
    
    var body: some View {
        VStack {
            TextField(
                "Type something",
                text: $title
            )
            .textFieldStyle(.roundedBorder)
            
            Button(action: onSubmit) {
                Text("Submit")
                    .padding()
                    .background(.blue)
                    .foregroundColor(.white)
                    .cornerRadius(8)
            }
            .sheet(isPresented: $showDetailSheet) {
                if let post = vm.post {
                    DetailView(post: post)
                }
            }
            .onChange(of: vm.post) { _, newPost in
                showDetailSheet = newPost != nil
                // 弹出后重置状态
                if showDetailSheet {
                    DispatchQueue.main.async {
                        vm.post = nil
                    }
                }
            }
        }
        .padding()
    }
    
    func onSubmit() {
        vm.submit(title: title)
    }
}

关键注意事项

  • 确保你的MyViewModel中post属性是@Published的,否则onChange不会触发:
    class MyViewModel: ObservableObject {
        @Published var post: Post?
        private let myService: MyService
        
        init(myService: MyService) {
            self.myService = myService
        }
        
        func submit(title: String) {
            // API调用示例,确保在主线程更新post
            myService.createPost(title: title) { [weak self] post in
                DispatchQueue.main.async {
                    self?.post = post
                }
            }
        }
    }
    
  • 跳转后清空vm.post是为了避免用户返回当前页面后,旧的post值再次触发跳转逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 07:40:09