今天在网上看到一个比较简单好用的日历组件,重要的是它是基于swift的。

官方地址在这里:CVCalendar

其实官方开发人员在产品的首页上已经把如何使用写得非常清楚了。

这位博主也整理得十分清楚。

一、准备工作

1、首先从官方团队的GitHub首页上将项目下载下来:

ios 年度日历控件开发 苹果桌面日历插件_calendar

2、将工程文件CVCalendar.xcodeproj直接拖动到工程当中去:

ios 年度日历控件开发 苹果桌面日历插件_Swift_02

3、在xcode中的左侧项目结构目录中,选中你的工程名称,在中部切换到General视图,然后找到“Embeded Binaries”项,在该项中添加“CVCalendar.framework”:

ios 年度日历控件开发 苹果桌面日历插件_calendar_03

二、代码实现


1、首先导入组件:


import CVCalendar

2、继承两个代理:


 - CVCalendarDelegate


 - CVCalendarMenuViewDelegate


class CVCalendarViewController: UIViewController{
    //...
}

extension CVCalendarViewController: CVCalendarViewDelegate,CVCalendarMenuViewDelegate {
    //...
}

3、定义两个UIView,分别用来显示日历上方的菜单栏(用以显示周一到周日)以及日历本身:


var viewCalendarMenu: CVCalendarMenuView!
    
var viewCalendar: CVCalendarView!

4、初始化这两个UIView:


/*
 *  初始化日历菜单
 */
self.viewCalendarMenu = CVCalendarMenuView(frame: CGRect(x:0,y:60, width:300, height:135))
    
/*
 *  初始化日历
 */
self.viewCalendar = CVCalendarView(frame: CGRect(x:0, y:143, width:300, height:450))

5、为这两个UIView注册代理:


/*
 *  为日历菜单注册代理
 */
self.viewCalendarMenu.menuViewDelegate = self
        
/*
 *  为日历注册代理
 */
self.viewCalendar.calendarDelegate = self

6、将日历组件放置到界面上:


/*
 *  将日历组件放在界面上
 */
self.view.addSubview(self.viewCalendarMenu)
self.view.addSubview(self.viewCalendar)

7、最关键的一步,你需要重写以下这个方法,用来刷新日历组件,否则日历无法显示在界面上:


override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    self.viewCalendarMenu.commitMenuViewUpdate()
    self.viewCalendar.commitCalendarViewUpdate()
}






ios 年度日历控件开发 苹果桌面日历插件_calendar_04



我把上面这些步骤封装在了一个方法中,这样只需要在viewDidLoad中调用这个方法就可以了:


var viewCalendarMenu: CVCalendarMenuView!
    
var viewCalendar: CVCalendarView!
    
override func viewDidLoad() {
    super.viewDidLoad()

    /*
     *  初始化日历组件
     */
    self.initCalendar()
}

/**
 *  初始化日历组件
 */
func initCalendar()->Void{
    /*
     *  在页面顶端显示当前的日期
     */
    let currentCalendar:Calendar = Calendar.init(identifier: .gregorian)
    self.title = CVDate(date: Date(), calendar: currentCalendar).globalDescription
    
    /*
     *  初始化日历菜单
     */
    self.viewCalendarMenu = CVCalendarMenuView(frame: CGRect(x:0,y:60, width:300, height:135))
    
    /*
     *  初始化日历
     */
    self.viewCalendar = CVCalendarView(frame: CGRect(x:0, y:143, width:300, height:450))
        
    /*
     *  为日历菜单注册代理
     */
    self.viewCalendarMenu.menuViewDelegate = self
        
    /*
     *  为日历注册代理
     */
    self.viewCalendar.calendarDelegate = self
        
    /*
     *  将日历组件放在界面上
     */
    self.view.addSubview(self.viewCalendarMenu)
    self.view.addSubview(self.viewCalendar)
}


三、扩展


点击这里查看官方高阶api
1、设置一周的第一天


func firstWeekday() -> Weekday {
    return .Sunday
}

2、跳转月份


在这个扩展例子中,官方写了两个方法


第一个方法用来直接返回当月:

@IBAction func todayMonthView() {
    self.calendarView.toggleCurrentDayView()
}

第二个方法用来直接跳到一个指定月份,注意入参并不是直接表示月份数,而是表示希望跳转到的月份与当月之间相差多少个月:


func toggleMonthViewWithMonthOffset(offset: Int) {
    let calendar = NSCalendar.currentCalendar()
    let calendarManager = CVCalendarManager.sharedManager
    let components = calendarManager.componentsForDate(NSDate()) // from today
        
    components.month += offset
    components.day = 1 // CVCalendar will select this day view
        
    let resultDate = calendar.dateFromComponents(components)!
        
    self.calendarView.toggleMonthViewWithDate(resultDate)
}

3、往前或往后一个月:


self.calendarView.loadNextMonthView()
self.calendarView.loadPreviousMonthView()

4、显示不属于当前月份的日期:


self.viewCalendar!.changeDaysOutShowingState(shouldShow: true)

5、动态切换日历的显示模式:


切换为周历


calendarView.changeMode(.WeekView)

切换为月历


calendarView.changeMode(.MonthView)



extension CVCalendarViewController: CVCalendarViewDelegate,CVCalendarMenuViewDelegate {
    //视图模式
    func presentationMode() -> CalendarMode {
        //使用月视图
        return .monthView
    }
    
    //每周的第一天
    func firstWeekday() -> Weekday {
        //从星期一开始
        return .monday
    }
    
    func presentedDateUpdated(_ date: CVDate) {
        //导航栏显示当前日历的年月
        self.title = date.globalDescription
    }
    
    //每个日期上面是否添加横线(连在一起就形成每行的分隔线)
    func topMarker(shouldDisplayOnDayView dayView: CVCalendarDayView) -> Bool {
        return true
    }
    
    //切换月的时候日历是否自动选择某一天(本月为今天,其它月为第一天)
    func shouldAutoSelectDayOnMonthChange() -> Bool {
        return false
    }
    
    //日期选择响应
    func didSelectDayView(_ dayView: CVCalendarDayView, animationDidFinish: Bool) {
        //获取日期
        let date = dayView.date.convertedDate()!
        // 创建一个日期格式器
        let dformatter = DateFormatter()
        dformatter.dateFormat = "yyyy年MM月dd日"
        let message = "当前选择的日期是:\(dformatter.string(from: date))"
        //将选择的日期弹出显示
        let alertController = UIAlertController(title: "", message: message,preferredStyle: .alert)
        let okAction = UIAlertAction(title: "确定", style: .cancel, handler: nil)
        alertController.addAction(okAction)
        self.present(alertController, animated: true, completion: nil)
    }
}