Swift 在自定义日历快捷界面中标记几天

Swift 在自定义日历快捷界面中标记几天,swift,calendar,swiftui,Swift,Calendar,Swiftui,我的应用程序中有一个自定义日历。现在,举例来说,我想强调从1月10日到1月20日的10天。我想从这两天开始改变背景色。所以我有两个日期,我想改变这两天和这两天之间的背景色。所以1月10-20日。我该怎么做 fileprivate extension DateFormatter { static var month: DateFormatter { let formatter = DateFormatter() formatter.dateFormat =

我的应用程序中有一个自定义日历。现在,举例来说,我想强调从1月10日到1月20日的10天。我想从这两天开始改变背景色。所以我有两个日期,我想改变这两天和这两天之间的背景色。所以1月10-20日。我该怎么做

fileprivate extension DateFormatter {
    static var month: DateFormatter {
        let formatter = DateFormatter()
        formatter.dateFormat = "MMMM"
        return formatter
    }

    static var monthAndYear: DateFormatter {
        let formatter = DateFormatter()
        formatter.dateFormat = "MMMM yyyy"
        return formatter
    }
}

fileprivate extension Calendar {
    func generateDates(
        inside interval: DateInterval,
        matching components: DateComponents
    ) -> [Date] {
        var dates: [Date] = []
        dates.append(interval.start)

        enumerateDates(
            startingAfter: interval.start,
            matching: components,
            matchingPolicy: .nextTime
        ) { date, _, stop in
            if let date = date {
                if date < interval.end {
                    dates.append(date)
                } else {
                    stop = true
                }
            }
        }

        return dates
    }
}

struct WeekView<DateView>: View where DateView: View {
    @Environment(\.calendar) var calendar

    let week: Date
    let content: (Date) -> DateView

    init(week: Date, @ViewBuilder content: @escaping (Date) -> DateView) {
        self.week = week
        self.content = content
    }

    private var days: [Date] {
        guard
            let weekInterval = calendar.dateInterval(of: .weekOfYear, for: week)
            else { return [] }
        return calendar.generateDates(
            inside: weekInterval,
            matching: DateComponents(hour: 0, minute: 0, second: 0)
        )
    }

    var body: some View {
        HStack {
            ForEach(days, id: \.self) { date in
                HStack {
                    if self.calendar.isDate(self.week, equalTo: date, toGranularity: .month) {
                        self.content(date)
                    } else {
                        self.content(date).hidden()
                    }
                }
            }
        }
    }
}

struct MonthView<DateView>: View where DateView: View {
    @Environment(\.calendar) var calendar

    let month: Date
    let showHeader: Bool
    let content: (Date) -> DateView

    init(
        month: Date,
        showHeader: Bool = true,
        @ViewBuilder content: @escaping (Date) -> DateView
    ) {
        self.month = month
        self.content = content
        self.showHeader = showHeader
    }

    private var weeks: [Date] {
        guard
            let monthInterval = calendar.dateInterval(of: .month, for: month)
            else { return [] }
        return calendar.generateDates(
            inside: monthInterval,
            matching: DateComponents(hour: 0, minute: 0, second: 0, weekday: calendar.firstWeekday)
        )
    }

    private var header: some View {
        let component = calendar.component(.month, from: month)
        let formatter = component == 1 ? DateFormatter.monthAndYear : .month
        return Text(formatter.string(from: month))
            .font(.title)
            .padding()
    }

    var body: some View {
        VStack {
            if showHeader {
                header
            }

            ForEach(weeks, id: \.self) { week in
                WeekView(week: week, content: self.content)
            }
        }
    }
}

struct CalendarView<DateView>: View where DateView: View {
    @Environment(\.calendar) var calendar

    let interval: DateInterval
    let content: (Date) -> DateView

    init(interval: DateInterval, @ViewBuilder content: @escaping (Date) -> DateView) {
        self.interval = interval
        self.content = content
    }

    private var months: [Date] {
        calendar.generateDates(
            inside: interval,
            matching: DateComponents(day: 1, hour: 0, minute: 0, second: 0)
        )
    }

    var body: some View {
        ScrollView(.vertical, showsIndicators: false) {
            VStack {
                ForEach(months, id: \.self) { month in
                    MonthView(month: month, content: self.content)
                }
            }
        }
    }
}

struct RootView: View {
    @Environment(\.calendar) var calendar

    private var year: DateInterval {
        calendar.dateInterval(of: .year, for: Date())!
    }

    var body: some View {
        CalendarView(interval: year) { date in
            Text("30")
                .hidden()
                .padding(8)
                .background(Color.white)
                .clipShape(Circle())
                .padding(.vertical, 4)
                .overlay(
                    Text(String(self.calendar.component(.day, from: date)))
                )
        }
    }
}
fileprivate扩展日期格式化程序{
静态变量月份:DateFormatter{
let formatter=DateFormatter()
formatter.dateFormat=“MMMM”
返回格式化程序
}
静态变量monthAndYear:DateFormatter{
let formatter=DateFormatter()
formatter.dateFormat=“MMMM-yyyy”
返回格式化程序
}
}
文件专用扩展日历{
生成函数(
间隔内:日期间隔,
匹配组件:DateComponents
)->[日期]{
变量日期:[日期]=[]
dates.append(interval.start)
列举日期(
startingAfter:interval.start,
匹配:组件,
匹配策略:。下一次
){date,{u0,在
如果让日期=日期{
如果日期DateView
初始化(周:日期,@ViewBuilder内容:@escaping(日期)->DateView){
self.week=周
self.content=内容
}
私人var天数:[日期]{
警卫
让weekInterval=calendar.dateInterval(of:.weekOfYear,for:week)
else{return[]}
return calendar.generateDates(
内部:周末,
匹配:DateComponents(小时:0,分钟:0,秒:0)
)
}
var body:一些观点{
HStack{
ForEach(天,id:\.self){中的日期
HStack{
如果self.calendar.isDate(self.week,equalTo:date,toGranularity:.month){
自我介绍内容(日期)
}否则{
self.content(date.hidden)()
}
}
}
}
}
}
结构MonthView:视图,其中DateView:视图{
@环境(\.calendar)变量日历
月份:日期
让我们看看标题:Bool
让内容:(日期)->DateView
初始化(
月份:日期,
showHeader:Bool=true,
@ViewBuilder内容:@escaping(日期)->DateView
) {
self.month=月
self.content=内容
self.showHeader=showHeader
}
私人var周:[日期]{
警卫
让monthInterval=calendar.dateInterval(of:.月,for:月)
else{return[]}
return calendar.generateDates(
内部:蒙特维尔,
匹配:DateComponents(小时:0,分钟:0,秒:0,工作日:日历。第一个工作日)
)
}
私有变量头:一些视图{
让component=calendar.component(.month,from:month)
让formatter=component==1?DateFormatter.monthAndYear:.month
返回文本(formatter.string(from:month))
.font(.title)
.padding()
}
var body:一些观点{
VStack{
如果显示标题{
标题
}
ForEach(weeks,id:\.self){week in
WeekView(周:周,内容:self.content)
}
}
}
}
结构CalendarView:视图,其中DateView:视图{
@环境(\.calendar)变量日历
让间隔:日期间隔
让内容:(日期)->DateView
初始化(间隔:DateInterval,@ViewBuilder内容:@escaping(Date)->DateView){
self.interval=间隔
self.content=内容
}
私人var月:[日期]{
日历生成日期(
内部:间隔,
匹配:DateComponents(天:1,小时:0,分钟:0,秒:0)
)
}
var body:一些观点{
滚动视图(.vertical,showsIndicators:false){
VStack{
ForEach(月,id:\.self){month in
MonthView(月:月,内容:self.content)
}
}
}
}
}
结构RootView:View{
@环境(\.calendar)变量日历
年份:日期间隔{
calendar.dateInterval(of:.年,for:Date())!
}
var body:一些观点{
日历视图(间隔:年){中的日期
文本(“30”)
.hidden()
.填充(8)
.背景(颜色.白色)
.clipShape(圆())
.padding(.vertical,4)
.覆盖(
文本(字符串(self.calendar.component(.day,from:date)))
)
}
}
}

使用此swift软件包,您可以根据需要进行定制