MBCalendarKit 是一个考虑了现代最佳实践和 Swift 互操作性的 Objective-C 编写的日历控件。
它提供了灵活的日历控件,支持显示由 NSCalendar
支持的任何日历系统。它还包括一个用于自定义日历单元格的 API。它还附带了一个由原始 iOS 日历启发的预构建视图控制器。
您需要针对 iOS 8 及更高版本。有三种方法可以集成 MBCalendarKit:
pod 'MBCalendarKit', '~> 5.0.0'
MBCalendarKit/CalendarKit
。如果遇到任何问题,请前往问题 #48 并留下意见。
MBCalendarKit 使用 Objective-C 编写。要与 Swift 一起使用 MBCalendarKit,只需将其链接起来并使用 import MBCalendarKit
。MBCalendarKit 5.0.0 包含了多项 Swift 增强。
这里的示例使用 Swift 编写,以简化说明。请注意,在编写 Objective-C 时,MBCalendarKit 使用 CK
作为其类和枚举的前缀。CalendarView
在 Swift 中是 CKCalendarView
,等等。
具体信息,请参阅 迁移指南。
您有两个选择使用 MBCalendarKit 显示日历。
CKCalendarView
的示例。如果您想手动管理视图层次结构或者只想显示不带事件表格的日历视图,请使用此功能。/// Here's how you'd show a CalendarView from within a view controller.
/// Import the framework, then it's just three easy steps.
import MBCalendarKit
// 1. Instantiate a CKCalendarView
let calendar = CalendarView()
// 2. Present the calendar
self.view.addSubview(calendar)
// 3. Add positioning constraints:
self.calendarView.translatesAutoresizingMaskIntoConstraints = false
calendarView.topAnchor.constraint(equalTo:self.topLayoutGuide.bottomAnchor).isActive = true
calendarView.centerXAnchor.constraint(equalTo:self.view.centerXAnchor).isActive = true
CalendarViewController
实例。使用CKCalendarViewController可以为您增加一个“今天”按钮和工具栏中的分段控制器,这将允许您选择显示模式。在MBCalendarKit 5.0.0及以后版本,如果您需要事件表格视图,也请使用CalendarViewController
。/// Here's how you'd show a CalendarViewController from
/// within a view controller. It's just three easy steps, including the framework import.
// 1. Import MBCalendarKit:
import MBCalendarKit
// 2. Instantiate a CalendarViewController
let calendar = CalendarViewController()
// 3. Present the calendar
self.present(calendar animated:true completion:nil)
使用CalenderView
和CalendarViewController
,您可以通过使用dataSource
和delegate
属性来显示事件,并获得有关用户交互的信息。
注意:在MBCalendarKit的旧版本中,CKCalendarViewController
曾经是UINavigationViewController
的子类,因此它不能安装在其他导航控制器内。在5.0.0版本中,这种情况不再存在。如果想在UINavigationViewController
中嵌入日历,您必须自行安装。有关详细信息,请参阅迁移指南。
在MBCalendarKit 5.0.0中,CalendarView
中新增了一个名为customCellProvider
的新属性,可以使用它以非常强大方式自定义单元格的显示。继续阅读以了解更多关于设置事件的信息。
CKCalendarDataSource
协议定义了一个方法,该方法提供了一组CKCalendarEvent
对象。日历视图会自动在代表具有事件的日期的单元格中显示一个指示器。
func calendarView(_ calendarView: CalendarView, eventsFor date: Date) -> [CalendarEvent]
在数据源中实现此方法,并返回与传入日期匹配的事件。
以下是在日历中添加一些事件的示例
func adEventsToCalendar() {
let title : NSString = NSLocalizedString("Add Swift Demo", comment: "") as NSString
if let date : Date = NSDate(day: 9, month: 1, year: 2015) as Date?
{
let event : CalendarEvent = CalendarEvent(title: title as String, andDate: date, andInfo: nil)
self.data[date] = [event]
}
let title2 : NSString = NSLocalizedString("Release MBCalendarKit 5.0.0", comment: "") as NSString
if let date2 : Date = NSDate(day: 15, month: 8, year: 2017) as Date?
{
let event2 : CalendarEvent = CalendarEvent(title: title2 as String, andDate: date2, andInfo: nil)
self.data[date2] = [event2]
}
}
现在,实现数据源
// MARK: - CalendarDataSource
override func calendarView(_ calendarView: CalendarView, eventsFor date: Date) -> [CalendarEvent]
{
let eventsForDate = self.data[date] ?? []
return eventsForDate
}
注意:用作键的日期必须与数据源方法传入的日期完全匹配。确保这一点的常见方法是使用NSCalendar
的isDate:equalToDate:toUnitGranularity:
,传入两个日期和作为第三个参数的.day
,以创建传递给事件的对象。
您还可以在示例应用的CKDemoViewController.m
或SwiftDemoViewController.swift
中查看此代码。
当用户选择一个日期时,会在定义在CalendarViewDelegate
协议中的这些方法上调用来委托。当用户在标题中点击箭头或者当用户从单元格抬起手指时,日期被视为已选择。
func calendarView(_ calendarView: CalendarView, willSelect date: Date)
func calendarView(_ calendarView: CalendarView, didSelect date: Date)
当在事件表格中选中一行时,会在委托上调用此方法。您可以使用它来推送一个详细视图,例如。
func calendarView(_ calendarView: CalendarView, didSelect event: CalendarEvent)
MBCalendarKit 5.0.0引入了一种全新的自定义单元格的方式,从而使您可以在单元格中添加自己的数据,甚至进行完全的设计。MBCalendarKit通过建立在UICollectionView
之上,提供了一个非常简单的API。首先,您需要在自己的代码中实现CustomCellProviding
。这由两部分组成:首先,告诉MBCalendarKit用于单元格的UICollectionViewCell
子类,其次,实现一个回调方法,这将是您根据单元格上下文自定义单元格的机会。
让我们看一下基于默认实现的实现示例
// Step 1. Formally adopt the `CustomCellProviding` protocol
Class MyCustomCellProvider: NSObject, CustomCellProviding {
// Step 2. Inform the framework of your `UICollectionViewCell` subclass, so it knows to use it.
var customCellClass: AnyClass
{
return CKCalendarCell.self
}
// Step 3. Implement the custom cell delegate callback
func calendarView(_ calendarView: CalendarView, willDisplay cell: UICollectionViewCell, in context: CalendarCellContext) {
// It's reasonable to cast to whatever class is in `customCellClass`.
guard let cell = cell as? CustomCalendarCell else
{
return
}
// Customize the cell's contents and display here.
}
}
现在,只需告诉日历视图您的对象正在提供自定义单元格
// 0. Assume an existing calendarView
// 1. Instantiate your custom cell provider.
let myCustomCellProvider = MyCustomCellProviderClass()
// 2. Assign the custom cell provider to the calendar view's customCellProvider.
calendarView.customCellProvider = myCustomCellProvider
那就对了。示例应用和迁移指南中提供了更多信息。
注意:在MBCalendarKit之前,单元格外观的自定义仅限于通过UIAppearance
访问的属性。这些UIAppearance
方法在MBCalendarKit 5.0.0中仍然可用。
如果您想知道单元格所代表的日期,或者单元格显示的范围,请查看上下文对象。CKCalendarCellContext
有几个有趣的属性。
要查看单元格表示的日期,请使用date
属性。
var date: Date
要查看单元格是否表示今天,是否超出月份,或者是否超出日历的最小和最大日期范围,请使用上下文的identifier
属性,它是CalendarCellContextIdentifier
的几个值之一。
var identifier: CKCalendarCellContextIdentifier
上下文标识符基于其他几个标志,这些标志也可在CalendarCellContext
上使用。更多信息请查看CocoaDocs生成的文档或类头文件。
CalendarEvent
是一个简单的数据结构类,它可以保留一个标题、一个日期和一个信息字典。日历视图将自动显示通过其数据源传入的CalendarEvent
对象。如果您想在详细视图中显示自定义信息,您可以将它附加到事件的info
属性。
从MBCalendarKit 2.1.0版本开始,还有一个color
属性。设置它将在单元格中显示一个彩色“标签”。目前这个功能应该被视为实验性质的。
版本2.2.0添加了对NSCalendar的firstWeekday
属性的支持。如果currentCalendar
(或您设置的任何日历)将除了周日以外的某天设置为一周的第一天,日历视图将尊重这一点。
/// Instantiate a CalendarViewController or CalendarView.
let calendarViewController = CKCalendarViewController()
/// Set the first day of the week to Monday.
calendarViewController.calendarView.firstWeekDay = 2
关于firstWeekday属性:使用整数1-7来设置从周日到周六的某一天。NSCalendar
没有说明如果使用其他数字会怎样,所以如果您这么做,请自行负责。
从MBCalendarKit 5.0.0版本开始,CalendarView
有一个animatesWeekTransitions
属性,可以打开以在周模式下启用动画过渡。
DeLong Dave,因为他的宝贵参考资料。感谢iOS Folks Slack团队在可空性上进行指导,并在处理浮点除法精度问题提供意见。
感谢各种贡献者对修补程序和问题报告的贡献。
点击此处了解如何贡献的更多信息。
MBCalendarKit遵循贡献者契约行为准则。在此阅读它。
根据MIT许可发布MBCalendarKit。有关详细信息,请参阅LICENSE。
如果喜欢MBCalendarKit,请查看我的其他项目