Home > Software design >  Text not updating when @Published is Updated
Text not updating when @Published is Updated

Time:11-30

I have a view that has the days of the week, which should increment when the user toggles the arrows (increment either to the next or prev day)

I first grab the current day of the week and format to a String. Then save to my var currentWeekday

class GrabCurrentDate: ObservableObject {
    @Published var currentWeekday = Date().dayNumberOfWeek()!
    
    func currentDate() {
        let date = Date()
        let formatter = DateFormatter()
           formatter.timeStyle = .short
        let dateString = formatter.string(from: Date())
        //set day of week
        currentWeekday = Date().dayNumberOfWeek()!
}

Then I dump the days of the week in a switch statement, assigning the days to display in the view as a string.

extension Date {
    func dayNumberOfWeek() -> Int? {
        return Calendar.current.dateComponents([.weekday], from: self).weekday! - 1
    }
}

func weekdayAsString(date: Int) -> String {
    switch Date().dayNumberOfWeek() {
        case 0:
        
            return "Sunday"
            
        case 1:
            return "Monday"
            
        case 2:
            return "Tuesday"
            
        case 3:
            return "Wednesday"
           
        case 4:
            return "Thursday"
           
        case 5:
            return "Friday"
           
        case 6:
            return "Saturday"
         
        default:
            return ""
    }
}

Lastly my view

Struct testView: View {
    @ObservedObject var currentDate = GrabCurrentDate()
           HStack{
                        Image(systemName: "arrow.left")
                            .onTapGesture{
                                currentDate.currentWeekday -= 1
                                print(currentDate.currentWeekday )
                            }
                        Text(weekdayAsString(date: currentDate.currentWeekday)) // << display current day of week
                        
                        Image(systemName: "arrow.right")
                            .onTapGesture{
                                currentDate.currentWeekday  = 1
                            }
                    }
}

When I go to increment, the published var updates correctly but the view does not. Thanks in advance for the help.

CodePudding user response:

Maybe this can help:

enum Weekday: String, CaseIterable {
    case sunday
    case monday
    case tuesday
    case wednesday
    case thursday
    case friday
    case saturday
}

class CurrentDate: ObservableObject {
    
    @Published private(set) var currentDay: Int = Date().currentDay
    
    var currentWeekday: Weekday {
        Weekday.allCases[currentDay - 1]
    }
    
    func increment() {
       // check if the currentDay is within the range
        currentDay  = 1
    }
    
    func decrement() {
        currentDay -= 1
    }
    
}

extension Date {
    
    var currentDay: Int {
        return Calendar.current.component(.weekday, from: self)
    }
}

struct ContentView: View {
    
    @StateObject private var currentDate = CurrentDate()
    
    var body: some View {
        NavigationStack {
            VStack {
                Text(currentDate.currentWeekday.rawValue.capitalized)
                Button("Next") {
                    currentDate.increment()
                }
            }
        }
    }
}

CodePudding user response:

You're NOT using the currentDate.currentWeekday in the weekdayAsString function. See in the switch you're using Date().dayNumberOfWeek() instead. So simply change it to the argument date:

func weekdayAsString(date: Int) -> String {
    switch date {
        case 0:
            return "Sunday"
        case 1:
            return "Monday"
        case 2:
            return "Tuesday"
        case 3:
            return "Wednesday"
        case 4:
            return "Thursday"
        case 5:
            return "Friday"
        case 6:
            return "Saturday"
        default:
            return ""
    }
}

Also I suggest you use a Button instead of an Image with an onTapGesture gesture, like this:

Button {
    currentDate.currentWeekday  = 1
    print(currentDate.currentWeekday )
} label: {
    Image(systemName: "arrow.right")
}

You can also show them in the primary color if you prefer it:

Button {
    currentDate.currentWeekday  = 1
    print(currentDate.currentWeekday )
} label: {
    Image(systemName: "arrow.right")
}
.foregroundColor(.primary)
  • Related