简体   繁体   中英

How to show an alert when the user taps on the List row in SwiftUI

What is the best way to show an alert which includes data from the row, when the user taps on the row in the List in SwiftUI?

I'm using this code.

import SwiftUI

struct ContentView: View {

    var testData = ["One","Two","Three"]

    var body: some View {

        List{
            ForEach(testData, id: \.self) { item in
                Text(item).onTapGesture {

                    if item == "One" {

                        print("One selected")

                        print("NEED TO SHOW THE ALERT HERE")

                    }

                }
            }

        }

    }

}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

I tried to solve the problem this way:

import SwiftUI

struct ContentView: View {

    @State private var showingAlert = false

    var testData = ["One","Two","Three"]

    var body: some View {

        List{
            ForEach(testData, id: \.self) { item in

                Button(action: {
                    self.showingAlert = true

                }) {
                    Text("\(item)")

                }
                .alert(isPresented: self.$showingAlert) {
                    Alert(title: Text("Text"), message: Text(item), dismissButton: .default(Text("Ok")))

                }

            }

        }

    }

}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

But this solution causes this warning:

Attempt to present <UIAlertController:>  which is already presenting <UIAlertController:>

Looking for a better solution or a solution that will avoid this warning.

This due to the single variable renders for all the cells when updated , so You can try

struct ContentView: View {

    @State private var showingAlert = false

    @State private var item = "" // track last clicked item

    var testData = ["One","Two","Three"]

    var body: some View {

        List{
            ForEach(testData, id: \.self) { item in

                Button(action: {
                    self.item = item
                    self.showingAlert = true

                }) {
                    Text("\(item)")

                }

            }

        }.alert(isPresented: self.$showingAlert) {
                Alert(title: Text("Text"), message:Text(item), dismissButton: .default(Text("Ok")))
        }

    }

}

Your code creates a separate alert for each item. Move the alert call outside the ForEach , then only one alert instance will be created.

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