Skip to content

Instantly share code, notes, and snippets.

@bencochran
Last active December 22, 2015 05:58
Show Gist options
  • Save bencochran/6427385 to your computer and use it in GitHub Desktop.
Save bencochran/6427385 to your computer and use it in GitHub Desktop.
//
// MOAnnotatedCalendarView.h
// MOKit
//
// Created by Ben Cochran on 9/4/13.
// Copyright (c) 2013 Ben Cochran. All rights reserved.
//
#import "MOCalendarView.h"
@class MOAnnotatedCalendarView;
@class MOCalendarAnnotation;
@protocol MOAnnotatedCalendarViewDelegate <MOCalendarViewDelegate>
@optional
- (MOCalendarAnnotation *)annotatedCalendarView:(MOAnnotatedCalendarView *)annotatedCalendarView annotationForSelectedRange:(MOCalendarRange *)selection;
/**
* Called before an annotation is displayed.
*
* @param annotatedCalendarView
* The calendar in which the tool tip will be displayed
* @param annotation
* The annotation that will be displayed
* @param day
* The day on which the annotation will be displayed
*
* @return
* An annotation to be displayed. Return an `MOCalendarAnnotation` other
* than the one provided to modify the annotation content. Return `nil` to
* prevent any annotation from being displayed.
*/
- (MOCalendarAnnotation *)annotatedCalendarView:(MOAnnotatedCalendarView *)annotatedCalendarView shouldDisplayAnnotation:(MOCalendarAnnotation *)annotation fromDay:(NSDateComponents *)day;
- (void)annotatedCalendarView:(MOAnnotatedCalendarView *)annotatedCalendarView willDisplayAnnotation:(MOCalendarAnnotation *)annotation fromDay:(NSDateComponents *)day;
- (void)annotatedCalendarView:(MOAnnotatedCalendarView *)annotatedCalendarView didDisplayAnnotation:(MOCalendarAnnotation *)annotation fromDay:(NSDateComponents *)day;
//- (void)annotatedCalendarView:(MOAnnotatedCalendarView *)annotatedCalendarView willRemoveAnnotation:(MOCalendarAnnotation *)annotation fromDay:(NSDateComponents *)day
@end
@interface MOAnnotatedCalendarView : MOCalendarView
@property (nonatomic, weak) id<MOAnnotatedCalendarViewDelegate> delegate;
- (void)displayAnnotation:(MOCalendarAnnotation *)annotation fromDay:(NSDateComponents *)day animated:(BOOL)animated;
- (void)removeAnnotationAnimated:(BOOL)animated;
- (void)hideAnnotationAnimated:(BOOL)animated;
@end
//
// MOCalendarAnnotation.h
// MOKit
//
// Created by Ben Cochran on 9/4/13.
// Copyright (c) 2013 Ben Cochran. All rights reserved.
//
@interface MOCalendarAnnotation : NSObject
- (id)initWithTitle:(NSString *)title subtitle:(NSString *)subtitle;
@property (nonatomic, copy, readonly) NSString *title;
@property (nonatomic, copy, readonly) NSString *subtitle;
@end
//
// MOCalendarRange.h
// MOKit
//
// Created by Ben Cochran on 8/30/13.
// Copyright (c) 2013 Ben Cochran. All rights reserved.
//
@interface MOCalendarRange : NSObject <NSCopying, NSMutableCopying>
+ (instancetype)rangeWithCalendar:(NSCalendar *)calendar startDay:(NSDateComponents *)startDay endDay:(NSDateComponents *)endDay;
- (id)initWithCalendar:(NSCalendar *)calendar startDay:(NSDateComponents *)startDay endDay:(NSDateComponents *)endDay;
@property (nonatomic, strong, readonly) NSCalendar *calendar;
/**
* The starting day of the selection.
*
* ## Note
*
* `startDay` does not necessarily come before `endDay` in time. If you need
* that guarantee you should obtain a normalized copy of the range with
* `normalizedRange`
*
*/
@property (nonatomic, copy, readonly) NSDateComponents *startDay;
/**
* The ending day of the selection.
*
* @see Note on `startDay` for information about `startDay` and `endDay` ordering
*/
@property (nonatomic, copy, readonly) NSDateComponents *endDay;
/**
* Checks to see if the provided day is contained in the range.
*
* @param day The day to check. Must contain `NSCalendarUnitDay`, `NSCalendarUnitMonth` and `NSCalendarUnitYear`
* @param openEnded If `YES`, the check will treat `nil` `startDay` or `endDay` as a range with an infinite length in that direction.
*
* @return `YES` if the range contains the day, otherwise `NO`
*/
- (BOOL)containsDay:(NSDateComponents *)day openEnded:(BOOL)openEnded;
/**
* Checks to see if the provided month is valid for the range. This will return
* `YES` for any month that that overlaps with the selection at all. (e.g. a
* selection of 02-14-2013 to 12-01-2014 will return `YES` for `02-2013` and
* `12-2014` and every month in between, but no others)
*
* @param month The month to check. Must contain `NSCalendarUnitMonth` and `NSCalendarUnitYear`
* @param openEnded If `YES`, the check will treat `nil` `startDay` or `endDay` as a range with an infinite length in that direction.
*
* @return `YES` if the month contains any part of the range, otherwise `NO`
*/
- (BOOL)containsMonth:(NSDateComponents *)month openEnded:(BOOL)openEnded;
/**
* Returns a copy of the range where startDay and endDay are ordered temporally
*
* @return A copy of the range with startDay and endDay in order
*/
- (MOCalendarRange *)normalizedRange;
/**
* Returns the current length (number of days) of the range. If `startDay` or
* `endDay` or both are nil, the length is defined as 0.
*/
@property (nonatomic, readonly) NSInteger length;
@end
//
// MOCalendarView.h
// MOKit
//
// Created by Ben Cochran on 8/30/13.
// Copyright (c) 2013 Ben Cochran. All rights reserved.
//
@class MOMutableCalendarRange;
@class MOCalendarScrollView;
@class MOCalendarRange;
@class MOCalendarView;
extern NSCalendarUnit const MOCalendarUnitsDMY;
extern NSCalendarUnit const MOCalendarUnitsMY;
typedef NS_ENUM(NSUInteger, MOCalendarSelectionStyle) {
MOCalendarSelectionStyleSingleDay,
MOCalendarSelectionStyleMultiDay
};
@protocol MOCalendarViewDelegate <NSObject>
@optional
- (void)calendarView:(MOCalendarView *)calendarView willBeginChangingSelection:(MOCalendarRange *)newSelection;
- (void)calendarViewDidBeginChangingSelection:(MOCalendarView *)calendarView;
- (void)calendarView:(MOCalendarView *)calendarView willChangeSelection:(MOCalendarRange *)newSelection;
- (void)calendarViewDidChangeSelection:(MOCalendarView *)calendarView;
- (void)calendarView:(MOCalendarView *)calendarView willFinishChangingSelection:(MOCalendarRange *)newSelection;
- (void)calendarViewDidFinishChangingSelection:(MOCalendarView *)calendarView;
- (void)calendarView:(MOCalendarView *)calendarView willChangeToVisibleMonth:(NSDateComponents *)month;
- (void)calendarView:(MOCalendarView *)calendarView didChangeToVisibleMonth:(NSDateComponents *)month;
@end
@interface MOCalendarView : UIView
- (id)initWithCalendar:(NSCalendar *)calendar;
- (id)initWithFrame:(CGRect)frame calendar:(NSCalendar *)calendar;
@property (nonatomic, copy, readonly) NSCalendar *calendar;
@property (nonatomic, weak) id<MOCalendarViewDelegate> delegate;
/**
* The day to display highlighted as today. Defaults to the day returned by
* [NSDate date]
*/
@property (nonatomic, copy) NSDateComponents *today;
/**
* The range of dates to allow for selection. Additionally, the calendar will
* not allow the user to navigate to a month outside this range. If either
* the selection `startDay` or `endDay` are `nil` that direction will be
* unbounded.
*/
@property (nonatomic, copy) MOCalendarRange *validRange;
/**
* The selection style (single or multi-day).
*/
@property (nonatomic, assign) MOCalendarSelectionStyle selectionStyle;
/**
* The minimum length to allow for selection. The calendar will prevent
* dragging a selection shorter than this. Defaults to 0 (no minimum).
*/
@property (nonatomic, assign) NSInteger minimumSelectionLength;
/**
* The maximum length to allow for selection. The calendar will prevent
* dragging a selection longer than this. Defaults to `NSIntegerMax` (no
* maximum).
*/
@property (nonatomic, assign) NSInteger maximumSelectionLength;
/**
* The selected date range. This value is updated live while data selection is
* being dragged. Setting this value will update the display and call
* appropriate delegate methods.
*/
@property (nonatomic, copy) MOCalendarRange *selectedRange;
/**
* The currently-visible month.
*
* Setting this property to a date outside of `validRange` will cause no change
* to the calendar.
*/
@property (nonatomic, copy) NSDateComponents *visibleMonth;
- (void)setVisibleMonth:(NSDateComponents *)visibleMonth animated:(BOOL)animated;
/**
* A subclass of `MOCalendarHeaderView` (or `MOCalendarHeaderView` itself) to
* be used to draw the calendar header.
*/
@property (nonatomic, strong) Class headerClass;
/**
* A subclass of `MOCalendarDayView` (or `MOCalendarDayView` itself) to be used
* to draw the individual calendar days.
*/
@property (nonatomic, strong) Class dayViewClass;
/**
* The `NSDateFormatter` to be used to create weekday labels in the calendar
* header. Defaults to localized single-day labels (S, M, T, etc.).
*/
@property (nonatomic, strong) NSDateFormatter *weekdayLabelFormatter;
/**
* The `NSDateFormatter` to be used to display the current month in the
* calendar header. Defaults to localized month name and full year (e.g.
* “October 2013” in US_en).
*/
@property (nonatomic, strong) NSDateFormatter *currentMonthFormatter;
/**
* Returns the frame of given day in the receiver's coorinate space.
*
* @note This frame may be outside of the receiver's visible bounds
*
* @param day The day to find the frame of.
*
* @return
* The day's frame in the receiver's coorinate space or `CGRectZero` if the
* given day is not loaded in the calendar.
*/
- (CGRect)frameForDay:(NSDateComponents *)day;
// Methods for subclasses.
/**
* The `MOCalendarScrollView` being used internally to draw the calendar.
*/
@property (nonatomic, strong, readonly) MOCalendarScrollView *calendarScrollView;
/**
* Called before the calendar will change the visible month.
*
* @note Subclasses overriding the method must call super.
*
* @param month The month that will be displayed
*/
- (void)willChangeToVisibleMonth:(NSDateComponents *)month;
/**
* Called after the calendar has changed the visible month.
*
* @note Subclasses overriding the method must call super.
*
* @param month The month that was displayed
*/
- (void)didChangeToVisibleMonth:(NSDateComponents *)month;
/**
* Called when the user begins dragging a new selection. Subclasses may modify
* the selection by changing the properties of the provided
* `MOMutableCalendarRange`.
*
* @note Subclasses overriding the method must call super.
*
* @param month
* The selection that is beginning. Modifying the properties of the range
* will modify the selection.
*/
- (void)willBeginChangingSelection:(MOMutableCalendarRange *)newSelection;
/**
* Called after the user has begun dragging a new selection (after the
* selection has been modified and displayed).
*
* @note Subclasses overriding the method must call super.
*/
- (void)didBeginChangingSelection;
/**
* Called before the selection is changed either as a result of the user
* dragging the selection or when setting the selection programmatically.
* Subclasses may modify the selection by changing the properties of the
* provided `MOMutableCalendarRange`.
*
* @note Subclasses overriding the method must call super.
*
* @param month
* The selection that will be applied. Modifying the properties of the
* range will modify the selection.
*/
- (void)willChangeSelection:(MOMutableCalendarRange *)newSelection;
/**
* Called after the selection has changed either as a result of the user
* dragging or when setting the selection programmatically.
*
* @note Subclasses overriding the method must call super.
*/
- (void)didChangeSelection;
/**
* Called when the user finished dragging a selection. Subclasses may modify
* the selection by changing the properties of the provided
* `MOMutableCalendarRange`.
*
* @note Subclasses overriding the method must call super.
*
* @param month
* The selection that is finishing. Modifying the properties of the range
* will modify the selection.
*/
- (void)willFinishChangingSelection:(MOMutableCalendarRange *)newSelection;
/**
* Called after the user has finished dragging a new selection, after the
* selection has been modified and displayed.
*
* @note Subclasses overriding the method must call super.
*/
- (void)didFinishChangingSelection;
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment