我是日历新手。我有一个非连续的日期数组。我想首先选择并突出显示它。并且,未突出显示的必须是不可点击的,即用户只能点击日期列表数组中的那些日期。
经过探索,我发现了一种方法,我们只能通过开始,结束和日期范围禁用选择日期。
我制作了一个视图模型
class DateSelectionVM: ObservableObject{
@Published var activeDate = [
DateComponents(year: 2024, month: 3, day: 12),
DateComponents(year: 2024, month: 3, day: 15),
DateComponents(year: 2024, month: 3, day: 18),
DateComponents(year: 2024, month: 3, day: 20),
DateComponents(year: 2024, month: 3, day: 21),
DateComponents(year: 2024, month: 3, day: 27)
]
@Published var selectedDates: Set<DateComponents> = []
var bounds: Range<Date> {
let calendar = Calendar.current
var dates: [Date] = []
for component in activeDate{
dates.append(calendar.date(from: component)!)
}
if let range = dates.dateRange {
print("Date range: \(range.lowerBound) to \(range.upperBound)")
return range
} else {
print("Array is empty")
}
return dates.first!..<dates.last!
}
init() {
calulateDate()
}
private func calulateDate(){
for date in activeDate{
selectedDates.insert(date)
}
}
}
我定义了一个 activeDate ,它必须在日历上显示为选定且可单击。
我将我的观点定义为
struct DateSelectionView: View {
@ObservedObject var dateSelectionVM = DateSelectionVM()
@Environment(\.calendar) var calendar
var body: some View {
VStack {
Spacer()
VStack{
VStack(alignment: .leading){
HStack{
Text("Your Daily Streak")
.foregroundColor(.blue)
.font(.title2)
Spacer()
Image(systemName: "flame")
.foregroundColor(.blue)
Text("120")
.font(.title)
.bold()
}
Divider()
.padding(EdgeInsets(top: 5, leading: 0, bottom: 5, trailing: 0))
Text("Engage daily")
.font(.system(size: 13))
.padding(EdgeInsets(top: 5, leading: 0, bottom: 5, trailing: 0))
MultiDatePicker("Select Dates", selection: $dateSelectionVM.selectedDates, in: dateSelectionVM.bounds)
.frame(height: 300)
}
.padding()
}
.background(.gray.opacity(0.2))
.cornerRadius(10)
Spacer()
}
.padding()
.background(.purple.opacity(0.2))
.navigationTitle("Stack")
}
}
我面临的问题是我无法禁用除 activeDate 之外的其他日期。 我知道我给出了一系列连续的日期,因此它允许用户单击。还有其他方法可以解决这个问题吗?
我已附上图片。但我想要的是我也想禁用 13,14,16,17,19,22,23,24,25,26。谁能帮我解决一下吗?
这不是我问题的完美答案,但它确实有效。 我所做的是强制取消选择除 activeDates 之外的用户选择。 我是如何通过代码完成的:
在视图模型上添加了代码,当用户尝试从日历中选择日期时,强制取消选择 activeDates 之外的其他日期。
func enableToggleOnActiveDateOnly(for date: DateComponents) {
if selectedDates.contains(date) && !activeDate.contains(date) {
selectedDates.remove(date)
}
}
并从观察函数中调用该函数为
.onChange(of: dateSelectionVM.selectedDates) { _, newValue in
for date in newValue {
dateSelectionVM.enableToggleOnActiveDateOnly(for: date)
}
}