Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

TimelineView stops updating

For some reason after the first time I tap the Indulge button the UI stops updating. The indulgences array count stops incrementing and the computed property pctIntervalComplete stops updating.

struct Habit: Hashable {
    static func == (lhs: Habit, rhs: Habit) -> Bool {
        return lhs.habitId == rhs.habitId
    }
    
    public let habitId: UUID
    public var habitName: String
    public var indulgences: [Indulgence]
    
    public var daysInterval: Int
    public var hoursInterval: Int
    public var minsInterval: Int
    public var secsInterval: Int
    public var daysIncrease: Int
    public var hoursIncrease: Int
    public var minsIncrease: Int
    public var secsIncrease: Int
    
    private let minutesToSeconds: Int = 60
    private let hoursToSeconds: Int = 3600
    private let daysToSeconds: Int = 86400
    
    public var pctIntervalComplete: Double {
        guard let latestIndulgence = indulgences.last else {
            return 0.0
        }
        
        let currentInterval = Date.now.timeIntervalSinceReferenceDate - latestIndulgence.timestamp.timeIntervalSinceReferenceDate
        
        return currentInterval / targetIntervalInSeconds
    }
    
    public var isIntervalComplete: Bool {
        return pctIntervalComplete >= 1.0
    }
    
    private var targetIntervalInSeconds: TimeInterval {
        return TimeInterval((daysInterval * daysToSeconds) + (hoursInterval * hoursToSeconds) + (minsInterval * minutesToSeconds) + secsInterval)
    }
    
    init(habitId: UUID = UUID(), habitName: String) {
        self.habitId = habitId
        self.habitName = habitName
        indulgences = [Indulgence]()
        daysInterval = 0
        hoursInterval = 0
        minsInterval = 1
        secsInterval = 0
        daysIncrease = 0
        hoursIncrease = 0
        minsIncrease = 1
        secsIncrease = 0
    }
    
    mutating public func addIndulgence() {
        var i = Indulgence(habitId: self.habitId)
        indulgences.append(i)
    }
}

struct Indulgence: Hashable {
    public let indulgenceId: UUID
    public let habitId: UUID
    public let timestamp: Date

    init(indulgenceId: UUID = UUID(), habitId: UUID, timestamp: Date = Date.now) {
        self.indulgenceId = indulgenceId
        self.habitId = habitId
        self.timestamp = timestamp
    }
}

struct HabitListView: View {
    @State private var habitList = [Habit(habitName: "Habit 1"), Habit(habitName: "Habit 2")]
    
    var body: some View {
        List {
            ForEach($habitList, id: \.habitId) { $habit in
                HStack{
                    Text(habit.habitName)
                    Spacer()
                    Button("Indulge") {
                        habit.addIndulgence() //only works once
                    }.buttonStyle(.borderedProminent)
                        .tint(habit.isIntervalComplete ? .pink : .gray)
                    
                    TimelineView(.periodic(from: Date.now, by: 1)) { _ in
                        CircularProgressView(progress: habit.pctIntervalComplete) //stops updating
                            .frame(maxHeight: 36)
                            .scaleEffect(0.35)
                        
                        Text("\(habit.indulgences.count)") //stops incrementing
                    }
                }
            }
        }
    }
}


struct CircularProgressView: View {
    let progress: Double
    let lineWidth: CGFloat = 7
    
    var body: some View {
        ZStack {
            Circle()
                .stroke(
                    Color.pink.opacity(0.5),
                    lineWidth: lineWidth
                )
                
            Circle()
                .trim(from: 0, to: progress)
                .stroke(
                    Color.pink,
                    style: StrokeStyle(
                        lineWidth: lineWidth,
                        lineCap: .round
                    )
                )
                .rotationEffect(.degrees(-90))
                .animation(.easeOut, value: progress)
        }
    }
}

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

You are lying to the compiler by providing your own Equatable conformance:

static func == (lhs: Habit, rhs: Habit) -> Bool {
  return lhs.habitId == rhs.habitId
}

By doing this, you’re telling it that any Habit that has the same habitId is completely equal. This is not true — they are not equal if they have different properties (such as number of indulgences).

Remove this and it will work.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading