Search code examples
swiftswiftui

how to select the current date in the pickerDate view


How to select the current date on PickerDate view when user just enter the page

my home page looking like this

    @State private var selectedDate: Date = Date()
    @State private var showDayView: Bool = false
    @State private var offsetY: CGFloat = -40
    @State private var searchText: String = ""
    
    var body: some View {
        NavigationStack{
            ZStack(alignment: .top) {
                VStack {
                    HStack {
                        Text("August")
                            .font(customFont(20, "-Medium"))
                        
                        Spacer()
                        NavigationLink {
                            Text("Calendar")
                        } label: {
                            Image("Calendar")
                        }
                        
                    }
                    .padding([.horizontal, .top])
                    
                    .background(Color.accentColor)
                    
                    PickerDate(selectedDate: $selectedDate) {
                        self.singlePickedDate(date: $0)
                    }
                    
                    Spacer()
                }
                
                DayView(selectedDate: $selectedDate)
                    .transition(.move(edge: .bottom)) 
                    .offset(y: offsetY)
            }

    func singlePickedDate(date: Date) {
        selectedDate = date
        withAnimation {
            showDayView = true
        }
    }

and My PickerDate looks like this to call the PickeDate View

struct PickerDate: View{
    
    @Binding var selectedDate: Date
    var onDateSelected: (Date) -> Void
    
    let daysOfWeek: [String] = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
    
    
    var body: some View{
        HStack{
            ForEach(0..<7){ index in
                let day = Calendar.current.date(byAdding: .day, value: index, to: startOfWeek())!
                VStack{
                    Text(daysOfWeek[Calendar.current.component(.weekday, from: day) - 1])
                        .font(customFont(15,"-Medium"))
                        .padding(.top,15)
                        .fontWeight(selectedDate == day ? .bold : .regular)
                    
                    Text(day, format: .dateTime.day())
                        .font(customFont(15,"-Medium"))
                        .fontWeight(selectedDate == day ? .bold : .regular)                        .frame(width: 30, height: 30)
                        .background(selectedDate == day ? Color.white : Color.clear)         .clipShape(Circle())
                        .foregroundColor(.black)
                        .padding(.bottom, 8)
                }
                .padding(.horizontal, 8)
                .background(selectedDate == day ? Color.deepAccent : Color.accentColor)
                .clipShape(Capsule())
                .onTapGesture {
                    onDateSelected(day)
                }
            }
        }
        .background(Color.accentColor)
        .frame(maxWidth: .infinity)
        .padding(.vertical, 10)
    }
    
    func startOfWeek() -> Date {
        let calendar = Calendar.current
        let today = Date()
        let components = calendar.dateComponents([.yearForWeekOfYear, .weekOfYear], from: today)
        return calendar.date(from: components) ?? today
    }
    
}

I'm wondering why my onAppear doesn't works here? Is that because when I passed selectedDate to the pickerDate view, the current date is not current any more?

but I tried to add a onAppear at PickerDate view too, it also doesn't work


Solution

  • The problem is that your selectedDate property has the time set to the current time while in the PickerDate view the local variable day has no time (it's 00:00.00) and therefore you will new get the two to match so all your checks for equality will fail

    The easiest solution here is to set the time part of selectedDate to zero as well.

    So in your main view change the initialisation of the property to

    @State private var selectedDate: Date = Calendar.current.startOfDay(for: .now)