Re-enable button based on date in SwiftUI

58 views Asked by At

I'm in the process of building a habit tracker and I've come across a problem. In my app there is a button that you can click to indicate that you have completed your task. As soon as this button is pressed, I set it to .disabled() so that the task cannot be executed more than once. Now I want the button to be able to be pressed again every day. How can I ensure that the button is enabled again at 0 o'clock? I have tried to change the variable isButtonDisabled at 0:00, but without success. Any help is appreciated!

import SwiftUI

struct HabitButton: View {
    @State private var isButtonDisabled: Bool = false // This value should change every new day at 0 o'clock.
    @AppStorage("streak") private var streak: Int = 0
    
    var body: some View {
        if (isButtonDisabled == false) {
            Button {
                UNUserNotificationCenter.current().setBadgeCount(0)
                isButtonDisabled = true
            } label: {
                Text("I have eaten an apple")
                    .padding(.vertical, 20)
                    .foregroundStyle(.white)
                    .fontDesign(.rounded)
                    .bold()
                    .frame(width: 400)
            }
            .background(BasicColor.tint)
            .clipShape(RoundedRectangle(cornerRadius: 20))
        } else {
            Button {
                UNUserNotificationCenter.current().setBadgeCount(0)
                isButtonDisabled = true
            } label: {
                Text("I have eaten an apple")
                    .padding(.vertical, 20)
                    .foregroundStyle(.white)
                    .fontDesign(.rounded)
                    .bold()
                    .frame(width: 400)
            }
            .background(BasicColor.tint)
            .clipShape(RoundedRectangle(cornerRadius: 20))
            .disabled(true)
        }
    }
}

#Preview {
    HabitButton()
}

I tried something similar to that, but these expressions are not allowed in SwiftUI.

struct HabitButton: View {
    @State private var isButtonDisabled: Bool = false // This value should change every new day at 0 o'clock.
    @AppStorage("streak") private var streak: Int = 0
    
    var body: some View {
        if (Date() == 0) {
            isButtonDisabled = false
        }
1

There are 1 answers

0
Fabio Pohl On BEST ANSWER

For documentation purposes

I have now adjusted the function a little so that you can only click the button once a day. To do this, I save the date on which the button was clicked in the UserDefaults. When the app is opened, a timer runs, which executes a function every 60 seconds to check whether the current date is one day after the last saved date.

Code snippets:

@AppStorage("lastAppleDate") private var lastAppleDate: Date?

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

.onReceive(timer) { _ in
        checkIfButtonShouldBeEnabled()
    }

private func checkIfButtonShouldBeEnabled() {
    if let lastAppleDate = lastAppleDate {
        let calendar = Calendar.current
        if !calendar.isDateInToday(lastAppleDate) {
            isButtonDisabled = false
        }
    } else {
        isButtonDisabled = false
    }
}