Display of the last LAP

Hello, I use a timer shared on GitHub. I want to display the last LAP recorded under the stopwatch (see screenshot). I manage to recover the LAP but not the LapTime. Thank you in advance for your assistance.




struct ContentView: View {

    let timer = Timer.publish(every: 0.01, on: .main, in: .common).autoconnect()

    

    @State var minutes  = 0

    @State var seconds = 0

    @State var centiseconds = 0

    @State var running = false

    @State var lapTimes : [LapTime] = []

    @State var lapCount = 1

    @State var lapMinutes = 0

    @State var lapSeconds = 0

    @State var lapCentiseconds = 0

    

    var body: some View {

        VStack{

            Text(getTimeString(cS: self.lapCentiseconds, sS: self.lapSeconds, mS: self.lapMinutes))

                .font(.system(size: 60, design: .monospaced))

                .frame(width: 300.0, height: 100.0)

                .onReceive(timer){_ in

                    if(self.running){

                        self.timerCalcs()

                    }

            }

            Text(getTimeString(cS: self.centiseconds, sS: self.seconds, mS: self.minutes))

                .font(.system(size: 60, design: .monospaced))

                .frame(width: 300.0, height: 100.0)

                .onReceive(timer){_ in

                    if(self.running){

                        self.timerCalcs()

                    }

            }

            Text("Lap \(lapCount - 1)")

//            Text(time)

            

            

            HStack{

                Button(action: {

                    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, t: self.getTimeString(cS: self.lapCentiseconds, sS: self.lapSeconds, mS: self.lapMinutes)))

                        self.lapCount += 1

                        self.lapMinutes = 0

                        self.lapSeconds = 0

                        self.lapCentiseconds = 0

                    }

                }) {

                    ZStack{

                        Circle().fill(Color.gray).frame(width: 100, height: 100)

                        self.running ? Text("Lap").foregroundColor(Color.white).font(.system(size: 20, design: .monospaced)) : Text("Reset").foregroundColor(Color.white).font(.system(size: 20, design: .monospaced))

                    }

                }

                

                Spacer()

                Button(action: {

                    self.running = !self.running

                }) {

                    ZStack{

                        Circle().fill(self.running ? Color.red : Color.green).frame(width: 100, height: 100).font(.system(size: 20, design: .monospaced))

                        self.running ? Text("Stop").foregroundColor(Color.white).font(.system(size: 20, design: .monospaced)) : Text("Start").foregroundColor(Color.white).font(.system(size: 20, design: .monospaced))

                    }

                }

            }.padding()

            List{

                LapTime(n: self.lapCount, t: self.getTimeString(cS: self.lapCentiseconds, sS: self.lapSeconds, mS: self.lapMinutes))

                ForEach(self.lapTimes.reversed()) { time in

                    time

                }

            }

        }

        

    }

    

    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(cS: Int, sS : Int, mS: Int) -> String{

        var centiString = String(cS)

        var secString = String(sS)

        var minString = String(mS)

        if(cS<10){

            centiString = "0\(cS)"

        }

        if(sS<10){

            secString = "0\(sS)"

        }

        if(mS<10){

            minString = "0\(mS)"

        }

        return "\(minString):\(secString).\(centiString)"

    }

}



struct LapTime : View, Identifiable{

    let id = UUID()

    let num : Int

    let time : String

    

    var body : some View{

        HStack{

            Text("Lap \(num)").font(.system(size: 20, design: .monospaced))

            Spacer()

            Text(time).font(.system(size: 20, design: .monospaced))

        }

    }

    

    init(n : Int, t : String){

        num = n

        time = t

    }

}

Accepted Reply

Your lap times are stored in your LapTime struct, and you can easily add it to the screen just below Text("Lap \(lapCount - 1)") using this:

Text("Lap \(lapCount - 1)")
let lastLapTime: String = self.lapTimes.last?.time ?? ""  // Get the last lap time in the array, or "" if it's not available, i.e. you haven't done any laps yet.
Text(lastLapTime)

Replies

Your lap times are stored in your LapTime struct, and you can easily add it to the screen just below Text("Lap \(lapCount - 1)") using this:

