Customization of Date Picker Issue in SwiftUI

106 Views Asked by At

I have added date picker in my application screen where need to designed using SwiftUI but not able to customize it at all, i want to set its leading, trailing and also want to add color in background of TEXT where selected date is visible but not able to proceed. I tried to check on google also but no luck

struct DateView: View {
    
    @EnvironmentObject var viewM: ViewModel
    
    var body: some View {
        HStack(alignment: .bottom) {
            DatePicker("",
                       selection: $viewM.bookingVM.date,
                       displayedComponents: [.date]
            )
            .frame(height: 40)
            .datePickerStyle(.compact)
            .foregroundColor(Color.black)
            .background(Color.white)
            .multilineTextAlignment(.leading)
            
            Spacer()
            
            DatePicker(
                "",
                selection: $viewM.bookingVM.date,
                displayedComponents: [.date]
            )
            .background(.white)
            .labelsHidden()
            .datePickerStyle(.compact)
            .foregroundColor(Color.black)
            .multilineTextAlignment(.trailing)
            
        }
    }
}

i tried to search on multiple places to customize but nothing found, everywhere they are showing different styling of datePicker but customization is not there. I want to customize the TEXT properties - Feb 9, 2024 showing in attached screenshot

enter image description here

1

There are 1 best solutions below

2
On

Maybe for that you need a custom DatePickerStyle. You can make one yourself by making a struct conforming to the DatePickerStyle protocol like this:

struct CustomDatePickerStyle: DatePickerStyle {
    
    var date: Date
    var text: String?
    @Binding var isDatePickerVisible: Bool
    
    func makeBody(configuration: Configuration) -> some View {
        HStack {
            Image(systemName: "calendar")
            Text(text ?? "")
            Text(date, formatter: DateFormatter.customFormatter)
                .foregroundStyle(.blue)
                .font(.body)
        }
        .onTapGesture {
            withAnimation(.bouncy) {
                isDatePickerVisible.toggle()
            }
        }
        
    }
}

/// Maybe declare your custom formatter too
extension DateFormatter {
    static let customFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "MMM:d:yyyy"
        return formatter
    }()
}

Now, for some reason when creating your own Picker Style the default calendar does seem not to appear though. I solved that by using a State variable that toggles a Calendar on top of the Custom Date Picker:

struct DateView: View {
    
    @State var date = Date.now
    @State var isDatePickerVisible = false
    
    var body: some View {
        ZStack {
            DatePicker("",
                       selection: $date,
                       displayedComponents: [.date]
            )
            .frame(height: 40)
            //.datePickerStyle(.compact)
            .datePickerStyle(CustomDatePickerStyle(date: date, 
                                                   text: "Hi Date!",
                                                   isDatePickerVisible: $isDatePickerVisible))
            .overlay(alignment: .top) {
                DatePicker("", selection: $date, displayedComponents: .date)
                    .datePickerStyle(.graphical)
                    .labelsHidden()
                    .scaleEffect(isDatePickerVisible ? 1 : 0)
                    .offset(y: -320)
                    .frame(width: 300)
                    .frame(maxWidth: .infinity)
            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
    }
}

Of course, you will need to adjust it for your needs. The idea was to point you in the right direction.

Result:

Custom Date Picker

Let me know how do you find this solution!