Hi all, could you please explain extreme detail what this code is doing exactly, because it's working on my APP but not very certain of this Tupple
ForEach(Array(filteredNonTECOProjects.enumerated()), id: \.offset) { (row, project) in
TimeKeyInRow(id: project.id, project: project, isSet: $isSet[row])
when.I look at the documentation of swift is seems like I'm using the TUPPLE within another tupple... I I'm lost hahahaha
Let's decompose this code:
ForEach(Array(filteredNonTECOProjects.enumerated()), id: \.offset) {
(row, project) in TimeKeyInRow(id: project.id, project: project, isSet: $isSet[row])
}
- ForEach(x) loops through all the elements of x
In this case, they are the elements of the Array.
The array is built from filteredNonTECOProjects
filteredNonTECOProjects is enumerated(), which means the index of the array is retrieved and associated to the element of the array itself, to get a tuple: (row, project).
id: \ .offset defines the id needed by ForEach which requires identifier (identifiable conformance). In the case, the offset of element in the array is used as identifier.
So at the end, ForEach loops through the array and pass (row, project) to the closure that is executed at each step of ForEach.
- The closure
{ (row, project) in TimeKeyInRow(id: project.id, project: project, isSet: $isSet[row]) }
for each (row, project), we create a TimeKeyInRow view that will be displayed (either in VStack or List or whatever else).
It passes the parameters required by TimeKeyInRow: id, project, isSet for the row.
isSet[row] requires $, because TimeKeyInRow expects a Binding.
- Note on Binding.
When you pass a parameter (isSet[row] to TimeKeyInRow) and this parameter will be modified in TimeKeyInRow, you need to retrieve the new value of isSet[row] in the caller, in the State var
@State var isSet: [Bool]
So, by using $, you pass a pointer to the var, and so the original var is modified when you change in TimeKeyInRow.
It is the equivalent of inout parameter for plain Swift: Function parameters are constants by default. Trying to change the value of a function parameter from within the body of that function results in a compile-time error. This means that you can’t change the value of a parameter by mistake. If you want a function to modify a parameter’s value, and you want those changes to persist after the function call has ended, define that parameter as an in-out parameter instead. You write an in-out parameter by placing the inout keyword right before a parameter’s type. An in-out parameter has a value that’s passed in to the function, is modified by the function, and is passed back out of the function to replace the original value.
func swapTwoInts(_ a: inout Int, _ b: inout Int)
// You call with an & sign (instead of $ sign)
swapTwoInts(&someInt, &anotherInt)
Home that helps.