当前位置: > > > Swift - 第三方日历组件CVCalendar使用详解1(配置、基本用法)

Swift - 第三方日历组件CVCalendar使用详解1(配置、基本用法)

相关文章系列:
Swift - 第三方日历组件CVCalendar使用详解1(配置、基本用法)[当前文章]
Swift - 第三方日历组件CVCalendar使用详解2(高级功能、样式)

CVCalendar 是一款超好用的第三方日历组件,不仅功能强大,而且可以方便地进行样式自定义。同时,CVCalendar 还提供月视图、周视图两种展示模式,我们可以根据需求自由选择使用。

一、安装配置

(1)从 GitHub 上下载最新的代码:https://github.com/Mozharovsky/CVCalendar
(2)将下载下来的源码包中 CVCalendar.xcodeproj 拖拽至你的工程中 

(3)工程 -> General -> Embedded Binaries 项,把 iOS 版的 framework 添加进来:CVCalendar.framework

(4)最后,在需要使用 CVCalendar 的地方 import 进来就可以了
import CVCalendar

二、基本用法

1,月视图使用样例 

(1)效果图
  • 初始化的时候自动显示当月日历,且“今天”的日期文字是红色的。
  • 顶部导航栏标题显示当前日历的年、月信息,日历左右滑动切换的时候,标题内容也会随之改变。
  • 点击导航栏右侧的“今天”按钮,日历又会跳回到当前日期。
  • 点击日历上的任一日期时间后,该日期背景色会变蓝色(如果是今天则变红色)。同时我们在日期选择响应中,将选择的日期弹出显示。
           

(2)样例代码
  • 日历组件分为:CVCalendarMenuView CVCalendarView 两部分。前者是显示星期的菜单栏,后者是日期表格视图。这二者的位置和大小我们可以随意调整设置。
  • 组件提供了许多代理协议让我进行样式调整或功能响应,我们可以选择使用。但其中 CVCalendarViewDelegate, CVCalendarMenuViewDelegate 这两个协议是必须的。
import UIKit
import CVCalendar

class ViewController: UIViewController {
    //星期菜单栏
    private var menuView: CVCalendarMenuView!
    
    //日历主视图
    private var calendarView: CVCalendarView!
    
    var currentCalendar: Calendar!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        currentCalendar = Calendar.init(identifier: .gregorian)
        
        //初始化的时候导航栏显示当年当月
        self.title = CVDate(date: Date(), calendar: currentCalendar).globalDescription
        
        //初始化星期菜单栏
        self.menuView = CVCalendarMenuView(frame: CGRect(x:0, y:80, width:300, height:15))
        
        //初始化日历主视图
        self.calendarView = CVCalendarView(frame: CGRect(x:0, y:110, width:300,
                                                         height:450))
        
        //星期菜单栏代理
        self.menuView.menuViewDelegate = self
        
        //日历代理
        self.calendarView.calendarDelegate = self
        
        //将菜单视图和日历视图添加到主视图上
        self.view.addSubview(menuView)
        self.view.addSubview(calendarView)
    }
    
    //今天按钮点击
    @IBAction func todayButtonTapped(_ sender: AnyObject) {
        let today = Date()
        self.calendarView.toggleViewWithDate(today)
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        
        //更新日历frame
        self.menuView.commitMenuViewUpdate()
        self.calendarView.commitCalendarViewUpdate()
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

extension ViewController: 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)
    }
}
源码下载hangge_1504.zip

2,周视图使用样例

同月视图模式相比,周视图日历区域只有一行(每次显示7天日期)。其它方面和月视图相比差别不大,也都是左右滑动切换显示下一周、下一周日期。
import UIKit
import CVCalendar

class ViewController: UIViewController {
    //星期菜单栏
    private var menuView: CVCalendarMenuView!
    
    //日历主视图
    private var calendarView: CVCalendarView!
    
    var currentCalendar: Calendar!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        currentCalendar = Calendar.init(identifier: .gregorian)
        
        //初始化的时候导航栏显示当年当月
        self.title = CVDate(date: Date(), calendar: currentCalendar).globalDescription
        
