diff --git a/PMCalendar/Theme/apple calendar.plist b/PMCalendar/Theme/apple calendar.plist index 6543aaf..279a2a0 100644 --- a/PMCalendar/Theme/apple calendar.plist +++ b/PMCalendar/Theme/apple calendar.plist @@ -9,10 +9,10 @@ Width 320 Height - 310 + 309 Header height - 46 + 45 Outer padding Height @@ -45,21 +45,6 @@ Background - grad - - - Color - 226,226,228 - Position - 0 - - - Color - 204,203,208 - Position - 1 - - Color background.png Shadow @@ -69,12 +54,12 @@ Offset Width - 1 + 0 Height 1 Blur radius - 2 + 9 @@ -160,6 +145,8 @@ 115,137,165 Shadow + Type + inner Color 0,0,0 Offset @@ -182,11 +169,11 @@ Insets Top - -2 + -1 Left -1 Bottom - 1 + 0 Right 0 @@ -226,6 +213,8 @@ 25,128,229 Shadow + Type + inner Color 0,0,0 Offset @@ -248,11 +237,11 @@ Insets Top - -2 + -1 Left -1 Bottom - 1 + 0 Right 0 @@ -528,11 +517,11 @@ Insets Top - -2 + -1 Left -1 Bottom - 1 + 0 Right 0 diff --git a/PMCalendar/Theme/background.png b/PMCalendar/Theme/background.png index f40ee78..c61697b 100644 Binary files a/PMCalendar/Theme/background.png and b/PMCalendar/Theme/background.png differ diff --git a/PMCalendar/Theme/background@2x.png b/PMCalendar/Theme/background@2x.png index 9c8892f..e758bbe 100644 Binary files a/PMCalendar/Theme/background@2x.png and b/PMCalendar/Theme/background@2x.png differ diff --git a/PMCalendar/Theme/default.plist b/PMCalendar/Theme/default.plist index 3ab99a0..afb178c 100644 --- a/PMCalendar/Theme/default.plist +++ b/PMCalendar/Theme/default.plist @@ -318,20 +318,20 @@ Bottom 2 Right - 3 + 4 Shadow Blur radius - 5 + 3 Color 0,0,0 Offset Width - 2 + 1 Height - 3 + 1 diff --git a/PMCalendar/src/NSDate+Helpers.h b/PMCalendar/src/NSDate+Helpers.h index dfd79d4..db606da 100644 --- a/PMCalendar/src/NSDate+Helpers.h +++ b/PMCalendar/src/NSDate+Helpers.h @@ -43,6 +43,11 @@ */ - (NSDate *) monthStartDate; +/** + * Returns start of day for the current (self) date. + */ +- (NSDate *) midnightDate; + /** * Returns the number of days in the current (self) month. */ @@ -67,4 +72,10 @@ */ - (NSString *) dateStringWithFormat:(NSString *) format; +/** + * Checks if a given date is before or after the current (self) date. + */ +- (BOOL) isBefore:(NSDate *) date; +- (BOOL) isAfter:(NSDate *) date; + @end diff --git a/PMCalendar/src/NSDate+Helpers.m b/PMCalendar/src/NSDate+Helpers.m index 349ec46..4081f9b 100644 --- a/PMCalendar/src/NSDate+Helpers.m +++ b/PMCalendar/src/NSDate+Helpers.m @@ -59,6 +59,17 @@ - (NSDate *) monthStartDate return monthStartDate; } +- (NSDate *) midnightDate +{ + NSDate *midnightDate = nil; + [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit + startDate:&midnightDate + interval:NULL + forDate:self]; + + return midnightDate; +} + - (NSUInteger) numberOfDaysInMonth { return [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit @@ -88,4 +99,14 @@ - (NSInteger) daysSinceDate:(NSDate *) date return [self timeIntervalSinceDate:date] / (60 * 60 * 24); } +- (BOOL) isBefore:(NSDate *) date +{ + return [self timeIntervalSinceDate:date] < 0; +} + +- (BOOL) isAfter:(NSDate *) date +{ + return [self timeIntervalSinceDate:date] > 0; +} + @end diff --git a/PMCalendar/src/PMCalendarBackgroundView.m b/PMCalendar/src/PMCalendarBackgroundView.m index 238ddaf..d938c63 100644 --- a/PMCalendar/src/PMCalendarBackgroundView.m +++ b/PMCalendar/src/PMCalendarBackgroundView.m @@ -14,6 +14,7 @@ @interface PMCalendarBackgroundView () +@property (nonatomic, assign) CGRect initialFrame; - (void)redrawComponent; @end @@ -22,6 +23,7 @@ @implementation PMCalendarBackgroundView @synthesize arrowDirection = _arrowDirection; @synthesize arrowPosition = _arrowPosition; +@synthesize initialFrame = _initialFrame; #pragma mark - UIView overridden methods - @@ -44,6 +46,7 @@ - (id)initWithFrame:(CGRect)frame name:kPMCalendarRedrawNotification object:nil]; self.backgroundColor = [UIColor clearColor]; + self.initialFrame = frame; return self; } @@ -215,8 +218,8 @@ -(void)drawRect:(CGRect)rect // backgound box. doesn't include arrow: CGRect boxBounds = CGRectMake(0, 0 - , self.bounds.size.width - arrowSize.height - , self.bounds.size.height - arrowSize.height); + , self.frame.size.width - arrowSize.height + , self.frame.size.height - arrowSize.height); CGFloat width = boxBounds.size.width - (shadowPadding.left + shadowPadding.right); CGFloat height = boxBounds.size.height - (shadowPadding.top + shadowPadding.bottom); diff --git a/PMCalendar/src/PMCalendarController.h b/PMCalendar/src/PMCalendarController.h index 0264e81..08bdca5 100644 --- a/PMCalendar/src/PMCalendarController.h +++ b/PMCalendar/src/PMCalendarController.h @@ -45,21 +45,27 @@ - (id) initWithThemeName:(NSString *) themeName andSize:(CGSize) size; /** - * Allows you to present a calendar from a rect in a particular view. - * "arrowDirections" is a bitfield which specifies what arrow directions are allowed + * Allows you to present a calendar from a rect in a particular view. + * "arrowDirections" is a bitfield which specifies what arrow directions are allowed * when laying out the calendar. + * If "isPopover" is set to YES, calendar will be presented with dimming view below it, + * which invokes delegate's "shouldDismiss" and "didDismiss" by tapping on it. + * "isPopover" is particulary handy for calendars like apple's calendar from Calendar.app + * which couldn't be dismissed and alows interaction below it. */ -- (void)presentCalendarFromRect:(CGRect) rect +- (void)presentCalendarFromRect:(CGRect) rect inView:(UIView *) view permittedArrowDirections:(PMCalendarArrowDirection) arrowDirections + isPopover:(BOOL) isPopover animated:(BOOL) animated; /** * Like the above, but is a convenience for presentation from a "UIView" instance. * This allows to calculate position of the calendar during rotation, so it positions itself properly. */ -- (void)presentCalendarFromView:(UIView *) anchorView +- (void)presentCalendarFromView:(UIView *) anchorView permittedArrowDirections:(PMCalendarArrowDirection) arrowDirections + isPopover:(BOOL) isPopover animated:(BOOL) animated; /** @@ -81,7 +87,7 @@ @property (nonatomic, strong) PMPeriod *period; /** - * TBI: this property is planned to reflect PMPeriod of dates allowed to select from. + * Reflects PMPeriod allowed to select from. * This also limits user's iteration. * * I.e. if allowed period is set to 23.02.2001 - 19.08.2020, user will not be able to see @@ -119,8 +125,12 @@ */ @property (nonatomic, assign) CGSize size; -@end +/** + * Returns whether the popover is visible (presented) or not. + */ +@property (nonatomic, assign, readonly, getter = isCalendarVisible) BOOL calendarVisible; +@end @protocol PMCalendarControllerDelegate @@ -145,3 +155,25 @@ - (void)calendarController:(PMCalendarController *)calendarController didChangePeriod:(PMPeriod *)newPeriod; @end + +@interface PMCalendarController (PMCalendarControllerDeprecated) + +/** + * Allows you to present a calendar from a rect in a particular view. + * "arrowDirections" is a bitfield which specifies what arrow directions are allowed + * when laying out the calendar. + */ +- (void)presentCalendarFromRect:(CGRect) rect + inView:(UIView *) view + permittedArrowDirections:(PMCalendarArrowDirection) arrowDirections + animated:(BOOL) animated; + +/** + * Like the above, but is a convenience for presentation from a "UIView" instance. + * This allows to calculate position of the calendar during rotation, so it positions itself properly. + */ +- (void)presentCalendarFromView:(UIView *) anchorView + permittedArrowDirections:(PMCalendarArrowDirection) arrowDirections + animated:(BOOL) animated; + +@end diff --git a/PMCalendar/src/PMCalendarController.m b/PMCalendar/src/PMCalendarController.m index 35af2c0..8453d9a 100644 --- a/PMCalendar/src/PMCalendarController.m +++ b/PMCalendar/src/PMCalendarController.m @@ -30,11 +30,13 @@ @interface PMCalendarController () @property (nonatomic, assign) PMCalendarArrowDirection calendarArrowDirection; @property (nonatomic, assign) CGPoint savedArrowPosition; @property (nonatomic, assign) UIDeviceOrientation currentOrientation; +@property (nonatomic, assign) CGRect initialFrame; @end @implementation PMCalendarController +@synthesize initialFrame = _initialFrame; @synthesize position = _position; @synthesize delegate = _delegate; @@ -46,6 +48,7 @@ @implementation PMCalendarController @synthesize calendarArrowDirection = _calendarArrowDirection; @synthesize currentOrientation = _currentOrientation; +@synthesize calendarVisible = _calendarVisible; @synthesize mainView = _mainView; @synthesize anchorView = _anchorView; @@ -56,6 +59,11 @@ @implementation PMCalendarController @synthesize size = _size; @synthesize savedArrowPosition = _savedArrowPosition; +- (void) dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + #pragma mark - object initializers - - (void) initializeWithSize:(CGSize) size @@ -64,32 +72,30 @@ - (void) initializeWithSize:(CGSize) size CGSize outerPadding = kPMThemeOuterPadding; self.calendarArrowDirection = PMCalendarArrowDirectionUnknown; - CGRect calendarRect = CGRectMake(0 - , 0 - , size.width + kPMThemeShadowPadding.left + kPMThemeShadowPadding.right - , size.height + kPMThemeShadowPadding.top + kPMThemeShadowPadding.bottom); - self.calendarView = [[UIView alloc] initWithFrame:calendarRect]; + self.initialFrame = CGRectMake(0 + , 0 + , size.width + kPMThemeShadowPadding.left + kPMThemeShadowPadding.right + , size.height + kPMThemeShadowPadding.top + kPMThemeShadowPadding.bottom); + self.calendarView = [[UIView alloc] initWithFrame:_initialFrame]; self.calendarView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; //Make insets from two sides of a calendar to have place for arrow CGRect calendarRectWithArrowInsets = CGRectMake(0, 0 - , calendarRect.size.width + arrowSize.height - , calendarRect.size.height + arrowSize.height); + , _initialFrame.size.width + arrowSize.height + , _initialFrame.size.height + arrowSize.height); self.mainView = [[UIView alloc] initWithFrame:calendarRectWithArrowInsets]; - + self.backgroundView = [[PMCalendarBackgroundView alloc] initWithFrame:CGRectInset(calendarRectWithArrowInsets , outerPadding.width , outerPadding.height)]; - UIEdgeInsetsInsetRect(calendarRect, kPMThemeShadowPadding); self.backgroundView.clipsToBounds = NO; [self.mainView addSubview:self.backgroundView]; - self.digitsView = [[PMCalendarView alloc] initWithFrame:UIEdgeInsetsInsetRect(CGRectInset(calendarRect + self.digitsView = [[PMCalendarView alloc] initWithFrame:UIEdgeInsetsInsetRect(CGRectInset(_initialFrame , kPMThemeInnerPadding.width , kPMThemeInnerPadding.height) , kPMThemeShadowPadding)]; self.digitsView.delegate = self; - self.digitsView.period = [PMPeriod oneDayPeriodWithDate:[NSDate date]]; [self.calendarView addSubview:self.digitsView]; [self.mainView addSubview:self.calendarView]; @@ -105,6 +111,10 @@ - (id) initWithSize:(CGSize) size return nil; } + if (![PMThemeEngine sharedInstance].themeName) + { + [PMThemeEngine sharedInstance].themeName = @"default"; + } [self initializeWithSize: size]; return self; @@ -127,11 +137,6 @@ - (id) initWithThemeName:(NSString *) themeName andSize:(CGSize) size return [self initWithSize:size]; } -- (void)dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - #pragma mark - rotation handling - - (void)didRotate:(NSNotification *) notice @@ -298,50 +303,69 @@ - (void) adjustCalendarPositionForPermittedArrowDirections:(PMCalendarArrowDirec self.savedArrowPosition = arrowPosition; } -- (void) presentCalendarFromView:(UIView *) anchorView - permittedArrowDirections:(PMCalendarArrowDirection) arrowDirections - animated:(BOOL) animated -{ - self.anchorView = anchorView; - self.savedPermittedArrowDirections = arrowDirections; - - [self presentCalendarFromRect:anchorView.frame - inView:self.anchorView.superview - permittedArrowDirections:arrowDirections - animated:animated]; -} -- (void) presentCalendarFromRect:(CGRect) rect - inView:(UIView *) view - permittedArrowDirections:(PMCalendarArrowDirection) arrowDirections - animated:(BOOL) animated +- (void)presentCalendarFromRect:(CGRect) rect + inView:(UIView *) view + permittedArrowDirections:(PMCalendarArrowDirection) arrowDirections + isPopover:(BOOL) isPopover + animated:(BOOL) animated { - self.view = [[PMDimmingView alloc] initWithFrame:view.bounds - controller:self]; - self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - [self.view addSubview:self.mainView]; + if (!isPopover) + { + self.view = self.mainView; + } + else + { + self.view = [[PMDimmingView alloc] initWithFrame:view.bounds + controller:self]; + self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + [self.view addSubview:self.mainView]; + } + [view addSubview:self.view]; CGRect rectInAppWindow = [self.view convertRect:rect fromView:view]; [self adjustCalendarPositionForPermittedArrowDirections:arrowDirections arrowPointsToRect:rectInAppWindow]; - + self.initialFrame = self.mainView.frame; [self fullRedraw]; [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(didRotate:) + selector:@selector(didRotate:) name:UIDeviceOrientationDidChangeNotification object:nil]; - + if (animated) { self.mainView.alpha = 0; - + [UIView animateWithDuration:0.2 animations:^{ self.mainView.alpha = 1; }]; } + + if (!_digitsView.period) + { + self.period = [PMPeriod oneDayPeriodWithDate:[NSDate date]]; + } + + _calendarVisible = YES; +} + +- (void)presentCalendarFromView:(UIView *) anchorView + permittedArrowDirections:(PMCalendarArrowDirection) arrowDirections + isPopover:(BOOL) isPopover + animated:(BOOL) animated +{ + self.anchorView = anchorView; + self.savedPermittedArrowDirections = arrowDirections; + + [self presentCalendarFromRect:anchorView.frame + inView:self.anchorView.superview + permittedArrowDirections:arrowDirections + isPopover:isPopover + animated:animated]; } - (void) dismissCalendarAnimated:(BOOL) animated @@ -350,7 +374,7 @@ - (void) dismissCalendarAnimated:(BOOL) animated void (^completionBlock)(BOOL) = ^(BOOL finished){ [[NSNotificationCenter defaultCenter] removeObserver:self]; [self.view removeFromSuperview]; - self.mainView.transform = CGAffineTransformMakeScale(1.0, 1.0); + _calendarVisible = NO; if ([self.delegate respondsToSelector:@selector(calendarControllerDidDismissCalendar:)]) { [self.delegate calendarControllerDidDismissCalendar:self]; @@ -425,6 +449,7 @@ - (PMPeriod *) period - (void) setPeriod:(PMPeriod *) period { self.digitsView.period = period; + self.digitsView.currentDate = period.startDate; } - (PMPeriod *) allowedPeriod @@ -455,19 +480,16 @@ - (void) currentDateChanged:(NSDate *) currentDate int numDaysInMonth = [currentDate numberOfDaysInMonth]; NSInteger monthStartDay = [[currentDate monthStartDate] weekday]; numDaysInMonth += (monthStartDay + (self.digitsView.mondayFirstDayOfWeek?5:6)) % 7; - CGFloat height = self.mainView.frame.size.height - outerPadding.height * 2 - arrowSize.height; - CGFloat vDiff = (height - kPMThemeHeaderHeight - kPMThemeInnerPadding.height * 2) / ((kPMThemeDayTitlesInHeader)?6:7); - CGRect frm = CGRectInset(self.mainView.bounds, outerPadding.width, outerPadding.height); + CGFloat height = _initialFrame.size.height - outerPadding.height * 2 - arrowSize.height; + CGFloat vDiff = (height - kPMThemeHeaderHeight - kPMThemeInnerPadding.height * 2 - kPMThemeShadowPadding.bottom - kPMThemeShadowPadding.top) / ((kPMThemeDayTitlesInHeader)?6:7); + CGRect frm = CGRectInset(_initialFrame, outerPadding.width, outerPadding.height); int numberOfRows = ceil((CGFloat)numDaysInMonth / 7); - frm.size.height = ceil(((numberOfRows + ((kPMThemeDayTitlesInHeader)?0:1)) * vDiff) + kPMThemeHeaderHeight + kPMThemeInnerPadding.height * 2 + arrowSize.height); + frm.size.height = ceil(((numberOfRows + ((kPMThemeDayTitlesInHeader)?0:1)) * vDiff) + kPMThemeHeaderHeight + kPMThemeInnerPadding.height * 2 + arrowSize.height) + kPMThemeShadowPadding.bottom + kPMThemeShadowPadding.top; if (self.calendarArrowDirection == PMCalendarArrowDirectionDown) { - CGRect calendarViewFrame = self.calendarView.frame; - frm.origin.y = self.mainView.bounds.size.height - frm.size.height; - calendarViewFrame.origin.y = frm.origin.y; - self.calendarView.frame = calendarViewFrame; + frm.origin.y += _initialFrame.size.height - frm.size.height; } // TODO: recalculate arrow position for left & right @@ -478,7 +500,7 @@ - (void) currentDateChanged:(NSDate *) currentDate // self.backgroundView.arrowPosition = // } - self.backgroundView.frame = frm; + self.mainView.frame = frm; [self fullRedraw]; } @@ -500,4 +522,28 @@ - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interface return YES; } +#pragma mark - Deprecated methods - + +- (void) presentCalendarFromRect:(CGRect) rect + inView:(UIView *) view + permittedArrowDirections:(PMCalendarArrowDirection) arrowDirections + animated:(BOOL) animated +{ + [self presentCalendarFromRect:rect + inView:view + permittedArrowDirections:arrowDirections + isPopover:YES + animated:animated]; +} + +- (void) presentCalendarFromView:(UIView *) anchorView + permittedArrowDirections:(PMCalendarArrowDirection) arrowDirections + animated:(BOOL) animated +{ + [self presentCalendarFromView:anchorView + permittedArrowDirections:arrowDirections + isPopover:YES + animated:animated]; +} + @end diff --git a/PMCalendar/src/PMCalendarView.h b/PMCalendar/src/PMCalendarView.h index 2a67a3b..88935a5 100644 --- a/PMCalendar/src/PMCalendarView.h +++ b/PMCalendar/src/PMCalendarView.h @@ -45,6 +45,8 @@ @property (nonatomic, assign) BOOL allowsLongPressMonthChange; @property (nonatomic, assign) id delegate; +@property (nonatomic, strong) NSDate *currentDate; + @end @protocol PMCalendarViewDelegate diff --git a/PMCalendar/src/PMCalendarView.m b/PMCalendar/src/PMCalendarView.m index 3cd8572..a47db20 100644 --- a/PMCalendar/src/PMCalendarView.m +++ b/PMCalendar/src/PMCalendarView.m @@ -18,10 +18,11 @@ @interface PMDaysView : UIView @property (nonatomic, strong) UIFont *font; -@property (nonatomic, strong) NSDate *currentDate; +@property (nonatomic, strong) NSDate *currentDate; // month to show @property (nonatomic, strong) PMPeriod *selectedPeriod; @property (nonatomic, strong) NSArray *rects; @property (nonatomic, assign) BOOL mondayFirstDayOfWeek; +@property (nonatomic, assign) CGRect initialFrame; - (void) redrawComponent; @@ -38,7 +39,7 @@ @interface PMCalendarView () @property (nonatomic, assign) CGPoint panPoint; @property (nonatomic, strong) PMDaysView *daysView; @property (nonatomic, strong) PMSelectionView *selectionView; -@property (nonatomic, strong) NSDate *currentDate; // month to show +@property (nonatomic, assign) CGRect initialFrame; - (NSInteger) indexForDate: (NSDate *)date; - (NSDate *) dateForPoint: (CGPoint)point; @@ -70,6 +71,7 @@ @implementation PMCalendarView @synthesize selectionView = _selectionView; @synthesize allowsPeriodSelection = _allowsPeriodSelection; @synthesize allowsLongPressMonthChange = _allowsLongPressMonthChange; +@synthesize initialFrame = _initialFrame; - (void)dealloc { @@ -82,7 +84,8 @@ - (id)initWithFrame:(CGRect)frame { return nil; } - + self.initialFrame = frame; + self.backgroundColor = [UIColor clearColor]; self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; self.mondayFirstDayOfWeek = NO; @@ -103,6 +106,7 @@ - (id)initWithFrame:(CGRect)frame [self addSubview:self.selectionView]; self.daysView = [[PMDaysView alloc] initWithFrame:self.bounds]; + self.daysView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; [self addSubview:self.daysView]; [[NSNotificationCenter defaultCenter] addObserver:self @@ -133,8 +137,8 @@ - (void)drawRect:(CGRect)rect CGFloat headerHeight = kPMThemeHeaderHeight; UIEdgeInsets shadowPadding = kPMThemeShadowPadding; - CGFloat width = self.frame.size.width + shadowPadding.left + shadowPadding.right; - CGFloat height = self.frame.size.height; + CGFloat width = _initialFrame.size.width + shadowPadding.left + shadowPadding.right; + CGFloat height = _initialFrame.size.height; CGFloat hDiff = width / 7; CGFloat vDiff = (height - headerHeight) / (kPMThemeDayTitlesInHeaderIntOffset + 5); @@ -193,57 +197,88 @@ - (void)drawRect:(CGRect)rect CGSize arrowSize = [arrowSizeDict pmThemeGenerateSize]; CGSize arrowOffset = [arrowOffsetDict pmThemeGenerateSize]; + BOOL showsLeftArrow = YES; + BOOL showsRightArrow = YES; - //// backArrow Drawing - UIBezierPath* backArrowPath = [UIBezierPath bezierPath]; - [backArrowPath moveToPoint: CGPointMake(hDiff / 2 - , headerHeight / 2)]; // left-center corner - [backArrowPath addLineToPoint: CGPointMake(arrowSize.width + hDiff / 2 - , headerHeight / 2 + arrowSize.height / 2)]; // right-bottom corner - [backArrowPath addLineToPoint: CGPointMake( arrowSize.width + hDiff / 2 - , headerHeight / 2 - arrowSize.height / 2)]; // right-top corner - [backArrowPath addLineToPoint: CGPointMake( hDiff / 2 - , headerHeight / 2)]; // back to left-center corner - [backArrowPath closePath]; - - CGAffineTransform transform = CGAffineTransformMakeTranslation(arrowOffset.width - shadowPadding.left - , arrowOffset.height); - [backArrowPath applyTransform:transform]; - - [[PMThemeEngine sharedInstance] drawPath:backArrowPath - forElementType:PMThemeMonthArrowsElementType - subType:PMThemeMainSubtype - inContext:context]; - leftArrowRect = CGRectInset(backArrowPath.bounds, -20, -20); - - //// forwardArrow Drawing - UIBezierPath* forwardArrowPath = [UIBezierPath bezierPath]; - [forwardArrowPath moveToPoint: CGPointMake( width - hDiff / 2 - , headerHeight / 2)]; // right-center corner - [forwardArrowPath addLineToPoint: CGPointMake( -arrowSize.width + width - hDiff / 2 - , headerHeight / 2 + arrowSize.height / 2)]; // left-bottom corner - [forwardArrowPath addLineToPoint: CGPointMake(-arrowSize.width + width - hDiff / 2 - , headerHeight / 2 - arrowSize.height / 2)]; // left-top corner - [forwardArrowPath addLineToPoint: CGPointMake( width - hDiff / 2 - , headerHeight / 2)]; // back to right-center corner - [forwardArrowPath closePath]; - - transform = CGAffineTransformMakeTranslation(-arrowOffset.width - shadowPadding.left, arrowOffset.height); - [forwardArrowPath applyTransform:transform]; - - [[PMThemeEngine sharedInstance] drawPath:forwardArrowPath - forElementType:PMThemeMonthArrowsElementType - subType:PMThemeMainSubtype - inContext:context]; - rightArrowRect = CGRectInset(forwardArrowPath.bounds, -20, -20); + if (self.allowedPeriod) + { + if ([[_currentDate dateByAddingMonths:-1] isBefore:[self.allowedPeriod.startDate monthStartDate]]) + { + showsLeftArrow = NO; + } + else if ([[_currentDate dateByAddingMonths:1] isAfter:self.allowedPeriod.endDate]) + { + showsRightArrow = NO; + } + } + + if (showsLeftArrow) + { + //// backArrow Drawing + UIBezierPath* backArrowPath = [UIBezierPath bezierPath]; + [backArrowPath moveToPoint: CGPointMake(hDiff / 2 + , headerHeight / 2)]; // left-center corner + [backArrowPath addLineToPoint: CGPointMake(arrowSize.width + hDiff / 2 + , headerHeight / 2 + arrowSize.height / 2)]; // right-bottom corner + [backArrowPath addLineToPoint: CGPointMake( arrowSize.width + hDiff / 2 + , headerHeight / 2 - arrowSize.height / 2)]; // right-top corner + [backArrowPath addLineToPoint: CGPointMake( hDiff / 2 + , headerHeight / 2)]; // back to left-center corner + [backArrowPath closePath]; + + CGAffineTransform transform = CGAffineTransformMakeTranslation(arrowOffset.width - shadowPadding.left + , arrowOffset.height); + [backArrowPath applyTransform:transform]; + + [[PMThemeEngine sharedInstance] drawPath:backArrowPath + forElementType:PMThemeMonthArrowsElementType + subType:PMThemeMainSubtype + inContext:context]; + leftArrowRect = CGRectInset(backArrowPath.bounds, -20, -20); + } + + if (showsRightArrow) + { + //// forwardArrow Drawing + UIBezierPath* forwardArrowPath = [UIBezierPath bezierPath]; + [forwardArrowPath moveToPoint: CGPointMake( width - hDiff / 2 + , headerHeight / 2)]; // right-center corner + [forwardArrowPath addLineToPoint: CGPointMake( -arrowSize.width + width - hDiff / 2 + , headerHeight / 2 + arrowSize.height / 2)]; // left-bottom corner + [forwardArrowPath addLineToPoint: CGPointMake(-arrowSize.width + width - hDiff / 2 + , headerHeight / 2 - arrowSize.height / 2)]; // left-top corner + [forwardArrowPath addLineToPoint: CGPointMake( width - hDiff / 2 + , headerHeight / 2)]; // back to right-center corner + [forwardArrowPath closePath]; + + CGAffineTransform transform = CGAffineTransformMakeTranslation(-arrowOffset.width - shadowPadding.left, arrowOffset.height); + [forwardArrowPath applyTransform:transform]; + + [[PMThemeEngine sharedInstance] drawPath:forwardArrowPath + forElementType:PMThemeMonthArrowsElementType + subType:PMThemeMainSubtype + inContext:context]; + rightArrowRect = CGRectInset(forwardArrowPath.bounds, -20, -20); + } } - (void) setCurrentDate:(NSDate *)currentDate { - _currentDate = currentDate; + if (self.allowedPeriod) + { + if (([currentDate isBefore:[self.allowedPeriod.startDate monthStartDate]]) + || ([currentDate isAfter:self.allowedPeriod.endDate])) + { + return; + } + } + + _currentDate = [currentDate monthStartDate]; NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; - NSDateComponents *eComponents = [gregorian components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit + NSDateComponents *eComponents = [gregorian components:NSDayCalendarUnit + | NSMonthCalendarUnit + | NSYearCalendarUnit fromDate:_currentDate]; BOOL needsRedraw = NO; @@ -290,7 +325,7 @@ - (void)setMondayFirstDayOfWeek:(BOOL)mondayFirstDayOfWeek - (UIFont *) font { - NSInteger newFontSize = self.frame.size.width / 20; + NSInteger newFontSize = _initialFrame.size.width / 20; if (!_font || fontSize == 0 || fontSize != newFontSize) { _font = [UIFont fontWithName: @"Helvetica" size: newFontSize]; @@ -325,11 +360,44 @@ - (void) periodUpdated self.daysView.selectedPeriod = _period; [self.daysView redrawComponent]; } + +- (void)setAllowedPeriod:(PMPeriod *)allowedPeriod +{ + if (allowedPeriod != _allowedPeriod) + { + _allowedPeriod = allowedPeriod; + _allowedPeriod.startDate = [_allowedPeriod.startDate midnightDate]; + _allowedPeriod.endDate = [_allowedPeriod.endDate midnightDate]; + } +} + - (void)setPeriod:(PMPeriod *)period { - if (![_period isEqual:period]) + PMPeriod *localPeriod = [period copy]; + if (self.allowedPeriod) + { + if ([localPeriod.startDate isBefore:self.allowedPeriod.startDate]) + { + localPeriod.startDate = self.allowedPeriod.startDate; + } + else if ([localPeriod.startDate isAfter:self.allowedPeriod.endDate]) + { + localPeriod.startDate = self.allowedPeriod.endDate; + } + + if ([localPeriod.endDate isBefore:self.allowedPeriod.startDate]) + { + localPeriod.endDate = self.allowedPeriod.startDate; + } + else if ([localPeriod.endDate isAfter:self.allowedPeriod.endDate]) + { + localPeriod.endDate = self.allowedPeriod.endDate; + } + } + + if (![_period isEqual:localPeriod]) { - _period = period; + _period = localPeriod; if (!_currentDate) { @@ -359,8 +427,8 @@ - (NSInteger) indexForDate: (NSDate *)date - (NSDate *) dateForPoint: (CGPoint)point { - CGFloat width = self.frame.size.width; - CGFloat height = self.frame.size.height; + CGFloat width = _initialFrame.size.width; + CGFloat height = _initialFrame.size.height; CGFloat hDiff = width / 7; CGFloat vDiff = (height - kPMThemeHeaderHeight) / ((kPMThemeDayTitlesInHeader)?6:7); @@ -419,7 +487,7 @@ - (void) panHandling: (UIGestureRecognizer *)recognizer { CGPoint point = [recognizer locationInView:self]; - CGFloat height = self.frame.size.height; + CGFloat height = _initialFrame.size.height; CGFloat vDiff = (height - kPMThemeHeaderHeight) / ((kPMThemeDayTitlesInHeader)?6:7); if (point.y > kPMThemeHeaderHeight + ((kPMThemeDayTitlesInHeader)?0:vDiff)) // select date in calendar @@ -430,7 +498,7 @@ - (void) panHandling: (UIGestureRecognizer *)recognizer } else if (([recognizer state] == UIGestureRecognizerStateChanged) && (recognizer.numberOfTouches == 1)) { - if ((point.x < 20) || (point.x > self.frame.size.width - 20)) + if ((point.x < 20) || (point.x > _initialFrame.size.width - 20)) { self.panPoint = point; if (self.panTimer) @@ -473,7 +541,7 @@ - (void) tapHandling: (UIGestureRecognizer *)recognizer { CGPoint point = [recognizer locationInView:self]; - CGFloat height = self.frame.size.height; + CGFloat height = _initialFrame.size.height; CGFloat vDiff = (height - kPMThemeHeaderHeight) / ((kPMThemeDayTitlesInHeader)?6:7); if (point.y > kPMThemeHeaderHeight + ((kPMThemeDayTitlesInHeader)?0:vDiff)) // select date in calendar @@ -510,7 +578,7 @@ - (void) longPressHandling: (UIGestureRecognizer *)recognizer } CGPoint point = [recognizer locationInView:self]; - CGFloat height = self.frame.size.height; + CGFloat height = _initialFrame.size.height; CGFloat vDiff = (height - kPMThemeHeaderHeight) / ((kPMThemeDayTitlesInHeader)?6:7); if (point.y > kPMThemeHeaderHeight + ((kPMThemeDayTitlesInHeader)?0:vDiff)) // select date in calendar @@ -591,6 +659,7 @@ @implementation PMDaysView @synthesize selectedPeriod = _selectedPeriod; @synthesize mondayFirstDayOfWeek = _mondayFirstDayOfWeek; @synthesize rects; +@synthesize initialFrame = _initialFrame; - (void)dealloc { @@ -608,7 +677,8 @@ - (id)initWithFrame:(CGRect)frame { return nil; } - + self.initialFrame = frame; + self.backgroundColor = [UIColor clearColor]; self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; @@ -622,9 +692,9 @@ - (id)initWithFrame:(CGRect)frame CGFloat headerHeight = kPMThemeHeaderHeight; UIFont *calendarFont = kPMThemeDefaultFont; - CGFloat width = self.frame.size.width + shadowPadding.left + shadowPadding.right; + CGFloat width = _initialFrame.size.width + shadowPadding.left + shadowPadding.right; CGFloat hDiff = width / 7; - CGFloat height = self.frame.size.height; + CGFloat height = _initialFrame.size.height; CGFloat vDiff = (height - headerHeight) / (kPMThemeDayTitlesInHeaderIntOffset + 6); CGSize shadow2Offset = CGSizeMake(1, 1); // TODO: remove! @@ -708,7 +778,6 @@ - (void)drawRect:(CGRect)rect inContext:context]; } - int finalRow = 0; int day = 1; for (int i = 0; i < 6; i++) @@ -722,7 +791,7 @@ - (void)drawRect:(CGRect)rect NSString *string = [NSString stringWithFormat:@"%d", day]; CGRect dayHeader2Frame = CGRectFromString([self.rects objectAtIndex:dayNumber]); BOOL selected = (dayNumber >= selectionStartIndex) && (dayNumber <= selectionEndIndex); - BOOL isToday = (dayNumber == todayIndex); + BOOL isToday = (dayNumber == (todayIndex + weekdayOfFirst - 1)); if(isToday) { @@ -730,8 +799,8 @@ - (void)drawRect:(CGRect)rect if (todayBGDict) { - CGFloat width = self.frame.size.width + shadowPadding.left + shadowPadding.right; - CGFloat height = self.frame.size.height; + CGFloat width = _initialFrame.size.width + shadowPadding.left + shadowPadding.right; + CGFloat height = _initialFrame.size.height; CGFloat hDiff = (width + shadowPadding.left + shadowPadding.right - kPMThemeInnerPadding.width * 2) / 7; CGFloat vDiff = (height - kPMThemeHeaderHeight - kPMThemeInnerPadding.height * 2) / ((kPMThemeDayTitlesInHeader)?6:7); CGSize bgOffset = [[todayBGDict elementInThemeDictOfGenericType:PMThemeOffsetGenericType] pmThemeGenerateSize]; @@ -800,8 +869,6 @@ - (void)drawRect:(CGRect)rect subType:PMThemeMainSubtype inContext:context]; - finalRow = i; - ++day; } } @@ -844,7 +911,6 @@ - (void)drawRect:(CGRect)rect inContext:context]; } } - PMLog( @"End" ); } - (void) setCurrentDate:(NSDate *)currentDate diff --git a/PMCalendar/src/PMPeriod.h b/PMCalendar/src/PMPeriod.h index 43de017..f133883 100644 --- a/PMCalendar/src/PMPeriod.h +++ b/PMCalendar/src/PMPeriod.h @@ -12,7 +12,7 @@ * PMPeriod is a simple class which represents a period of time. * PMPeriod has start and end date which could be the same in order to represent one-day period. */ -@interface PMPeriod : NSObject +@interface PMPeriod : NSObject @property (nonatomic, strong) NSDate *startDate; @property (nonatomic, strong) NSDate *endDate; diff --git a/PMCalendar/src/PMPeriod.m b/PMCalendar/src/PMPeriod.m index c0a6c97..cbabe0a 100644 --- a/PMCalendar/src/PMPeriod.m +++ b/PMCalendar/src/PMPeriod.m @@ -87,4 +87,13 @@ - (BOOL) containsDate:(NSDate *) date return NO; } +- (id) copyWithZone:(NSZone *) zone +{ + PMPeriod *copiedPeriod = [[PMPeriod alloc] init]; + copiedPeriod.startDate = [_startDate copyWithZone: zone]; + copiedPeriod.endDate = [_endDate copyWithZone: zone]; + + return copiedPeriod; +} + @end diff --git a/PMCalendar/src/PMSelectionView.m b/PMCalendar/src/PMSelectionView.m index bd72566..b51528b 100644 --- a/PMCalendar/src/PMSelectionView.m +++ b/PMCalendar/src/PMSelectionView.m @@ -12,12 +12,15 @@ @interface PMSelectionView () +@property (nonatomic, assign) CGRect initialFrame; + @end @implementation PMSelectionView @synthesize startIndex = _startIndex; @synthesize endIndex = _endIndex; +@synthesize initialFrame = _initialFrame; - (void)dealloc { @@ -43,6 +46,7 @@ - (id)initWithFrame:(CGRect)frame name:kPMCalendarRedrawNotification object:nil]; self.backgroundColor = [UIColor clearColor]; + self.initialFrame = frame; return self; } @@ -61,8 +65,8 @@ - (void)drawRect:(CGRect)rect CGSize innerPadding = kPMThemeInnerPadding; CGFloat headerHeight = kPMThemeHeaderHeight; - CGFloat width = self.frame.size.width; - CGFloat height = self.frame.size.height; + CGFloat width = _initialFrame.size.width; + CGFloat height = _initialFrame.size.height; CGFloat hDiff = (width + shadowPadding.left + shadowPadding.right - innerPadding.width * 2) / 7; CGFloat vDiff = (height - headerHeight - innerPadding.height * 2) / (kPMThemeDayTitlesInHeaderIntOffset + 6); @@ -119,7 +123,7 @@ - (void)drawRect:(CGRect)rect , floor((thisRowEndCell - thisRowStartCell + 1) * hDiff) , floor(vDiff)); rect = UIEdgeInsetsInsetRect(rect, rectInset); - NSLog( @"%@", NSStringFromCGRect(rect) ); + UIBezierPath* selectedRectPath = [UIBezierPath bezierPathWithRoundedRect: rect cornerRadius: cornerRadius]; [[PMThemeEngine sharedInstance] drawPath: selectedRectPath diff --git a/PMCalendar/src/PMTheme.h b/PMCalendar/src/PMTheme.h index c14c492..be87a16 100644 --- a/PMCalendar/src/PMTheme.h +++ b/PMCalendar/src/PMTheme.h @@ -19,29 +19,3 @@ #define kPMThemeCornerRadius [PMThemeEngine sharedInstance].cornerRadius #define kPMThemeArrowSize [PMThemeEngine sharedInstance].arrowSize #define kPMThemeOuterPadding [PMThemeEngine sharedInstance].outerPadding - - -#ifdef MIMIC_APPLE_THEME - -// 226,226,228 (0) -// 204,203,208 (1) - - -#define kPMThemeBackgroundTodayColor UIColorMakeRGB(115, 137, 165) -#define kPMThemeBackgroundTodayStrokeWidth 2 -#define kPMThemeBackgroundTodayStrokeColor UIColorMakeRGB(54, 79, 114) -#define kPMThemeBackgroundTodayOffset (UIOffset){0, -1} -#define kPMThemeBackgroundTodaySizeInset (CGSize){1, 1} -#define kPMThemeBackgroundTodayInnerShadowColor UIColorMakeRGB(0, 0, 0) -#define kPMThemeBackgroundTodayInnerShadowOffset (UIOffset){1, 1} -#define kPMThemeBackgroundTodayInnerShadowBlurRadius 5 - - -#define kPMThemeCalendarDigitsTodayColor [UIColor whiteColor] -#define kPMThemeCalendarDigitsTodayShadowColor UIColorMakeRGB(35, 76, 117) -#define kPMThemeCalendarDigitsTodayShadowOffset (UIOffset){0, 1} - - -#define kPMThemeSelectionCeilCoordinates YES - -#endif diff --git a/PMCalendar/src/PMThemeEngine.h b/PMCalendar/src/PMThemeEngine.h index 87b178f..6d80823 100644 --- a/PMCalendar/src/PMThemeEngine.h +++ b/PMCalendar/src/PMThemeEngine.h @@ -6,7 +6,7 @@ // Copyright (c) 2012 Pavel Mazurin. All rights reserved. // -#import +#import typedef enum PMThemeElementType { PMThemeGeneralElementType = 0, diff --git a/PMCalendar/src/PMThemeEngine.m b/PMCalendar/src/PMThemeEngine.m index c2f6239..b96f2e2 100644 --- a/PMCalendar/src/PMThemeEngine.m +++ b/PMCalendar/src/PMThemeEngine.m @@ -11,6 +11,7 @@ #import static PMThemeEngine* sharedInstance; + @interface PMThemeEngine () @property (nonatomic, strong) NSDictionary *themeDict; @@ -400,45 +401,59 @@ - (void) drawPath:(UIBezierPath *) path subtype:themeElementSubtype]; id colorObj = [themeDictionary elementInThemeDictOfGenericType:PMThemeColorGenericType]; - CGContextSaveGState(context); NSDictionary *shadowDict = [themeDictionary elementInThemeDictOfGenericType:PMThemeShadowGenericType]; - - if (shadowDict) + CGContextSaveGState(context); { - CGSize shadowOffset = [[shadowDict elementInThemeDictOfGenericType:PMThemeOffsetGenericType] pmThemeGenerateSize]; - UIColor *shadowColor = [PMThemeEngine colorFromString:[shadowDict elementInThemeDictOfGenericType:PMThemeColorGenericType]]; - NSNumber *blurRadius = [shadowDict elementInThemeDictOfGenericType:PMThemeShadowBlurRadiusType]; - CGContextSetShadowWithColor(context - , shadowOffset - , blurRadius?[blurRadius floatValue]:sharedInstance.shadowBlurRadius - , shadowColor.CGColor); + if (shadowDict) + { + CGSize shadowOffset = [[shadowDict elementInThemeDictOfGenericType:PMThemeOffsetGenericType] pmThemeGenerateSize]; + UIColor *shadowColor = [PMThemeEngine colorFromString:[shadowDict elementInThemeDictOfGenericType:PMThemeColorGenericType]]; + NSNumber *blurRadius = [shadowDict elementInThemeDictOfGenericType:PMThemeShadowBlurRadiusType]; + CGContextSetShadowWithColor(context + , shadowOffset + , blurRadius?[blurRadius floatValue]:sharedInstance.shadowBlurRadius + , shadowColor.CGColor); + if (![shadowDict objectForKey:@"Type"]) + { + [shadowColor setFill]; + [path fill]; + } + } } - [path addClip]; - - if ([colorObj isKindOfClass:[NSString class]]) // plain color + if (![shadowDict objectForKey:@"Type"]) { - [[PMThemeEngine colorFromString:colorObj] setFill]; - - [path fill]; + CGContextRestoreGState(context); + + CGContextSaveGState(context); } - else { - [PMThemeEngine drawGradientInContext:context - inRect:path.bounds - fromArray:colorObj]; - } + [path addClip]; - NSDictionary *stroke = [themeDictionary elementInThemeDictOfGenericType:PMThemeStrokeGenericType]; - - if (stroke) - { - NSString *strokeColorStr = [stroke elementInThemeDictOfGenericType:PMThemeColorGenericType]; - UIColor *strokeColor = [PMThemeEngine colorFromString:strokeColorStr]; - [strokeColor setStroke]; - path.lineWidth = [[stroke elementInThemeDictOfGenericType:PMThemeSizeWidthGenericType] floatValue]; // TODO: make separate stroke width generic type - [path stroke]; + if ([colorObj isKindOfClass:[NSString class]]) // plain color + { + [[PMThemeEngine colorFromString:colorObj] setFill]; + + [path fill]; + } + else + { + [PMThemeEngine drawGradientInContext:context + inRect:path.bounds + fromArray:colorObj]; + } + + NSDictionary *stroke = [themeDictionary elementInThemeDictOfGenericType:PMThemeStrokeGenericType]; + + if (stroke) + { + NSString *strokeColorStr = [stroke elementInThemeDictOfGenericType:PMThemeColorGenericType]; + UIColor *strokeColor = [PMThemeEngine colorFromString:strokeColorStr]; + [strokeColor setStroke]; + path.lineWidth = [[stroke elementInThemeDictOfGenericType:PMThemeSizeWidthGenericType] floatValue]; // TODO: make separate stroke width generic type + + [path stroke]; + } } - CGContextRestoreGState(context); } diff --git a/PMCalendar/src/PMThemeShadow.h b/PMCalendar/src/PMThemeShadow.h index 59b66bf..19edee8 100644 --- a/PMCalendar/src/PMThemeShadow.h +++ b/PMCalendar/src/PMThemeShadow.h @@ -6,7 +6,7 @@ // Copyright (c) 2012 Pavel Mazurin. All rights reserved. // -#import +#import @interface PMThemeShadow : NSObject diff --git a/PMCalendarDemo/PMViewController.m b/PMCalendarDemo/PMViewController.m index 5ede846..29e25e4 100644 --- a/PMCalendarDemo/PMViewController.m +++ b/PMCalendarDemo/PMViewController.m @@ -18,36 +18,49 @@ @interface PMViewController () @implementation PMViewController @synthesize pmCC; - @synthesize periodLabel; - (IBAction)showCalendar:(id)sender { + if ([self.pmCC isCalendarVisible]) + { + [self.pmCC dismissCalendarAnimated:NO]; + } + + BOOL isPopover = YES; if ([sender tag] == 10) { + isPopover = NO; self.pmCC = [[PMCalendarController alloc] initWithThemeName:@"apple calendar"]; + // limit apple calendar to 2 months before and 2 months after current date +// self.pmCC.allowedPeriod = [PMPeriod periodWithStartDate:[[NSDate date] dateByAddingMonths:-2] +// endDate:[[NSDate date] dateByAddingMonths:2]]; } else { self.pmCC = [[PMCalendarController alloc] initWithThemeName:@"default"]; } - pmCC.delegate = self; - pmCC.mondayFirstDayOfWeek = NO; + + self.pmCC.delegate = self; + self.pmCC.mondayFirstDayOfWeek = NO; if ([sender tag] == 10) { - [pmCC presentCalendarFromRect:CGRectZero - inView:[sender superview] - permittedArrowDirections:PMCalendarArrowDirectionAny - animated:YES]; + [self.pmCC presentCalendarFromRect:CGRectZero + inView:[sender superview] + permittedArrowDirections:PMCalendarArrowDirectionAny + isPopover:isPopover + animated:YES]; } else { - [pmCC presentCalendarFromView:sender - permittedArrowDirections:PMCalendarArrowDirectionAny - animated:YES]; + [self.pmCC presentCalendarFromView:sender + permittedArrowDirections:PMCalendarArrowDirectionAny + isPopover:isPopover + animated:YES]; } + self.pmCC.period = [PMPeriod oneDayPeriodWithDate:[NSDate date]]; [self calendarController:pmCC didChangePeriod:pmCC.period]; } diff --git a/README.md b/README.md index 8aefd7f..eac1037 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -PMCalendar v0.2 +PMCalendar v0.3 ========== Yet another calendar component for iOS. Compatible with iOS 4.0 (iPhone & iPad) and higher. @@ -19,9 +19,9 @@ PMCalendar is released under the MIT License. Screenshots ---------- -![Screenshot 1](PMCalendar/raw/master/screenshots/screenshot_1.png)  ![Screenshot 2](PMCalendar/raw/master/screenshots/screenshot_2.png) +![Screenshot 1](http://github.com/kovpas/PMCalendar/raw/master/screenshots/screenshot_1.png)  ![Screenshot 2](http://github.com/kovpas/PMCalendar/raw/master/screenshots/screenshot_2.png) -![Screenshot 3](PMCalendar/raw/master/screenshots/screenshot_3.png) +![Screenshot 3](http://github.com/kovpas/PMCalendar/raw/master/screenshots/screenshot_3.png) Usage ---------- @@ -71,6 +71,7 @@ Usage ``` objective-c [calendarController presentCalendarFromView:pressedButton permittedArrowDirections:PMCalendarArrowDirectionUp | PMCalendarArrowDirectionLeft + isPopover:YES animated:YES]; ``` @@ -80,6 +81,7 @@ Usage [calendarController presentCalendarFromRect:CGRectMake(100, 100, 10, 10) inView:self.view permittedArrowDirections:PMCalendarArrowDirectionUp | PMCalendarArrowDirectionLeft + isPopover:YES animated:YES]; ``` @@ -128,7 +130,7 @@ Implemented properties @property (nonatomic, strong) PMPeriod *period; ``` -*TBI!* **Period allowed for selection** +**Period allowed for selection** ``` objective-c @property (nonatomic, strong) PMPeriod *allowedPeriod; @@ -164,6 +166,12 @@ Implemented properties @property (nonatomic, assign) CGSize size; ``` +**Returns whether the popover is visible (presented) or not** + +``` objective-c + @property (nonatomic, assign, readonly, getter = isCalendarVisible) BOOL calendarVisible; +``` + Themes (beta!) ---------- @@ -171,7 +179,7 @@ Themes allows you to create your own calendar component look without touching PM However, current implementation is powerful enough to create for example something like this: -![Apple calendar theme 1](PMCalendar/raw/master/screenshots/apple_theme_1.png) ![Apple calendar theme 2](PMCalendar/raw/master/screenshots/apple_theme_2.png) +![Apple calendar theme 1](http://github.com/kovpas/PMCalendar/raw/master/screenshots/apple_theme_1.png) ![Apple calendar theme 2](http://github.com/kovpas/PMCalendar/raw/master/screenshots/apple_theme_2.png) Themes documentation is in progress, so for now please use two examples ("default.plist" and "apple calendar.plist") as a refernce.