1
votes

This is for MacOS. I am trying to recreate a pull down menu button in SwiftUI using the new Menu control. The menu has several sections separated by a Divider. Each section should be able to set a tick mark on one item only. I originally had a custom ButtonGroup view to handle the sections but it didn't work, so I simplified it to the code below, but it still doesn't work properly. I would expect to get a menu with A,B then a divider, then C,D,E,F but I get A,B | A,B,E,F instead. Selecting an item in one group also create a tick in the other group and the menus change as well. After selecting an item I sometimes get CD | CDEF. Can anyone see what is going wrong before I submit a bug report?

struct ContentView: View {
    @State private var selected1: Int = -1
    @State private var selected2: Int = 2

    var items1 = ["A", "B"]
    var items2 = ["C", "D","E", "F"]

    var body: some View {
        ZStack{
            Menu("Configure") {
                ForEach(0..<items1.count){ index in
                    Button((index == selected1 ? "✔︎ " : "    ") + items1[index], action: {
                        selected1 = index
                    })
                }
                Divider()
                ForEach(0..<items2.count){ index in
                    Button((index == selected2 ? "✔︎ " : "    ") + items2[index], action: {
                        selected2 = index
                    })
                }
            }.frame(width: 70)
        }.frame(width: 200, height: 200)
    }
}
1

1 Answers

1
votes

It is confused by same id, because in both dynamic groups you use indexes, so 0, 1 in first and 0, 1 in second are overlapped.

The best would be to create explicit menu item model and unique identifier for each, but for your demo case it is possible to use also the following approach

Menu("Configure") {
    ForEach(Array(items1.enumerated()), id: \.1){ index, item in
        Button((index == selected1 ? "✔︎ " : "    ") + item, action: {
            selected1 = index
        })
    }
    Divider()
    ForEach(Array(items2.enumerated()), id: \.1){ index, item in
        Button((index == selected2 ? "✔︎ " : "    ") + item, action: {
            selected2 = index
        })
    }
}.frame(width: 70)