定制Github日历库EPCalendarPicker实现项目需求(一)

版权声明:大熊猫猪·侯佩原创或翻译作品.谢绝转载! hopy https://blog.csdn.net/mydo/article/details/82178128

最近App需要一个日历显示界面,找了一下发现EPCalendarPicker库比较合适。

简单看了一下它的源代码,发现其简单,小巧,虽然界面可定制能力一般。

我的App不需要使用日期的选择功能,只需要显示功能。它的界面对于我来说基本满足,不需要再进行太大的涂修,所以可定制有限也勉强够用了。


这里写图片描述

不过EPCalendarPicker对于我的项目来说有几个需要改进的地方:

  • 它只能初始化成startYear到endYear之间的整年日期;而我需要精细到某个月
  • 它的界面都是英文;而我需要根据不同语言自动进行切换
  • 它的选择日期的颜色是可以用户修改的,但只能是相同的;而我需要不同日期有不同的选择颜色

我看了一下EPCalendarPicker作者有近1年没更过了,找作者估计也是没戏了。所以我们主要就以上3点自己做一下修改。有的修改很简单,有的稍微困难点;但不管怎样总体难度都不会太高,请跟随本猫,顺其自然 ;)

一.创建精确到月

打开EPCalendarPicker.swift文件发现其最具体最复杂的初始化器是:

public init(startYear: Int, endYear: Int, multiSelection: Bool, selectedDates: [Date]?)

查看相关源代码可以发现,默认初始月都是1月。因为我们需要精确到指定月,所以首先需要增加2个实例属性:

fileprivate(set) open var startYear: Int
fileprivate(set) open var endYear: Int
fileprivate(set) open var startMonth: Int   //New
fileprivate(set) open var endMonth: Int     //New

为了为它们赋值,需要增加一个新的初始化器:

public init(startYear: Int, startMonth: Int, endYear: Int, endMonth: Int, multiSelection: Bool, selectedDates: [Date]?)

把之前初始化器中的内容原封不动的拷贝进来,并增加对startMonth和endMonth的赋值代码。同时将原来的初始化器内容修改为:

public convenience init(startYear: Int, endYear: Int, multiSelection: Bool, selectedDates: [Date]?) {
    self.init(startYear: startYear, startMonth: 1, endYear: endYear, endMonth: 1, multiSelection: multiSelection, selectedDates: selectedDates)
}

注意初始化器名称要增加convenience修饰。

当然光改添加2个实例属性是不够的,我们还得深入到调用逻辑中去,遍历该类将:

let startDate = Date(year: startYear, month: 1, day: 1)

代码替换为:

let startDate = Date(year: startYear, month: startMonth, day: 1)

因为每个Section代表一个月,所以原来Section的属性总是12的整倍数。但现在精确到了月,所以Section的数量就发生了变化,定位到如下方法:

override open func numberOfSections(in collectionView: UICollectionView) -> Int

将其中对于Section数量的算法做一下替换:

//let numberOfMonths = 12 * (endYear - startYear) + 12
//上面一句替换为如下一句
let numberOfMonths = (12 - startMonth + 1) + (endYear - startYear - 1) * 12 + endMonth

EPCalendarPicker类中有一个滚动到当前日的实例方法,因为月的数量发生了变化,所以我们需要重写该实例方法:

open func scrollToToday () {
    let today = Date()
    scrollToMonthForDate(today)
}

open func scrollToMonthForDate (_ date: Date) {

    let month = date.month()
    let year = date.year()
    //重新计算section的索引
    let section = ((year - startYear) * 12) + month - startMonth + 1
    let indexPath = IndexPath(row:1, section: section-1)

    self.collectionView?.scrollToIndexpathByShowingHeader(indexPath)
}

最后我们需要对传入的年和月做合法验证,在如下方法中添加一段代码:

override open func numberOfSections(in collectionView: UICollectionView) -> Int{
    if startYear > endYear {
        return 0
    }
    //添加如下一句
    if startYear == endYear,startMonth > endMonth{
        return 0
    }
    //省略无关代码...
}

OK,现在我们就可以使用新的初始化器,创建EPCalendarPicker精确到起始月和结束月了,虽然很累,但看一下成果,还是很有成就感的嘛 :)

以下是2016.5到2017.1的日历界面:


这里写图片描述

猜你喜欢

转载自blog.csdn.net/mydo/article/details/82178128