        //初始化星期菜单栏
        self.menuView = CVCalendarMenuView(frame: CGRect(x:0, y:80, width:300, height:15))
        
        //初始化日历主视图
        self.calendarView = CVCalendarView(frame: CGRect(x:0, y:110, width:300,
                                                         height:50))
        
        //星期菜单栏代理
        self.menuView.menuViewDelegate = self
        
        //日历代理
        self.calendarView.calendarDelegate = self
        
        //将菜单视图和日历视图添加到主视图上
        self.view.addSubview(menuView)
        self.view.addSubview(calendarView)
    }
    
    //今天按钮点击
    @IBAction func todayButtonTapped(_ sender: AnyObject) {
        let today = Date()
        self.calendarView.toggleViewWithDate(today)
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        
        //更新日历frame
        self.menuView.commitMenuViewUpdate()
        self.calendarView.commitCalendarViewUpdate()
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

extension ViewController: CVCalendarViewDelegate,CVCalendarMenuViewDelegate {
    //视图模式
    func presentationMode() -> CalendarMode {
        //使用周视图
        return .weekView
    }
    
    //每周的第一天
    func firstWeekday() -> Weekday {
        //从星期一开始
        return .monday
    }
    
    func presentedDateUpdated(_ date: CVDate) {
        //导航栏显示当前日历的年月
        self.title = date.globalDescription
    }
    
    //每个日期上面是否添加横线(连在一起就形成每行的分隔线)
    func topMarker(shouldDisplayOnDayView dayView: CVCalendarDayView) -> Bool {
        return true
    }
    
    //切换周的时候日历是否自动选择某一天(本周为今天,其它周为第一天)
    func shouldAutoSelectDayOnWeekChange() -> Bool {
        return false
    }
    
    //日期选择响应
    func didSelectDayView(_ dayView: CVCalendarDayView, animationDidFinish: Bool) {
        //获取日期
        let date = dayView.date.convertedDate(calendar: currentCalendar)!
        // 创建一个日期格式器
        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)
    }
}
评论6
  • 6楼
    2017-12-21 15:10

    航哥你好,GitHub上下来的这个项目的Demo直接运行是会出现 “Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value”这个错误,另外请教新手想读懂这些开源项目的源码该如何下手,每一个类都有太多属性不知道是什么作用

    站长回复

    我试了下官方的demo,运行是没问题的啊?不知道你那边是什么情况。学习这些第三方的组件库,无非就是看看它提供的demo,它提供的一些说明文档,或者网上其他人写的相关文章(比如我就常常写一些介绍开源库的文章,你可常来看看)。

  • 5楼
    2017-11-30 15:05
    lorain东

    您好 在Products中CVCalendar.framework 一直是红色的 添加到工程 import 也是暴红

    站长回复

    为了缩小体积,我上传的工程压缩包中没有包含CVCalendar库,你要手动把它下载下来添加到项目中。

  • 4楼
    2017-11-17 04:37
    jose

    你好,我使用的时候出现这种 “Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value” 改怎么办

    站长回复

    试了下没碰到你说的问题。你试试把我们文章里的工程附件下载下来,直接运行也会有同样的问题吗?

  • 3楼
    2017-08-16 15:37
    liqiu

    您好,当前日期比实际日期小一天,这个bug怎么处理

    站长回复

    我测试了下是没问题的啊,是不是你设备或者模拟器系统的时区设置的不对。

  • 2楼
    2017-06-05 11:01
    tanlei

    站长你好,我想请问下,我这边日历信息都是现实英文,不知道怎么本地化变成中文呢

    站长回复

    这个组件本身就做好国际化了,你检查下模拟器或者手机,系统语言、以及环境是否是中国。

  • 1楼
    2017-04-19 17:25
    lf98287

    站长你好,我想请问下,如何让日历控件在月视图和周视图之间进行切换,我尝试过用控件changeMode方法,但是发现只能切换一次。

    站长回复

    我测试了下是可以交替切换的。要注意:只有当前有选中日期的情况下才能切换。