JZCalendarWeekView 0.7.1

JZCalendarWeekView 0.7.1

Jeff Zhang 维护。



  • Jeff Zhang



Build Status CocoaPods Carthage compatible Platform Swift 5.0 license MIT

iOS Swift 日历周/日视图

灵感来自 WRCalendarView

特性

  • 每页 X 天(日视图:1 天,3 天视图,周视图:7 天)
  • 两种滚动类型:单日滚动(滚动一个部分)或页面滚动
  • 两种长按手势类型:添加新事件和移动现有事件
  • 事件在日历视图中显示(支持冲突时间的活动和跨越多天的事件)
  • 设置水平可滚动日期范围
  • 支持所有设备方向(包括 iPhone X 横屏)和 iPad(滑动和分割视图)
  • 自定义当前时间线
  • 全天活动

使用方法

ViewController

在您的 ViewController 中,您只需做几件事情。

  1. viewDidLoad 中设置自己的自定义 calendarWeekView
calendarWeekView.setupCalendar(numOfDays: 7,
                               setDate: Date(),
                               allEvents: JZWeekViewHelper.getIntraEventsByDate(originalEvents: events),
                               scrollType: .pageScroll,
                               firstDayOfWeek: .Monday)
  1. 重写 viewWillTransition 并在 JZWeekViewHelper 中调用 viewTransitionHandler 以支持所有设备方向
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    JZWeekViewHelper.viewTransitionHandler(to: size, weekView: calendarWeekView)
}
  1. viewDidLoad 中设置自己的自定义 flowLayout 样式(可选)
calendarWeekView.updateFlowLayout(JZWeekViewFlowLayout(hourHeight: 50, rowHeaderWidth: 50, columnHeaderHeight: 50, hourGridDivision: JZHourGridDivision.noneDiv))

JZBaseWeekView

创建自己的继承自 JZBaseWeekView 的 WeekView 类,并应该重写以下函数。

  1. 注册函数:在此处注册您自己的 UICollectionReusableView。(CollectionViewCell、SupplementaryView 或 DecorationView)
override func registerViewClasses() {
    super.registerViewClasses()

    // Register CollectionViewCell
    self.collectionView.register(UINib(nibName: "EventCell", bundle: nil), forCellWithReuseIdentifier: "EventCell")

    // Register DecorationView: must provide corresponding JZDecorationViewKinds
    self.flowLayout.register(BlackGridLine.self, forDecorationViewOfKind: JZDecorationViewKinds.verticalGridline)
    self.flowLayout.register(BlackGridLine.self, forDecorationViewOfKind: JZDecorationViewKinds.horizontalGridline)

    // Register SupplementrayView: must override collectionView viewForSupplementaryElementOfKind
    collectionView.register(RowHeader.self, forSupplementaryViewOfKind: JZSupplementaryViewKinds.rowHeader, withReuseIdentifier: "RowHeader")
}

如果您想使用您自己的补充视图(包括您当前的时序),您应该注册它并重写以下函数

override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView
  1. CollectionView 的 cellForItemAt 方法:使用您自定义的 collectionViewCell
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let date = flowLayout.dateForColumnHeader(at: indexPath)
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: EventCell.className, for: indexPath) as! EventCell
    cell.updateView(event: allEventsBySection[date]![indexPath.row] as! Event)
    return cell
}

JZLongPressView

此视图继承自 JZBaseWeekView 并实现了长按手势。您可以简单地遵循 JZBaseWeekView 的设置规则。
为了实现长按手势,您应在您的 ViewController 中实现 JZLongPressViewDelegateJZLongPressViewDataSource

public protocol JZLongPressViewDelegate: class {
    /// When addNew long press gesture ends, this function will be called.
    func weekView(_ weekView: JZLongPressWeekView, didEndAddNewLongPressAt startDate: Date)
    /// When Move long press gesture ends, this function will be called.
    func weekView(_ weekView: JZLongPressWeekView, editingEvent: JZBaseEvent, didEndMoveLongPressAt startDate: Date)
    /// Sometimes the longPress will be cancelled because some curtain reason.
    func weekView(_ weekView: JZLongPressWeekView, longPressType: JZLongPressWeekView.LongPressType, didCancelLongPressAt startDate: Date)
}

