SwiftUI中修改KVKCalendar的CalendarType实现日历视图类型切换
解决方案
核心实现逻辑是将日历类型的控制状态通过Binding从SwiftUI视图层传入封装好的UIViewRepresentable组件,状态变更时触发调用KVKCalendar原生的类型切换方法即可。
1. 修改ContentView.swift
添加分段控制器绑定selectedType,并将该状态传递给CalendarDisplayView:
import SwiftUI import KVKCalendar struct ContentView: View { @State var events: [Event] = [] @State var selectedType: CalendarType = .week var body: some View { VStack(spacing: 0){ // 分段切换控制器 Picker("日历类型", selection: $selectedType) { Text("日").tag(CalendarType.day) Text("周").tag(CalendarType.week) Text("月").tag(CalendarType.month) } .pickerStyle(.segmented) .padding() CalendarDisplayView(events: $events, selectedType: $selectedType) } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
2. 修改CalendarDisplayView.swift
新增类型绑定参数,在状态更新时调用原生切换方法:
import SwiftUI import EventKit import KVKCalendar struct CalendarDisplayView: UIViewRepresentable { @Binding var events: [Event] @Binding var selectedType: CalendarType // 新增类型绑定 // 修改初始化方法 public init(events: Binding<[Event]>, selectedType: Binding<CalendarType>) { self._events = events self._selectedType = selectedType } private var calendar: CalendarView = { var style = Style() if UIDevice.current.userInterfaceIdiom == .phone { style.timeline.widthTime = 40 style.timeline.currentLineHourWidth = 45 style.timeline.offsetTimeX = 2 style.timeline.offsetLineLeft = 2 style.headerScroll.titleDateAlignment = .center style.headerScroll.isAnimateTitleDate = true style.headerScroll.heightHeaderWeek = 70 style.event.isEnableVisualSelect = false style.month.isHiddenTitle = true style.month.weekDayAlignment = .center } else { style.timeline.widthEventViewer = 350 style.headerScroll.fontNameDay = .systemFont(ofSize: 17) } style.month.autoSelectionDateWhenScrolling = true style.timeline.offsetTimeY = 25 style.startWeekDay = .monday style.timeSystem = .current ?? .twelve style.systemCalendars = ["Calendar"] if #available(iOS 13.0, *) { style.event.iconFile = UIImage(systemName: "paperclip") } style.locale = Locale.current style.timezone = TimeZone.current return CalendarView(frame: UIScreen.main.bounds, style: style) }() func makeUIView(context: UIViewRepresentableContext<CalendarDisplayView>) -> CalendarView { calendar.dataSource = context.coordinator calendar.delegate = context.coordinator calendar.reloadData() return calendar } func updateUIView(_ uiView: CalendarView, context: UIViewRepresentableContext<CalendarDisplayView>) { context.coordinator.events = events // 新增:类型变更时触发切换 if uiView.type != selectedType { uiView.setType(selectedType, animated: true) } } func makeCoordinator() -> CalendarDisplayView.Coordinator { Coordinator(self) } class Coordinator: NSObject, CalendarDataSource, CalendarDelegate { private let view: CalendarDisplayView var events: [Event] = [] { didSet { view.calendar.reloadData() } } init(_ view: CalendarDisplayView) { self.view = view super.init() } func eventsForCalendar(systemEvents: [EKEvent]) -> [Event] { return events } } }
如果需要添加年视图、列表视图等其他切换选项,只需要在Picker中新增对应CalendarType枚举的选项即可。
内容的提问来源于stack exchange,提问作者Kazuya Fujimoto
相关产品推荐
相关产品推荐

