假设我有一个简单的 DatePicker 视图:
struct ContentView: View {
@State private var date = Date()
var body: some View {
DatePicker("Date", selection: $date)
.datePickerStyle(GraphicalDatePickerStyle())
}
}
我怎样才能让用户在星期日或节假日都不能点击?
答案 0 :(得分:0)
好的,所以这不是一件容易的事。经过大量调查,我最终使用了 WenchaoD's FSCalendar。
这花了很多工作,我在日历中添加了我最初想要的其他内容,但这就是最终结果:
struct MyCalendar: UIViewRepresentable {
typealias UIViewType = FSCalendar
@Binding var selectedDate: Date
@Binding var listOfAvailableTimes: [String]
@Binding var appointmentType: String
@Binding var currentPage: Date
@ObservedObject var eventsManager = EventsManager()
var calendar = FSCalendar()
var today: Date {
return Date()
}
func makeCoordinator() -> MyCalendar.Coordinator {
Coordinator(self)
}
func makeUIView(context: Context) -> FSCalendar {
eventsManager.fetchHolidays(year: 2021)
calendar.delegate = context.coordinator
calendar.dataSource = context.coordinator
calendar.scrollDirection = .horizontal
calendar.scope = .month
calendar.locale = Locale(identifier: "es")
calendar.appearance.titleFont = UIFont.systemFont(ofSize: 17)
calendar.appearance.headerTitleFont = UIFont.boldSystemFont(ofSize: 18)
calendar.appearance.weekdayFont = UIFont.boldSystemFont(ofSize: 16)
calendar.appearance.todayColor = .none
calendar.appearance.titleTodayColor = .black
calendar.appearance.weekdayTextColor = .systemGray
calendar.appearance.headerTitleColor = .black
calendar.placeholderType = .none
calendar.appearance.headerMinimumDissolvedAlpha = 0
return calendar
}
func updateUIView(_ uiView: FSCalendar, context: Context) {
uiView.setCurrentPage(currentPage, animated: true)
calendar.reloadData()
}
class Coordinator: NSObject, FSCalendarDelegateAppearance, FSCalendarDataSource, FSCalendarDelegate {
fileprivate let gregorian: Calendar = Calendar(identifier: .gregorian)
var parent: MyCalendar
init(_ calendar: MyCalendar) {
self.parent = calendar
}
var formatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yyyy"
return formatter
}()
//STARTING HERE IS WHERE YOU CAN SEE THE CODE TO INDICATE
//WHICH DAYS SHOULD NOT BE SELECTED. I GOT THE LIST OF HOLIDAYS
//FROM AN API. LET ME KNOW IF YOU NEED HELP WITH THIS OTHER PART.
func calendar(_ calendar: FSCalendar, appearance: FSCalendarAppearance, titleDefaultColorFor date: Date) -> UIColor? {
// IF DATE IS A HOLIDAY, IT SHOULD APPEAR RED
let listOfHolidays = self.parent.eventsManager.holidays
for holiday in listOfHolidays {
guard let excludedDate = formatter.date(from: holiday) else { return nil }
if date.compare(excludedDate) == .orderedSame {
return .red
}
}
// IF DATE IS A SUNDAY, IT SHOULD APPEAR RED
if [1].contains((self.gregorian.component(.weekday, from: date))) {
return .red
}
return nil
}
func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
var stringSelectedDate: String {
let year = Calendar.current.component(.year, from: date)
let month = Calendar.current.component(.month, from: date)
let day = Calendar.current.component(.day, from: date)
let stringDate = String(format: "%04d%02d%02d", year, month, day)
return stringDate
}
self.parent.eventsManager.searchAppointment(day: stringSelectedDate, appointmentType: self.parent.appointmentType) { (appointment) in
self.parent.listOfAvailableTimes = appointment?.times ?? [""]
}
self.parent.selectedDate = date
print("Date Selected = \(formatter.string(from: date))")
}
func minimumDate(for calendar: FSCalendar) -> Date {
return Date()
}
func maximumDate(for calendar: FSCalendar) -> Date {
return Date().addingTimeInterval((60 * 60 * 24) * 365)
}
func calendar(_ calendar: FSCalendar, shouldSelect date: Date, at monthPosition: FSCalendarMonthPosition) -> Bool {
let listOfHolidays = self.parent.eventsManager.holidays
for holiday in listOfHolidays {
// IF DATE IS A HOLIDAY, IT SHOULD NOT BE CLICKABLE
guard let excludedDate = formatter.date(from: holiday) else { return true }
if date.compare(excludedDate) == .orderedSame {
return false
}
}
// IF DATE IS A SUNDAY, IT SHOULD NOT BE CLICKABLE
if [1].contains((self.gregorian.component(.weekday, from: date))) {
return false
}
return true
}
}
}
所以在 ContentView 中,我没有使用 DatePicker,而是使用了 MyCalendar