public protocol JZLongPressViewDataSource: class {
    /// Implement this function to customise your own AddNew longPressView
    func weekView(_ weekView: JZLongPressWeekView, viewForAddNewLongPressAt startDate: Date) -> UIView
    /// Implement this function to customise your own Move longPressView
    func weekView(_ weekView: JZLongPressWeekView, movingCell: UICollectionViewCell, viewForMoveLongPressAt startDate: Date) -> UIView
}

您还需要提供长按类型,还有其他一些可以更改的属性。

calendarWeekView.longPressDelegate = self
calendarWeekView.longPressDataSource = self
calendarWeekView.longPressTypes = [.addNew, .move]

// Optional
calendarWeekView.addNewDurationMins = 120
calendarWeekView.moveTimeMinInterval = 15

如果您想使用 move 类型的长按,您必须从 JZLongPressEventCell 继承您的 UICollectionViewCell 以允许检索编辑 JZBaseEvent,因为存在 UICollectionView 重用问题。记得设置您的细胞 backgroundColor 在细胞 contentView 中。

JZBaseEvent

在 JZCalendarWeekView 中,数据模型使用 [Date: [Event]] 字典,因为对于每一天(collectionView中的一个部分),可能会有一些事件。

JZWeekViewHelper 中提供的静态函数 getIntraEventsByDate 允许您将事件列表转换为 [Date: [Event]] 字典。

open class func getIntraEventsByDate<T: JZBaseEvent>(originalEvents: [T]) -> [Date: [T]]

为了调用此函数,您应该创建一个 JZBaseEvent 的子类,并实现 NSCopying 协议。
JZBaseEvent 中的 intraStartDateintraEndDate 的含义是,如果一个事件跨越两天,则应将其分割成两个事件,但有不同的 intraStartDateintraEndDate
例如,起始日期 = 180329 14:00,结束日期 = 180330 03:00,则应生成两个事件:1. 180329 14:00(内部起始) - 23:59(内部结束) 2. 180330 00:00(内部起始) - 03:00(内部结束)

全天事件

全天功能旨在单独显示全天事件,但只有标记为 isAllDay 为 true 的事件才能显示。对于跨越几天的 evento 建议保持 isAllDay 为 false。(参考 Apple Calendar & Google Calendar)
为了激活全天功能,您只需做两件事。

  1. JZAllDayEvent 继承您的事件类,以确保添加 isAllDay 变量。
  2. 在您自定义的 CalendarViewWeekView 中,重写 viewForSupplementaryElementOfKind 并使用 updateViewAllDayHeader 中更新您全天视图,使用您自己的视图。示例

水平可滚动范围

水平可滚动范围日期允许您设置您首选的可滚动范围。CalendarWeekView只能从startDate(包含)横向滚动到endDate(包含)。nil表示无限制。

  1. 您可以在调用setupCalendar()时设置scrollableRange,或者简单更改此变量。
  2. 如果您在未调用forceReload()的情况下更改scrollType,您应调用setHorizontalEdgesOffsetX()来重置边缘,因为对于不同的滚动类型,边缘是不同的。

对于进一步使用,您也可以查看示例项目,一些代码注释,或者直接给我发邮件。

要求

  • iOS 9.0+
  • Xcode 10+
  • Swift 4.2

安装

CocoaPods

JZCalendarWeekView可以通过将以下行添加到您的Podfile中添加到您的项目中

# Latest release in CocoaPods (recommend to use latest version before v1.0.0 release, optional: provide version number)
pod 'JZCalendarWeekView'

Carthage

JZCalendarWeekView 可以通过在您的 Cartfile 中添加以下行添加到您的项目中:

# Latest release on Carthage (recommend to use latest version before v1.0.0 release, optional: provide version number)
github "zjfjack/JZCalendarWeekView"

Todo

  • 用于不同背景视图的装饰视图(参考 #12)
  • 日期范围限制:日历视图中的开始时间和结束时间(垂直)
  • 主题实现
  • 新滚动类型:无限滚动
  • 支持不同类型的事件排列规则

作者

Jeff Zhang, [email protected]
如果您有任何问题和建议,请随时联系我。

许可协议

JZCalendarWeekView 在 MIT 许可协议下可用。有关更多信息,请参阅 LICENSE