MBCalendarKit 5.1.0

MBCalendarKit 5.1.0

测试已测试
语言语言 Obj-CObjective C
许可证 MIT
发布上次发布2017年9月

Moshe Berman 维护。




  • 作者
  • Moshe Berman

关于

MBCalendarKit 是一个考虑了现代最佳实践和 Swift 互操作性的 Objective-C 编写的日历控件。

它提供了灵活的日历控件,支持显示由 NSCalendar 支持的任何日历系统。它还包括一个用于自定义日历单元格的 API。它还附带了一个由原始 iOS 日历启发的预构建视图控制器。

特性

  • 交互式日历控件
  • 自动布局支持
  • 适用于 iOS 8 及更高版本的动态框架
  • 带默认实现的自定义单元格 API
  • 显示日历事件
  • 自定义第一周的第一天
  • 将日期限制在最小/最大值内
  • 显示任何区域或日历标识符
  • 显示模式:月、周和日
  • 支持本地化,包括从右向左和日期格式
  • 灵感来源于原始 iOS 日历应用的预构建视图控制器
  • 包含各种示例实现的示例应用程序

入门

您需要针对 iOS 8 及更高版本。有三种方法可以集成 MBCalendarKit:

  1. Cocoapods: pod 'MBCalendarKit', '~> 5.0.0'
  2. 将此 Xcode 项目拖到自己的项目中,并将框架作为依赖项添加。
  3. 如果您确实想拖入原始源代码,框架代码在 MBCalendarKit/CalendarKit

如果遇到任何问题,请前往问题 #48 并留下意见。

Swift 和 Objective-C

MBCalendarKit 使用 Objective-C 编写。要与 Swift 一起使用 MBCalendarKit,只需将其链接起来并使用 import MBCalendarKit。MBCalendarKit 5.0.0 包含了多项 Swift 增强。

这里的示例使用 Swift 编写,以简化说明。请注意,在编写 Objective-C 时,MBCalendarKit 使用 CK 作为其类和枚举的前缀。CalendarView 在 Swift 中是 CKCalendarView,等等。

具体信息,请参阅 迁移指南

特性

显示日历

您有两个选择使用 MBCalendarKit 显示日历。

  1. 您可以显示一个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
  1. 您的第二个选项是创建一个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)
		

使用CalenderViewCalendarViewController,您可以通过使用dataSourcedelegate属性来显示事件,并获得有关用户交互的信息。


注意:在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
}

注意:用作键的日期必须与数据源方法传入的日期完全匹配。确保这一点的常见方法是使用NSCalendarisDate:equalToDate:toUnitGranularity:,传入两个日期和作为第三个参数的.day,以创建传递给事件的对象。

您还可以在示例应用的CKDemoViewController.mSwiftDemoViewController.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,请查看我的其他项目