简体   繁体   中英

SwiftUI: How can I get the selected row in a List before pushing another view

Another SwiftUI struggle!

I have a view that contains a list. When user taps on a row, I want to first save the selected item in my VM then push another view. The only way I can think of to solve that issue is to first save the selected row and have another button to push the next view. It seems impossible to do this with only one tap.

Anyone have a clue?

Here's the code by the way:

struct AnotherView : View {
    @State var viewModel = AnotherViewModel()

    var body: some View {
        NavigationView {
            VStack {
                    List(viewModel.items.identified(by: \.id)) { item in
                        NavigationLink(destination: DestinationView()) {
                            Text(item)
                        }
                        // Before the new view is open, I want to save the selected item in my VM, which will write to a global store.
                        self.viewModel.selectedItem = item
                    }
                }
        }
    }
}

Thank you!

Alright, I found a not too shady solution. I used this article https://ryanashcraft.me/swiftui-programmatic-navigation shout out to him! Instead of using a NavigationLink button, I use a regular button, save the selected item when the user tap then use NavigationDestinationLink to push the new view as is self.link.presented?.value = true .

Works like a charm as of beta 3! I'll update my post if something change in the next betas.

Here's how it could look like:

struct AnotherView : View {
    private let link: NavigationDestinationLink<AnotherView2>
    @State var viewModel = AnotherViewModel()

    init() {
        self.link = NavigationDestinationLink(
            AnotherView2(),
            isDetail: true
        )
    }

    var body: some View {
        NavigationView {
            VStack {
                List(viewModel.items.identified(by: \.id)) { item in
                    Button(action: {
                        // Save the object into a global store to be used later on
                        self.viewModel.selectedItem = item
                        // Present new view
                        self.link.presented?.value = true
                    }) {
                        Text(value: item)
                    }
                }
            }
        }
    }
}

You can add simple TapGesture

                NavigationLink(destination: ContentView() ) {
                    Text("Row")
                        .gesture(TapGesture()
                            .onEnded({ _ in
                                //your action here
                    }))
                }

这也可以通过在任何 View 继承者中使用 Publisher 和OnReceive挂钩来完成。

Swift 5.1

In case you would like to apply it to a static List. You may try this.

NavigationView{
        List{
            NavigationLink("YourView1Description", destination: YourView1())

            NavigationLink("YourView2Description", destination: YourView2())

           NavigationLink("YourView3Description", destination: YourView3())

           NavigationLink("YourView4Description", destination: YourView4())

        }
        .navigationBarTitle(Text("Details"))
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM