Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Example/JZCalendarWeekViewExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -518,11 +518,11 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = XRYH9M2JN7;
DEVELOPMENT_TEAM = L85MD8WTSB;
INFOPLIST_FILE = "$(SRCROOT)/JZCalendarWeekViewExample/Supporting Files/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.zjfjack.JZCalendarWeekViewExample;
PRODUCT_BUNDLE_IDENTIFIER = com.midrive.JZCalendarWeekViewExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
Expand All @@ -535,11 +535,11 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = XRYH9M2JN7;
DEVELOPMENT_TEAM = L85MD8WTSB;
INFOPLIST_FILE = "$(SRCROOT)/JZCalendarWeekViewExample/Supporting Files/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.zjfjack.JZCalendarWeekViewExample;
PRODUCT_BUNDLE_IDENTIFIER = com.midrive.JZCalendarWeekViewExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
Expand Down
6 changes: 3 additions & 3 deletions JZCalendarWeekView.podspec
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
Pod::Spec.new do |s|
s.name = "JZCalendarWeekView"
s.version = "0.7.1"
s.version = "0.7.3"
s.summary = "Calendar Week & Day View in iOS Swift"
s.homepage = "https://github.com/zjfjack/JZCalendarWeekView"
s.homepage = "https://github.com/midrive/JZCalendarWeekView"
s.license = { :type => "MIT", :file => "LICENSE" }
s.author = { "Jeff Zhang" => "[email protected]" }
s.platform = :ios, "9.0"
s.source = { :git => "https://github.com/zjfjack/JZCalendarWeekView.git", :tag => s.version }
s.source = { :git => "https://github.com/fawxy/JZCalendarWeekView.git", :tag => s.version }
s.source_files = "JZCalendarWeekView/**/*.swift"
end
50 changes: 29 additions & 21 deletions JZCalendarWeekView/JZBaseWeekView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ open class JZBaseWeekView: UIView {
(numOfDays) days before current page first date, which means the start of the collectionView, not the current page first date
- The core structure of JZCalendarWeekView is 3 pages, previous-current-next
- If you want to update this value instead of using [updateWeekView(to date: Date)](), please **make sure the date is startOfDay**.
*/
*/
public var initDate: Date! {
didSet {
baseDelegate?.initDateDidChange(self, initDate: initDate)
Expand Down Expand Up @@ -144,17 +144,17 @@ open class JZBaseWeekView: UIView {

/**
Basic Setup method for JZCalendarWeekView,it **must** be called.

- Parameters:
- numOfDays: Number of days in a page
- setDate: The initial set date, the first date in current page except WeekView (numOfDays = 7)
- allEvents: The dictionary of all the events for present. JZWeekViewHelper.getIntraEventsByDate can help transform the data
- firstDayOfWeek: First day of a week, **only works when numOfDays is 7**. Default value is Sunday
- scrollType: The horizontal scroll type for this view. Default value is pageScroll
- currentTimelineType: The current time line type for this view. Default value is section
- visibleTime: WeekView will be scroll to this time, when it appears the **first time**. This visibleTime only determines **y** offset. Defaut value is current time.
- scrollableRange: The scrollable area for this weekView, both start and end dates are included, set nil as unlimited in one side
*/
- numOfDays: Number of days in a page
- setDate: The initial set date, the first date in current page except WeekView (numOfDays = 7)
- allEvents: The dictionary of all the events for present. JZWeekViewHelper.getIntraEventsByDate can help transform the data
- firstDayOfWeek: First day of a week, **only works when numOfDays is 7**. Default value is Sunday
- scrollType: The horizontal scroll type for this view. Default value is pageScroll
- currentTimelineType: The current time line type for this view. Default value is section
- visibleTime: WeekView will be scroll to this time, when it appears the **first time**. This visibleTime only determines **y** offset. Defaut value is current time.
- scrollableRange: The scrollable area for this weekView, both start and end dates are included, set nil as unlimited in one side
*/
open func setupCalendar(numOfDays: Int,
setDate: Date,
allEvents: [Date: [JZBaseEvent]],
Expand Down Expand Up @@ -330,11 +330,15 @@ open class JZBaseWeekView: UIView {
return dates
}

open func selectedItemAt(indexPath: IndexPath) {

}

/**
Used to Refresh the weekView when viewWillTransition
**Must override viewWillTransition in the ViewController and call this function**
*/
Used to Refresh the weekView when viewWillTransition

**Must override viewWillTransition in the ViewController and call this function**
*/
open func refreshWeekView() {
updateWeekView(to: self.initDate.add(component: .day, value: numOfDays))
}
Expand All @@ -358,7 +362,7 @@ open class JZBaseWeekView: UIView {

/**
Get date excluding time from **collectionView contentOffset only** rather than gesture point in collectionView
- Parameter contentOffsetX: collectionView contentOffset x
- Parameter contentOffsetX: collectionView contentOffset x
*/
open func getDateForContentOffsetX(_ contentOffsetX: CGFloat) -> Date {
let adjustedX = contentOffsetX - flowLayout.contentsMargin.left
Expand All @@ -368,7 +372,7 @@ open class JZBaseWeekView: UIView {

/**
Get time excluding date from **collectionView contentOffset only** rather than gesture point in collectionView
- Parameter contentOffsetY: collectionView contentOffset y
- Parameter contentOffsetY: collectionView contentOffset y
*/
open func getDateForContentOffsetY(_ contentOffsetY: CGFloat) -> (hour: Int, minute: Int) {
var adjustedY = contentOffsetY - flowLayout.contentsMargin.top
Expand All @@ -380,7 +384,7 @@ open class JZBaseWeekView: UIView {

/**
Get full date from **collectionView contentOffset only** rather than gesture point in collectionView
- Parameter contentOffset: collectionView contentOffset
- Parameter contentOffset: collectionView contentOffset
*/
open func getDateForContentOffset(_ contentOffset: CGPoint) -> Date {
let yearMonthDay = getDateForContentOffsetX(contentOffset.x)
Expand All @@ -390,7 +394,7 @@ open class JZBaseWeekView: UIView {

/**
Get date excluding time from **gesture point in collectionView only** rather than collectionView contentOffset
- Parameter xCollectionView: gesture point x in collectionView
- Parameter xCollectionView: gesture point x in collectionView
*/
open func getDateForPointX(_ xCollectionView: CGFloat) -> Date {
// RowHeader(horizontal UICollectionReusableView) should be considered in gesture point
Expand All @@ -402,7 +406,7 @@ open class JZBaseWeekView: UIView {

/**
Get time excluding date from **gesture point in collectionView only** rather than collectionView contentOffset
- Parameter yCollectionView: gesture point y in collectionView
- Parameter yCollectionView: gesture point y in collectionView
*/
open func getDateForPointY(_ yCollectionView: CGFloat) -> (hour: Int, minute: Int) {
// ColumnHeader and AllDayHeader(vertical UICollectionReusableView) should be considered in gesture point
Expand All @@ -418,7 +422,7 @@ open class JZBaseWeekView: UIView {

/**
Get full date from **gesture point in collectionView only** rather than collectionView contentOffset
- Parameter point: gesture point in collectionView
- Parameter point: gesture point in collectionView
*/
open func getDateForPoint(_ point: CGPoint) -> Date {
let yearMonthDay = getDateForPointX(point.x)
Expand Down Expand Up @@ -529,6 +533,10 @@ extension JZBaseWeekView: UICollectionViewDelegate, UICollectionViewDelegateFlow
self.endOfScroll()
}

open func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.selectedItemAt(indexPath: indexPath)
}

/// Some actions need to be done when scroll ends
private func endOfScroll() {
// vertical scroll should not load page, handled in loadPage method
Expand Down
56 changes: 42 additions & 14 deletions JZCalendarWeekView/JZLongPressWeekView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ public protocol JZLongPressViewDelegate: class {
/// - startDate: the startDate of the event when gesture ends
func weekView(_ weekView: JZLongPressWeekView, editingEvent: JZBaseEvent, didEndMoveLongPressAt startDate: Date)

/// When Custom long press gesture begins on an , this function will be called.
/// Use this function to perform actions when a use long presses on an existing event
/// - Parameters:
/// - weekView: current long pressed JZLongPressWeekView
/// - cell: current long pressed JZLongPressEventCell
func weekView(_ weekView: JZLongPressWeekView, didBeginLongPressOn cell: JZLongPressEventCell)

/// Sometimes the longPress will be cancelled because some curtain reason.
/// Normally this function no need to be implemented.
/// - Parameters:
Expand Down Expand Up @@ -57,6 +64,7 @@ extension JZLongPressViewDelegate {
public func weekView(_ weekView: JZLongPressWeekView, longPressType: JZLongPressWeekView.LongPressType, didCancelLongPressAt startDate: Date) {}
public func weekView(_ weekView: JZLongPressWeekView, didEndAddNewLongPressAt startDate: Date) {}
public func weekView(_ weekView: JZLongPressWeekView, editingEvent: JZBaseEvent, didEndMoveLongPressAt startDate: Date) {}
public func weekView(_ weekView: JZLongPressWeekView, didBeginLongPressOn cell: JZLongPressEventCell) {}
}

extension JZLongPressViewDataSource {
Expand All @@ -78,6 +86,8 @@ open class JZLongPressWeekView: JZBaseWeekView {
case addNew
/// when long press position is on a existed event, this type will allow user to move the existed event
case move
// Custom event to implement functionality besides move when long press on an existing event
case custom
}

/// This structure is used to save editing information before reusing collectionViewCell (Type Move used only)
Expand Down Expand Up @@ -271,7 +281,7 @@ open class JZLongPressWeekView: JZBaseWeekView {
open func initLongPressView(selectedCell: UICollectionViewCell?, type: LongPressType, startDate: Date) -> UIView {

let longPressView = type == .move ? longPressDataSource!.weekView(self, movingCell: selectedCell!, viewForMoveLongPressAt: startDate) :
longPressDataSource!.weekView(self, viewForAddNewLongPressAt: startDate)
longPressDataSource!.weekView(self, viewForAddNewLongPressAt: startDate)
longPressView.clipsToBounds = false

// timeText width will change from 00:00 - 24:00, and for each time the length will be different
Expand Down Expand Up @@ -371,12 +381,16 @@ extension JZLongPressWeekView: UIGestureRecognizerDelegate {
if gestureRecognizer.state == .possible {
// Long press on ouside margin area should not begin
let isOutsideBeginArea = pointInSelfView.x < longPressLeftMarginX || pointInSelfView.x > longPressRightMarginX ||
pointInSelfView.y < longPressTopMarginY || pointInSelfView.y > longPressBottomMarginY
pointInSelfView.y < longPressTopMarginY || pointInSelfView.y > longPressBottomMarginY
if isOutsideBeginArea { return false }
}

let hasItemAtPoint = collectionView.indexPathForItem(at: pointInCollectionView) != nil

if hasItemAtPoint && longPressTypes.contains(LongPressType.custom) {
return true
}

// Long press should not begin if there are events at long press position and move not required
if hasItemAtPoint && !longPressTypes.contains(LongPressType.move) {
return false
Expand All @@ -400,19 +414,37 @@ extension JZLongPressWeekView: UIGestureRecognizerDelegate {
let pointInCollectionView = gestureRecognizer.location(in: collectionView)

let state = gestureRecognizer.state
var currentMovingCell: UICollectionViewCell!

var currentLongPressCell: UICollectionViewCell!

if isLongPressing == false {
if let indexPath = collectionView.indexPathForItem(at: pointInCollectionView) {
// Can add some conditions for allowing only few types of cells can be moved
currentLongPressType = .move
currentMovingCell = collectionView.cellForItem(at: indexPath)
if longPressTypes.contains(.move) {
currentLongPressType = .move
currentLongPressCell = collectionView.cellForItem(at: indexPath)
} else if longPressTypes.contains(.custom) {
currentLongPressType = .custom
currentLongPressCell = collectionView.cellForItem(at: indexPath)
}
} else {
currentLongPressType = .addNew
}
isLongPressing = true
}

if currentLongPressType == .custom {
if state == .began {
longPressDelegate?.weekView(self, didBeginLongPressOn: currentLongPressCell as! JZLongPressEventCell)
return
} else if state == .ended || state == .cancelled {
isLongPressing = false
return
} else {
return
}
}

// The startDate of the longPressView (the date of top Y in longPressView)
var longPressViewStartDate: Date!

Expand All @@ -422,20 +454,20 @@ extension JZLongPressWeekView: UIGestureRecognizerDelegate {
}

if state == .began {
currentEditingInfo.cellSize = currentLongPressType == .move ? currentLongPressCell.frame.size : CGSize(width: flowLayout.sectionWidth, height: flowLayout.hourHeight * CGFloat(addNewDurationMins)/60)
pressPosition = currentLongPressType == .move ? (pointInCollectionView.x - currentLongPressCell.frame.origin.x, pointInCollectionView.y - currentLongPressCell.frame.origin.y) : (currentEditingInfo.cellSize.width/2, currentEditingInfo.cellSize.height/2)

currentEditingInfo.cellSize = currentLongPressType == .move ? currentMovingCell.frame.size : CGSize(width: flowLayout.sectionWidth, height: flowLayout.hourHeight * CGFloat(addNewDurationMins)/60)
pressPosition = currentLongPressType == .move ? (pointInCollectionView.x - currentMovingCell.frame.origin.x, pointInCollectionView.y - currentMovingCell.frame.origin.y) :
(currentEditingInfo.cellSize.width/2, currentEditingInfo.cellSize.height/2)
longPressViewStartDate = getLongPressViewStartDate(pointInCollectionView: pointInCollectionView, pointInSelfView: pointInSelfView)
longPressView = initLongPressView(selectedCell: currentMovingCell, type: currentLongPressType, startDate: longPressViewStartDate)
longPressView = initLongPressView(selectedCell: currentLongPressCell, type: currentLongPressType, startDate: longPressViewStartDate)
longPressView.frame.size = currentEditingInfo.cellSize
longPressView.transform = CGAffineTransform(scaleX: 0.1, y: 0.1)
self.addSubview(longPressView)

longPressView.center = CGPoint(x: pointInSelfView.x - pressPosition!.xToViewLeft + currentEditingInfo.cellSize.width/2,
y: pointInSelfView.y - pressPosition!.yToViewTop + currentEditingInfo.cellSize.height/2)

if currentLongPressType == .move {
currentEditingInfo.event = (currentMovingCell as! JZLongPressEventCell).event
currentEditingInfo.event = (currentLongPressCell as! JZLongPressEventCell).event
getCurrentMovingCells().forEach {
$0.contentView.layer.opacity = movingCellOpacity
currentEditingInfo.allOpacityContentViews.append($0.contentView)
Expand All @@ -449,18 +481,14 @@ extension JZLongPressWeekView: UIGestureRecognizerDelegate {
let topYPoint = max(pointInSelfView.y - pressPosition!.yToViewTop, longPressTopMarginY)
longPressView.center = CGPoint(x: pointInSelfView.x - pressPosition!.xToViewLeft + currentEditingInfo.cellSize.width/2,
y: topYPoint + currentEditingInfo.cellSize.height/2)

} else if state == .cancelled {

UIView.animate(withDuration: 0.3, delay: 0.0, options: .curveEaseOut, animations: {
self.longPressView.alpha = 0
}, completion: { _ in
self.longPressView.removeFromSuperview()
})
longPressDelegate?.weekView(self, longPressType: currentLongPressType, didCancelLongPressAt: longPressViewStartDate)

} else if state == .ended {

self.longPressView.removeFromSuperview()
if currentLongPressType == .addNew {
longPressDelegate?.weekView(self, didEndAddNewLongPressAt: longPressViewStartDate)
Expand Down
1 change: 0 additions & 1 deletion JZCalendarWeekView/JZWeekViewFlowLayout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ open class JZWeekViewFlowLayout: UICollectionViewFlowLayout {
let height = hourHeight * 24 // statement too long for Swift 5 compiler
return columnHeaderHeight + height + contentsMargin.top + contentsMargin.bottom + allDayHeaderHeight
}

let minOverlayZ = 1000 // Allows for 900 items in a section without z overlap issues
let minCellZ = 100 // Allows for 100 items in a section's background
let minBackgroundZ = 0
Expand Down
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ public protocol JZLongPressViewDelegate: class {
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)
/// When an event is long pressed on, this function will be called.
func weekView(_ weekView: JZLongPressWeekView, didBeginLongPressOn cell: JZLongPressEventCell)
/// Sometimes the longPress will be cancelled because some curtain reason.
func weekView(_ weekView: JZLongPressWeekView, longPressType: JZLongPressWeekView.LongPressType, didCancelLongPressAt startDate: Date)
}
Expand All @@ -110,10 +112,10 @@ public protocol JZLongPressViewDataSource: class {
```
Also, you should provide the long press types and there are some other properties you can change.

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

// Optional
calendarWeekView.addNewDurationMins = 120
Expand All @@ -126,7 +128,7 @@ If you want to use the `move` type long press, you have to inherit your `UIColle
In JZCalendarWeekView, the data model is using `[Date: [Event]]` dictionary because for each day (a section in collectionView), there might be some events. <br />

A static function called `getIntraEventsByDate` provided in `JZWeekViewHelper` allow you to tranform your events list into `[Date: [Event]]` dictionary.
```swift
```swift
open class func getIntraEventsByDate<T: JZBaseEvent>(originalEvents: [T]) -> [Date: [T]]
```
In order to call this function, you should create a subclass of `JZBaseEvent` and also implement the `NSCopying` protocol. <br />
Expand Down Expand Up @@ -192,6 +194,3 @@ If you have any questions and suggestions, feel free to contact me.
## License

JZCalendarWeekView is available under the MIT license. See the [LICENSE](https://github.com/zjfjack/JZCalendarWeekView/blob/master/LICENSE) for more info.