swift API响应后按下按钮导航到新视图

e5nqia27  于 4个月前  发布在  Swift
关注(0)|答案(1)|浏览(51)

我有以下观点:

struct FormView: View {
    @StateObject private var vm = MyViewModel(myService: MyService())
    
    @State private var title: String = ""
    
    var body: some View {
        VStack {
            TextField(
                "Type something",
                text: $title
            )
                
            Button(action: onSubmit) {
                Text("Submit")
            }
        }
        .onChange(of: vm.post != nil) { oldValue, newValue in
            // Navigate here
        }
    }
    
    func onSubmit() {
        vm.submit(title: fieldTitle)
    }
}

字符串
正如你所看到的,我有一个Submit按钮,它在按下时调用API。我想在API响应返回后导航到一个新视图,即当onChange(of: vm.post != nil) {}被调用时。
但是我不确定如何最好地做到这一点,我正在寻找关于如何在按钮按下时做到这一点的例子(没有API调用),但没有API调用。

8zzbczxx

8zzbczxx1#

尝试这种方法,当您按下提交按钮并从API响应中获取新数据后,使用NavigationStacknavigationDestination导航到新视图:
范例程式码:

struct ContentView: View {
    var body: some View {
        NavigationStack {
            FormView()
        }
    }
}

protocol MyServiceProtocol {
    func submit(title: String)
}

struct MyService: MyServiceProtocol {
    var name: String = "namename"
    func submit(title: String){ }
}

struct Post: Identifiable, Hashable {
    let id = UUID()
    var name: String = "PostPost"
}

class MyViewModel: ObservableObject {
    private var cancellables = Set<AnyCancellable>()
    let myService: MyServiceProtocol
    @Published var post: Post?
    
    init(myService: MyServiceProtocol) {
        self.myService = myService
    }

    func submit(title: String) {
        // simulated fetching and changing the model post
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
            self.post = Post(name: "newpostname") // <-- for testing
        }
    }
}

struct FormView: View {
    @StateObject private var vm = MyViewModel(myService: MyService())
    
    @State private var title: String = ""
    @State private var toNextView = false
    
    var body: some View {
        VStack {
            TextField("Type something", text: $title).border(.red)
            
            Button(action: onSubmit) {
                Text("Submit")
            }.buttonStyle(.bordered)
        }
        .onChange(of: vm.post) { oldValue, newValue in
            if vm.post != nil { // <-- adjust if need be
                toNextView = true
            }
        }
        .navigationDestination(isPresented: $toNextView) {
            TheNextView().environmentObject(vm)
        }
    }
    
    func onSubmit() {
        vm.submit(title: title)
    }
}

struct TheNextView: View {
    @EnvironmentObject var vm: MyViewModel
    
    var body: some View {
        Text("TheNextView post: \(vm.post?.name ?? "no name")")
    }
}

字符串
编辑1:
当然,您可以将post传递到下一个视图,例如:

.navigationDestination(isPresented: $toNextView) {
     TheNextView(post: vm.post)
 }
 
 struct TheNextView: View {
     @State var post: Post?
     
     var body: some View {
         Text("TheNextView post: \(post?.name ?? "no name")")
     }
 }

相关问题