Color of BackGround and Condition

Hi, I simply want to compare 2 values ​​to determine the color of the background. I am unable to handle the if condition properly. If "tpsRealise" > "tpsEstime" background is red else is green. Thanks


struct ContentView: View {
    @State var comparaisonTemps = true
    @State var tpsRealise = 0
    @State var tpsEstime = 0
    
    var backgroundColor : Color {
        return comparaisonTemps ? Color.green : Color.red
        
    }

    var body: some View {
        
        
        ZStack {
            backgroundColor
            
            VStack {
                Text("Tps Réalisé : \(tpsRealise)")
                Image(systemName: "plus.square")
                    .font(.title)
                    .onTapGesture {
                        tpsRealise += 1
                        
                    }
                Spacer()
                
                Text("Temps estimé : \(tpsEstime)")
                Image(systemName: "plus.square")
                    .font(.title)
                    .onTapGesture {
                        tpsEstime += 1
                        
                    }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Answered by darkpaw in 738649022

It's because you've not told the view to update when something has changed. This works by setting the bgColour to green initially, then it's recalculated when the icons are tapped. Because bgColour is a @State var and it's changed, the background is redrawn.

struct ContentView: View {
	@State var bgColour = Color.green
	@State var tpsRealise = 0
	@State var tpsEstime = 0

	var body: some View {
		ZStack {
			bgColour

			VStack {
				Text("Tps Réalisé : \(tpsRealise)")
				Image(systemName: "plus.square")
					.font(.title)
					.onTapGesture {
						tpsRealise += 1
						bgColour = displayBackgroundColour()
					}
				Spacer()

				Text("Temps estimé : \(tpsEstime)")
				Image(systemName: "plus.square")
					.font(.title)
					.onTapGesture {
						tpsEstime += 1
						bgColour = displayBackgroundColour()
					}
			}
		}
	}

	func displayBackgroundColour() -> Color {
		return tpsRealise > tpsEstime ? Color.red : Color.green
	}
}
Accepted Answer

It's because you've not told the view to update when something has changed. This works by setting the bgColour to green initially, then it's recalculated when the icons are tapped. Because bgColour is a @State var and it's changed, the background is redrawn.

struct ContentView: View {
	@State var bgColour = Color.green
	@State var tpsRealise = 0
	@State var tpsEstime = 0

	var body: some View {
		ZStack {
			bgColour

			VStack {
				Text("Tps Réalisé : \(tpsRealise)")
				Image(systemName: "plus.square")
					.font(.title)
					.onTapGesture {
						tpsRealise += 1
						bgColour = displayBackgroundColour()
					}
				Spacer()

				Text("Temps estimé : \(tpsEstime)")
				Image(systemName: "plus.square")
					.font(.title)
					.onTapGesture {
						tpsEstime += 1
						bgColour = displayBackgroundColour()
					}
			}
		}
	}

	func displayBackgroundColour() -> Color {
		return tpsRealise > tpsEstime ? Color.red : Color.green
	}
}

You did not compute comparaisonTemps.

Just compute it in a var (not a State var), it will work:

struct ContentView: View {
    var comparaisonTemps : Bool  {  // <<-- Change, no more state var
        tpsRealise >= tpsEstime
    }
    @State var tpsRealise = 0
    @State var tpsEstime = 0
    
    var backgroundColor : Color {
        return comparaisonTemps ? Color.green : Color.red
    }

    var body: some View {
        
        ZStack {
            backgroundColor
            
            VStack {
                Text("Tps Réalisé : \(tpsRealise)")
                Image(systemName: "plus.square")
                    .font(.title)
                    .onTapGesture {
                        tpsRealise += 1
                    }
                Spacer()
                
                Text("Temps estimé : \(tpsEstime)")
                Image(systemName: "plus.square")
                    .font(.title)
                    .onTapGesture {
                        tpsEstime += 1
                    }
            }
        }
    }

You can also recompute directly on tap, keeping the State var:

struct ContentView: View {
    @State var comparaisonTemps = true
    @State var tpsRealise = 0
    @State var tpsEstime = 0
    
    var backgroundColor : Color {
        return comparaisonTemps ? Color.green : Color.red
    }

    var body: some View {
        
        ZStack {
            backgroundColor
            
            VStack {
                Text("Tps Réalisé : \(tpsRealise)")
                Image(systemName: "plus.square")
                    .font(.title)
                    .onTapGesture {
                        tpsRealise += 1
                        comparaisonTemps = tpsRealise >= tpsEstime  // <<-- Compute
                    }
                Spacer()
                
                Text("Temps estimé : \(tpsEstime)")
                Image(systemName: "plus.square")
                    .font(.title)
                    .onTapGesture {
                        tpsEstime += 1
                        comparaisonTemps = tpsRealise >= tpsEstime  // <<-- Compute
                    }
            }
        }
    }
}

Les 2 fonctionnent comme prévu.

Thanks Darkpaw and Claude31, The three solutions work for my example, I'll look at which one is the easiest to adapt to my project where I have to compare a target time with the lap on a stopwatch.

Hello, I'm coming back to you because I have a problem comparing my lap time (retrieved via the Picker) and the lapTimes.last the value of the lap time is let tempsTour = Double(secondesSelection) + (Double(dixiemesSelection) / 10) but I don't see how to retrieve the LapTimes.last in the same format to perform the comparison. a idea? Thanks

code snippet

                                List {
                                    LapTime(n: self.lapCount, m: self.lapMinutes, s: self.lapSeconds, c: self.lapCentiseconds)
                                    ForEach(self.lapTimes.reversed()) { time in time }
                                }.frame(width: UIScreen.main.bounds.width * 0.15)
                            }
                      
                        ZStack {
                            Rectangle()
                                .fill(Color.yellow.opacity(0.0))
                            .frame(height: UIScreen.main.bounds.height * 0.65)
                            Text(self.lapTimes.last?.getLapSecondsString() ?? "")
                                .font(.system(size: min(geo.size.height, geo.size.width) * 0.40))
                                .fontWeight(.bold)
                                .frame(height: UIScreen.main.bounds.height * 0.38)  // <<-- HERE
                        }
                    }
                    Rectangle()
                        .fill(Color.green.opacity(0.1))
                        .onTapGesture {
                            if(!self.running) {
                                self.minutes = 0
                                self.seconds = 0
                                self.centiseconds = 0
                                self.lapTimes = []
                                self.lapMinutes = 0
                                self.lapSeconds = 0
                                self.lapCentiseconds = 0
                                self.lapCount = 1
                            } else {
                                self.lapTimes.append(LapTime(n: self.lapCount, m: self.lapMinutes, s: self.lapSeconds, c: self.lapCentiseconds))
                                self.lapCount += 1
                                self.lapMinutes = 0
                                self.lapSeconds = 0
                                self.lapCentiseconds = 0
                            }
                        }
                    
                }
            }
        }
    }
    
    func timerCalcs() {
        if(self.centiseconds < 99) {
            self.centiseconds += 1
            
        } else {
            self.centiseconds = 0
            if(self.seconds < 59) {
                self.seconds += 1
                
            } else {
                self.seconds = 0
                self.minutes += 1
            }
        }
        
        if(self.lapCentiseconds < 99) {
            self.lapCentiseconds += 1
            
        } else {
            self.lapCentiseconds = 0
            if(self.lapSeconds < 59) {
                self.lapSeconds += 1
                
            } else {
                self.lapSeconds = 0
                self.lapMinutes += 1
            }
        }
    }
}

