You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 21:39:03