\n
For your particular situation I suggest handling it like so:
\nfunc addDay(_ index: Double) -> Text {\n let someDate = startDate.addingTimeInterval(86400 * index)\n return Text("\\(someDate, formatter: Self.weekFormat)")\n}\n
\n...
\nForEach(0..<weekdays.count) { weekday in\n VStack{\n RoundedRectangle(cornerRadius: 9, style: .continuous)\n .stroke(Color.blue)\n .frame(width: 68.5, height: 68.5)\n \n self.addDay(Double(weekday))\n Text(String(Double(weekday)))\n Text(self.weekdays[weekday])\n \n \n }\n}\n
\nThis once again boils down to the way SwiftUI works, you can think of SwiftUI as a "function" of its states. In my example you can pass in any weekday, with it's position in the array, and you'll be able to generate a UI.
\n-Side note-
\nI did not know that you could access the static version of self
by using Self
(capital S). How convenient Swift is!
Reputation: 23
I cannot seem to find a solution to this after much searching. I am trying to update my state variable d
in the function call addDay
. This function is called in the ForEach loop. The problem is, d
is updated once to a value of 2.0, then it stays at 2.0 forever. I'm not sure what is wrong, any insight?
let weekdays: [String] = ["Mon", "Tues", "Wed", "Thurs", "Fri"]
@State var startDate: Date = Date().next(.monday, direction: .backward)
@State var d:Double = 1.0
/**
- parameter startDate: the beginning date that will be modified
- Returns: A new Text that has a date attached
*/
func addDay(startDate: Date) -> Text {
self.startDate = startDate.addingTimeInterval(86400 * self.d)
self.d += 1.0
return Text("\(startDate, formatter: Self.weekFormat)")
}
static let weekFormat: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "MMMM dd"
return formatter
}()
var body: some View {
ScrollView(.horizontal) {
HStack{
ForEach(weekdays, id: \.self) { weekday in
VStack{
RoundedRectangle(cornerRadius: 9, style: .continuous)
.stroke(Color.blue)
.frame(width: 68.5, height: 68.5)
self.addDay(startDate: self.startDate)
Text(String(self.d))
Text(weekday)
}
}
}
}
}
}
Upvotes: 2
Views: 2454
Reputation: 258413
I'm not sure what you try to achieve, but here is a demo of approach of how to use temporary variables during view generation.
Tested with Xcode 12 / iOS 14 (original logic preserved)
struct ContentView: View {
let weekdays: [String] = ["Mon", "Tues", "Wed", "Thurs", "Fri"]
@State var startDate: Date = Date()//.next(.monday, direction: .backward)
/**
- parameter startDate: the beginning date that will be modified
- Returns: A new Text that has a date attached
*/
func addDay(startDate: inout Date, d: inout Double) -> Text {
startDate = startDate.addingTimeInterval(86400 * d)
d += 1.0
return Text("\(startDate, formatter: Self.weekFormat)")
}
static let weekFormat: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "MMMM dd"
return formatter
}()
var body: some View {
ScrollView(.horizontal) {
genererateContent()
}
}
private func genererateContent() -> some View {
var d: Double = 1.0
var startDate = self.startDate.addingTimeInterval(86400 * d)
return HStack{
ForEach(weekdays, id: \.self) { weekday in
VStack{
RoundedRectangle(cornerRadius: 9, style: .continuous)
.stroke(Color.blue)
.frame(width: 68.5, height: 68.5)
self.addDay(startDate: &startDate, d: &d)
Text(String(d))
Text(weekday)
}
}
}
}
}
Upvotes: 0
Reputation: 813
It appears that you might be modifying the view state during update...
This is a fancy term for a possible never ending loop:
addDay
causes startDate
or d
to change, both of which are @State
variables.Your case is a bit different however, because SwiftUI appears to be actually stopping the state change, which is probably good in your case because if it wasn't stopping the state change, your CPU usage would spike up to 100 percent.
For your particular situation I suggest handling it like so:
func addDay(_ index: Double) -> Text {
let someDate = startDate.addingTimeInterval(86400 * index)
return Text("\(someDate, formatter: Self.weekFormat)")
}
...
ForEach(0..<weekdays.count) { weekday in
VStack{
RoundedRectangle(cornerRadius: 9, style: .continuous)
.stroke(Color.blue)
.frame(width: 68.5, height: 68.5)
self.addDay(Double(weekday))
Text(String(Double(weekday)))
Text(self.weekdays[weekday])
}
}
This once again boils down to the way SwiftUI works, you can think of SwiftUI as a "function" of its states. In my example you can pass in any weekday, with it's position in the array, and you'll be able to generate a UI.
-Side note-
I did not know that you could access the static version of self
by using Self
(capital S). How convenient Swift is!
Upvotes: 1