1

I would expect that sheet that is presented show the actual string that was pressed in the list.

i.e, long press G and the presenting sheet should show G

Unfortunately it doesn't, I'm assuming this is a SwiftUI bug.

Does anyone have a clean solution for this?

Thanks

struct ContentView: View {

    let items = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]

    @State var showing = false

    var body: some View {
        NavigationView {
            List {
                ForEach(items, id: \.self) { item in
                    Text(item).font(.largeTitle)
                        .contextMenu {
                            self.contextEdit(item)
                    }
                }
            }
        }
    }

    private func contextEdit(_ item: String) -> some View {
        Button(action: {
            self.showing.toggle()
            print(item)
        }) {
            Text("Edit")
            Image(systemName: "circle")
        }.sheet(isPresented: $showing) {
            Text(item)
        }
    }
}
1
  • sounds for me like an Apple Bug... :( Commented Nov 12, 2019 at 12:33

2 Answers 2

4

sheets should only be used on the top level. This causes unexpected behaviour as the warnings in your output should also say.

Here is a working example:

struct ContentView: View {

    let items = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]

    @State var showing = false
    @State var currentItem: String = ""

    var body: some View {
        NavigationView {
            List {
                ForEach(items, id: \.self) { item in
                    Text(item).font(.largeTitle)
                        .contextMenu {
                        Button(action: {
                            self.currentItem = item
                            self.showing.toggle()
                        }) {
                            Text("Edit")
                            Image(systemName: "circle")
                        }
                    }
                }
            }
        }.sheet(isPresented: self.$showing) {
            Text(self.currentItem)
        }
    }
}

I hope this helps

Greetings krjw

Sign up to request clarification or add additional context in comments.

1 Comment

I have multiple sheets for my view - that's why I was attaching the sheet to the buttons.If I attach the sheet to the buttons, in your example it still works. I guess for the moment I'll have to live with my the massive nested ForEach. Thanks
1

After a lot of trail and error I found that his works well for my needs

struct PresentingContextItem<Destination: View>: View {

    @State private var showingDestination: Bool = false
    var destination: () -> Destination
    let title: String
    let image: String

    init(title: String, image: String, @ViewBuilder _ destination: @escaping () -> Destination) {
        self.destination = destination
        self.title = title
        self.image = image
    }

    var body: some View {
        Button(action: {
            self.showingDestination.toggle()
        }) {
            Text(self.title)
            Image(systemName: self.image)
        }.sheet(isPresented: self.$showingDestination) {
            self.destination()
        }
    }
}

Usage

struct ContentView: View {

    let items = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]

    var body: some View {
        NavigationView {
            List(items, id: \.self) { item in
                Text(item).font(.largeTitle)
                    .contextMenu {
                        // option 1
                        PresentingContextItem(title: "Create", image: "circle") {
                            Text("Edit...\(item)").foregroundColor(.red)
                        }
                        // option 2
                        self.starItem(item)
                }
            }
        }
    }

    private func starItem(_ item: String) -> some View {
        PresentingContextItem(title: "Star", image: "star") {
            Text("Star...\(item)").foregroundColor(.green)
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.