这是一个易于使用的日历组件,类似于“直接拖放至代码中”的类型,适用于iOS。它支持垂直和水平滚动,以及原生日历事件。
要求
- iOS 8.0+
- XCode 9.0+
- Swift 4.2
安装
CocoaPods
pod 'KDCalendar', '~> 1.8.9'
Carthage
将以下内容添加到Cartfile中,然后运行carthage update
github "mmick66/CalendarView" "master"
Swift Package Manager
转到“项目”->“Swift Packages”并添加仓库
https://github.com/mmick66/CalendarView.git
将以下内容添加到您的Package.swift
dependencies: [
.Package(url: "https://github.com/mmick66/CalendarView")
]
请访问
手册只需将CalendarView/子文件夹中的文件添加到项目中。
请访问
设置日历是一个UIView
,可以通过编程或通过XIB/Storyboard添加。如果使用后者,请确保选择模块为'KDCalendar'。
它需要一个符合以下要求的代理和数据源。
protocol CalendarViewDataSource {
func startDate() -> NSDate // UTC Date
func endDate() -> NSDate // UTC Date
}
protocol CalendarViewDelegate {
func calendar(_ calendar : CalendarView, canSelectDate date : Date) -> Bool /* optional */
func calendar(_ calendar : CalendarView, didScrollToMonth date : Date) -> Void
func calendar(_ calendar : CalendarView, didSelectDate date : Date, withEvents events: [CalendarEvent]) -> Void
func calendar(_ calendar : CalendarView, didDeselectDate date : Date) -> Void /* optional */
func calendar(_ calendar : CalendarView, didLongPressDate date : Date, withEvents events: [CalendarEvent]?) -> Void /* optional */
}
数据源将提供日历的开始日期和结束日期。方法有一个默认实现,它将返回Date()
,这将导致显示当前月份的单页日历。
代理将对滚动和选择特定日期等事件做出响应。
注意:日期应使用UTC(与GMT相同)。
请访问
如何使用您可以在视觉效果示例中实现的视图控制器中实现代理函数。
例如,您希望滚动3个月以前,那么
func startDate() -> Date {
var dateComponents = DateComponents()
dateComponents.month = -3
let today = Date()
let threeMonthsAgo = self.calendarView.calendar.date(byAdding: dateComponents, to: today)
return threeMonthsAgo
}
您可能仍然希望日历从今天的日期打开,在这种情况下,请这样做
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let today = Date()
self.calendarView.setDisplayDate(today, animated: false)
}
例如,您可能想选择明天
// can be in the viewDidAppear
let today = Date()
if let tomorrow = self.calendarView.calendar.date(byAdding: tomorrowComponents, to: today) {
self.calendarView.selectDate(tomorrow)
}
请访问
选择和取消选择日期日历支持选择多个日期。您可以通过单击单元格或通过编程选择它来选择日期。
self.calendarView.selectDate(date)
同样,您可以取消选择它。
self.calendarView.deselectDate(date)
您可以使用以下方法获取所有已选择的日期,无论是手动还是通过编程:
self.calendarView.selectedDates
请访问
布局该日历支持两种基本布局。将 direction
属性设置为 .horizontal
或 .vertical
calendarView.direction = .horizontal
样式
可以使用 CalendarView.Style
结构设置此日历的外观。有一个“预装”的样式,可以通过 CalendarView.Style.Default
静态访问。要修改它,请实例化一个新的样式对象,并在代码中的任何位置设置所需的变量。
override func viewDidLoad() {
super.viewDidLoad()
let myStyle = CalendarView.Style()
// set your values
calendarView.style = myStyle
}
有关更多信息,请参阅我们的 wiki。
标记周末
某些日历可能会将周末显示为特殊,并使用不同的文本颜色进行标记。为此,首先在 calendarView 本身上设置 marksWeekends 变量,并(可选)定义要使用的颜色。
CalendarView.Style.cellTextColorWeekend = UIColor.red
calendarView.marksWeekends = true
CellShape
将定义日期是以圆形、方形还是斜边显示。
淡化天数
如果您想让位于 startDate
和 endDate
范围之外的天数变暗,您可以在
CalendarView.Style.cellColorOutOfRange = UIColor(white: 0.0, alpha: 0.5)
一周的第一天
根据文化,一周可能从周一或周日开始。要更改天数的显示方式,请使用
CalendarView.Style.firstWeekday = .sunday
日历默认为周一,这在欧洲是标准。
设置日历区域设置
设置周头部和月份标签的本地化设置。使用
CalendarView.Style.locale = Locale(identifier: "en_US")
默认的本地化为设备上的 Locale.current。
自定义标题
根据语言的设置,你可能会在标题中遇到月份字符串显示问题。但是,你可以采用一种方法,根据传入的日期返回任何你想要的字符串。
public protocol CalendarViewDataSource {
/* other methods */
func headerString(_ date: Date) -> String?
}
事件
该组件能够从系统的EKEventStore
同步事件,这是与iOS中提供的原生日历共享的。这个功能是可选的,并需要通过构建设置中的自定义标志单独激活,以保持日历的占用空间小,如下所示
在"构建设置"中,"Swift编译器 - 自定义标志"和"活跃编译条件"下,只需为调试和发布都添加KDCALENDAR_EVENT_MANAGER_ENABLED
标志。这样就启用了事件。
加载事件
要从系统的日历加载事件,请调用以下方法
self.calendarView.loadEvents()
可选地,可以添加一个完整处理程序,以防返回错误
self.calendarView.loadEvents() { error in
if error != nil {
// handle error
}
}
代码将弹出一个警告视图,询问用户是否允许此应用程序访问日历。如果提供了访问权限,我们将事件传递给CalendarView
,否则我们得到一个nil,并通知应用程序拒绝。
创建(添加)新事件
有一个允许你在日历中添加新事件的功能。它目前仅限于一天(就像日历中的其他部分一样)
func addEvent(_ title: String, date: Date, duration hours: NSInteger = 1) -> Bool
为了检测用户想要添加新日期的情况,委托可以实现didLongPressDate
方法来通知控制器长按事件,并且通常使用addEvent
函数与这个委托方法结合使用。
目前,本repo的示例实现将打开一个警告视图,提示用户输入事件的标题,并设置为小时的持续时间。可以添加更多自定义控件来进一步细化选择。
和加载事件一样,我们需要给应用程序特定的权限。
关于日期
计算日期可能会有些复杂,因为虽然时间是绝对值,但日期是文化的产物:时区是具有地理政治意义的区域,夏令时是根据政府决策变化的。最好的解决办法是将所有内容都计算为UTC时间(对我们而言等同于GMT),因此委托方返回的startDate
和endDate
都应该以UTC时间(+0000)表示。
需要帮助
如果您想做出贡献,总有一些标记为增强功能的开放性问题在问题标签中。任何帮助都欢迎。