I’ve got ForEach loop inside a picker widget, that suppose to iterate a list of items (handler.items
).
However, in reality, I get that the tags where not properly set and $arg = $0
instead of $arg = $0.components(separatedBy: " ")[0]
after debugging the problem, it seems that although i see the right number of items according to the list size … the ForEach iterate all the items twice, thus causing duplicated tags where they suppose to be unique.
here’s the code, any idea how come the iteration repeat itself ?
VStack {
Picker("items", selection: $arg) {
ForEach(handler.items , id: .self, content: {
Text($0).tag($0.components(separatedBy: " ")[0])
})
}
}
and here’s how handler.items are defined. it’s actually a separated object that is visible from the view, and can be changed from swift native methods.
class myHandler: ObservableObject {
@Published var items = [String]()
}
when setting a breakpoint in the ForEach
statement, i could print this object
(lldb) p handler.items
([String]) $R1 = 2 values {
[0] = "aaa bbb cc 1.1.1.1"
[1] = "ddd eee ff 2.2.2.2"
}
When i put breakpoint inside the ForEach body, I could see that the breakpoint caught there 4 times, and printing the iterator value i Got this printouts:
aaa bbb cc 1.1.1.1
ddd eee ff 2.2.2.2
aaa bbb cc 1.1.1.1
ddd eee ff 2.2.2.2
EDIT : here’s a minimal reproducible example. notice the circled text that clearly shows that the arg didn’t get the tag expression but the whole item :
2
Answers
You need to have
.pickerStyle(.wheel)
to make it work on ios devices. Here is the code I used for testing:(on macos 12.3-beta, using xcode 13.3-beta, targets ios 15 and macCatalyst 12)
EDIT-1:
Note, on macos (Monterey) only app,
pickerStyle
withradioGroup
,segmented
andinline
, will work (i.e, no repeat of tags),however,
menu
, andautomatic
do not.On ios/mac Catalyst,
wheel
,inline
,segmented
andautomatic
work, butmenu
does not.Well I suggest moving the strings to a custom
enumeration
instead of yourObservableObject
. Setting the tag doesn’t really need to be done then. And no duplicate entriesHere’s an example from Apple