func getTimeString(m: Int, s: Int, c: Int) -> String {
    var centiString = String(c)
    var secString = String(s)
    var minString = String(m)
    if(c < 10) {
        centiString = "0\(c)"
    }
    if(s < 10) {
        secString = "0\(s)"
    }
    if(m < 10) {
        minString = "0\(m)"
    }
    return "\(minString):\(secString).\(centiString)"
}

struct LapTime: View, Identifiable {
    let id = UUID()
    let num: Int
    let minutes: Int
    let seconds: Int
    let centiSeconds: Int
    let time: String
    
    var body: some View {
        HStack {
            Text("\(num)").font(.system(size: 20, design: .monospaced)) //Lap
            Spacer()
            Text(time).font(.system(size: 20, design: .monospaced))
        }
    }
    
    init(n: Int, m: Int, s: Int, c: Int) {
        num = n
        minutes = m
        seconds = s
        centiSeconds = c
        time = getTimeString(m: minutes, s: seconds, c: centiSeconds)
    }
    
    func getLapSecondsString() -> String {
        var centiString = String(centiSeconds)
        var secString = String(seconds)
        if(centiSeconds < 10) {
            centiString = "0\(centiSeconds)"
        }
        if(seconds < 10) {
            secString = "0\(seconds)"
        }
        return "\(secString).\(centiString)"
    }
}

As you closed the thread, it would be better to open a new one.

And please, show the relevant code with detailed explanations:

  • where is the picker in code?
  • What do you get exactly ? What did you expect ?

I don't see how to retrieve the LapTimes.last in the same format to perform the comparison

  • What format do you mean ?
  • what format do you get ?
  • where is the comparison ?

So detail your question by referring to the specific part of code. That will make it much easier.

Rendez vous dans une nouvelle thread…

Thanks, I Make that

Color of BackGround and Condition
 
 
Q