1

I was looking here at this to try to solve my problem, and many said that this was fixed in the latest XCode version, but it is not working for me and I am on the latest public XCode version that supports iOS 14.5. I have a few arrays that each contain info such as a name, number, and description. I want each of these to appear as buttons and then when tapped on to show a sheet with a unique view to that button.

Here is a shortened example of one of my arrays:

var discussionTask = [
        Task(taskname: "Pick Up Around Your City", taskdescription: "Pick up and recycle litter", sfsymbolname: "trash.slash.fill", tokencount: 15),
        Task(taskname: "Go Paperless", taskdescription: "When possible, opt to use a digital device over paper.", sfsymbolname: "trash.slash.fill", tokencount: 15),
        Task(taskname: "Plant a Tree", taskdescription: "Plant a tree.", sfsymbolname: "leaf.fill", tokencount: 15)
    ]

With this example array, I would want to make a button for each Task, so in this case there would be 3 buttons. The first button should show the name "Pick Up Around Your City" and have the number "15". When clicked on, I want it to show all of the data including the taskdescription and sfsymbol.

Everything that I currently try only shows the first item in the sorted array, but I want it to show a unique sheet for each button. And instead of just three items in the list there are many more that I will continue to add to. Here is what I am currently trying:

func DiscussionTrackViewButton(tasknumber: Int) -> some View {
        
        Button(action: {
            print(tasknumber)
            showTaskSheet = true
        }, label: {
            TrackBlockView(sfimagename: discussionTask.sorted { $0.taskname < $1.taskname }[tasknumber].sfsymbolname, taskname: discussionTask.sorted { $0.taskname < $1.taskname }[tasknumber].taskname, tokencount: String(discussionTask.sorted { $0.taskname < $1.taskname }[tasknumber].tokencount)) 
        })
        .sheet(isPresented: $showTaskSheet) {
            DetailedTrackView(sfsymbolname: discussionTask.sorted { $0.taskname < $1.taskname }[tasknumber].sfsymbolname, taskname: discussionTask.sorted { $0.taskname < $1.taskname }[tasknumber].taskname, taskdetails: discussionTask.sorted { $0.taskname < $1.taskname }[tasknumber].taskdescription, tokencount: discussionTask.sorted { $0.taskname < $1.taskname }[tasknumber].tokencount, trackData: $trackdata, DailyGoalProgress: $DailyGoalProgress, TabSelection: $TabSelection, SavedDailyGoal: $SavedDailyGoal, DateSinceStreak: $DateSinceStreak, DaysOfStreak: $DaysOfStreak)
        }
            
        
    }

Here is where I call the function:

ForEach(0..<discussionTask.count) { index in
                                    DiscussionTrackViewButton(tasknumber: index)
                                 }

In this case it prints the unique tasknumber and the buttons are all unique. However, any time I click on any button, it only shows the first sorted item's info. For context, DetailedTrackView is just the detailed info screen that I want to appear. Why is this problem occurring and how can I fix it?

Thanks in advance

1 Answers1

3

You can do something like this:

struct DiscussionTaskView: View {
    var discussionTasks = [
        Task(taskname: "Pick Up Around Your City", taskdescription: "Pick up and recycle litter", sfsymbolname: "trash.slash.fill", tokencount: 15),
        Task(taskname: "Go Paperless", taskdescription: "When possible, opt to use a digital device over paper.", sfsymbolname: "trash.slash.fill", tokencount: 15),
        Task(taskname: "Plant a Tree", taskdescription: "Plant a tree.", sfsymbolname: "leaf.fill", tokencount: 15)
    ]
    
    @State var selectedTask: Task?
    
    var body: some View {
        VStack(spacing: 20) {
            ForEach(discussionTasks) { task in
                Button {
                    selectedTask = task
                } label: {
                    Image(systemName: task.sfsymbolname)
                }
                .sheet(item: $selectedTask) { task in
                    VStack(alignment: .center, spacing: 20) {
                        Text(task.taskname)
                            .font(.headline)
                        Text(task.taskdescription)
                        Text("\(task.tokencount)")
                        Image(systemName: task.sfsymbolname)
                    }
                }
            }
        }
    }
}

This uses the .sheet(item:content:) version of the sheet modifier to display each item as its corresponding button is tapped.

It also assumes your Task struct conforms to Identifiable, which would not be hard to do if it is not already.

Patrick Wynne
  • 1,864
  • 15
  • 20