Text("Lap \(lapCount - 1)")
let lastLapTime: String = self.lapTimes.last?.time ?? ""  // Get the last lap time in the array, or "" if it's not available, i.e. you haven't done any laps yet.
Text(lastLapTime)

Very nice. A big thanks

A other question, if I want only this format : ss.00 what is the code? Thanks

No problem.

Don't forget to tip your waiter (mark my answer as accepted).

Your struct has the time as a String so you can either grab the last x characters from that String, or you can extend the LapTime struct to store the relevant seconds, and retrieve the lap seconds time whenever you need it (my preference). Here's the code, re-written to do that:

import SwiftUI

struct ContentView: View {
	let timer = Timer.publish(every: 0.01, on: .main, in: .common).autoconnect()

	@State var minutes  = 0
	@State var seconds = 0
	@State var centiseconds = 0
	@State var running = false
	@State var lapTimes: [LapTime] = []
	@State var lapCount = 1
	@State var lapMinutes = 0
	@State var lapSeconds = 0
	@State var lapCentiseconds = 0

	var body: some View {
		VStack{
			Text(getTimeString(m: self.lapMinutes, s: self.lapSeconds, c: self.lapCentiseconds))
				.font(.system(size: 60, design: .monospaced))
				.frame(width: 300.0, height: 100.0)
				.onReceive(timer) {_ in
					if(self.running) {
						self.timerCalcs()
					}
				}
			Text(getTimeString(m: self.lapMinutes, s: self.lapSeconds, c: self.lapCentiseconds))
				.font(.system(size: 60, design: .monospaced))
				.frame(width: 300.0, height: 100.0)
				.onReceive(timer) {_ in
					if(self.running) {
						self.timerCalcs()
					}
				}
			Text("Lap \(lapCount - 1)")
			Text(self.lapTimes.last?.time ?? "")
			Text(self.lapTimes.last?.getLapSecondsString() ?? "")

			HStack{
				Button(action: {
					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
					}
				}) {
					ZStack{
						Circle().fill(Color.gray).frame(width: 100, height: 100)
						self.running ? Text("Lap").foregroundColor(Color.white).font(.system(size: 20, design: .monospaced)) : Text("Reset").foregroundColor(Color.white).font(.system(size: 20, design: .monospaced))
					}
				}

				Spacer()
				Button(action: {
					self.running = !self.running
				}) {
					ZStack{
						Circle().fill(self.running ? Color.red : Color.green).frame(width: 100, height: 100).font(.system(size: 20, design: .monospaced))
						self.running ? Text("Stop").foregroundColor(Color.white).font(.system(size: 20, design: .monospaced)) : Text("Start").foregroundColor(Color.white).font(.system(size: 20, design: .monospaced))
					}
				}
			}.padding()
			List{
				LapTime(n: self.lapCount, m: self.lapMinutes, s: self.lapSeconds, c: self.lapCentiseconds)
				ForEach(self.lapTimes.reversed()) { time in
					time
				}
			}
		}
	}

	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("Lap \(num)").font(.system(size: 20, design: .monospaced))
			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)"
	}
}


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

You still have your func getTimeString() which is used in a couple of places at the top, but you have a smaller version of it that only deals with the seconds and centiSeconds in that specific instance of a LapTime object. So, this line: Text(self.lapTimes.last?.getLapSecondsString() ?? "") says, "give me the last lap, then give me the lap seconds as a String made up of just the seconds and centiSeconds for that specific LapTime object."

Note also how the init() func in the struct also generates the time value itself - there was no point in generating it then giving it to the object, when you could just get the object to generate it itself. time = getTimeString(m: minutes, s: seconds, c: centiSeconds).

Hope this makes sense?

You are a boss. Very big thanks.

is it feasible to save the times on another View as a list? as like the screenshot?

You can do that by setting up some modelData, then saving the LapTimes into there. Your second view would then simply access the modelData. Do a search on these forums for modelData, or use your preferred search site.

thanks for the advice. I will look at it. Thanks again

hello, how to retrieve the value of the lap Times.last to compare it with the lap time retrieved via the Picker? I think the picker format for tempsTour is let tempsTour = Double(secondesSelection) + (Double(dixiemesSelection) / 10) Thanks