From fcffba9f2638b9ed7bc16846d86094e5b5bf6e69 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Wed, 8 Jan 2014 18:07:06 +0800 Subject: [PATCH 01/87] Version 0.1.0 --- DayFlow.podspec | 14 - DayFlow/DFDatePickerCollectionView.h | 14 - DayFlow/DFDatePickerCollectionView.m | 13 - DayFlow/DFDatePickerDayCell.h | 9 - DayFlow/DFDatePickerDayCell.m | 144 --------- DayFlow/DFDatePickerMonthHeader.h | 7 - DayFlow/DFDatePickerMonthHeader.m | 17 -- DayFlow/DFDatePickerView.h | 9 - DayFlow/DFDatePickerViewController.h | 16 - DayFlow/DFDatePickerViewController.m | 40 --- DayFlow/DayFlow.h | 8 - DayFlow/NSCalendar+DFAdditions.h | 7 - README.md | 26 +- RSDayFlow.podspec | 14 + .../project.pbxproj | 120 ++++---- RSDayFlow/NSCalendar+RSDFAdditions.h | 7 + .../NSCalendar+RSDFAdditions.m | 9 +- RSDayFlow/RSDFDatePickerCollectionView.h | 15 + RSDayFlow/RSDFDatePickerCollectionView.m | 15 + RSDayFlow/RSDFDatePickerDayCell.h | 15 + RSDayFlow/RSDFDatePickerDayCell.m | 266 ++++++++++++++++ RSDayFlow/RSDFDatePickerMonthHeader.h | 11 + RSDayFlow/RSDFDatePickerMonthHeader.m | 34 +++ RSDayFlow/RSDFDatePickerView.h | 26 ++ .../RSDFDatePickerView.m | 283 ++++++++++-------- .../RSDayFlow-Prefix.pch | 0 RSDayFlow/RSDayFlow.h | 7 + Screenshot.png | Bin 0 -> 34126 bytes 28 files changed, 658 insertions(+), 488 deletions(-) delete mode 100644 DayFlow.podspec delete mode 100644 DayFlow/DFDatePickerCollectionView.h delete mode 100644 DayFlow/DFDatePickerCollectionView.m delete mode 100644 DayFlow/DFDatePickerDayCell.h delete mode 100644 DayFlow/DFDatePickerDayCell.m delete mode 100644 DayFlow/DFDatePickerMonthHeader.h delete mode 100644 DayFlow/DFDatePickerMonthHeader.m delete mode 100644 DayFlow/DFDatePickerView.h delete mode 100644 DayFlow/DFDatePickerViewController.h delete mode 100644 DayFlow/DFDatePickerViewController.m delete mode 100644 DayFlow/DayFlow.h delete mode 100644 DayFlow/NSCalendar+DFAdditions.h create mode 100644 RSDayFlow.podspec rename {DayFlow.xcodeproj => RSDayFlow.xcodeproj}/project.pbxproj (50%) create mode 100644 RSDayFlow/NSCalendar+RSDFAdditions.h rename DayFlow/NSCalendar+DFAdditions.m => RSDayFlow/NSCalendar+RSDFAdditions.m (73%) create mode 100644 RSDayFlow/RSDFDatePickerCollectionView.h create mode 100644 RSDayFlow/RSDFDatePickerCollectionView.m create mode 100644 RSDayFlow/RSDFDatePickerDayCell.h create mode 100644 RSDayFlow/RSDFDatePickerDayCell.m create mode 100644 RSDayFlow/RSDFDatePickerMonthHeader.h create mode 100644 RSDayFlow/RSDFDatePickerMonthHeader.m create mode 100644 RSDayFlow/RSDFDatePickerView.h rename DayFlow/DFDatePickerView.m => RSDayFlow/RSDFDatePickerView.m (57%) rename DayFlow/DayFlow-Prefix.pch => RSDayFlow/RSDayFlow-Prefix.pch (100%) create mode 100644 RSDayFlow/RSDayFlow.h create mode 100644 Screenshot.png diff --git a/DayFlow.podspec b/DayFlow.podspec deleted file mode 100644 index 67086b6..0000000 --- a/DayFlow.podspec +++ /dev/null @@ -1,14 +0,0 @@ -Pod::Spec.new do |s| - s.name = "DayFlow" - s.version = "0.0.2" - s.summary = "Strollable Date Picker." - s.homepage = "http://github.com/evadne/DayFlow" - s.license = 'MIT' - s.author = { "Evadne Wu" => "ev@radi.ws" } - s.source = { :git => "http://github.com/evadne/DayFlow.git", :tag => "0.0.2" } - s.platform = :ios, '6.0' - s.source_files = 'DayFlow', 'DayFlow/**/*.{h,m}' - s.exclude_files = 'DayFlow/Exclude' - s.frameworks = 'QuartzCore', 'UIKit' - s.requires_arc = true -end diff --git a/DayFlow/DFDatePickerCollectionView.h b/DayFlow/DFDatePickerCollectionView.h deleted file mode 100644 index 9e33aba..0000000 --- a/DayFlow/DFDatePickerCollectionView.h +++ /dev/null @@ -1,14 +0,0 @@ -#import - -@class DFDatePickerCollectionView; -@protocol DFDatePickerCollectionViewDelegate - -- (void) pickerCollectionViewWillLayoutSubviews:(DFDatePickerCollectionView *)pickerCollectionView; - -@end - -@interface DFDatePickerCollectionView : UICollectionView - -@property (nonatomic, assign) id delegate; - -@end diff --git a/DayFlow/DFDatePickerCollectionView.m b/DayFlow/DFDatePickerCollectionView.m deleted file mode 100644 index 6c7dad9..0000000 --- a/DayFlow/DFDatePickerCollectionView.m +++ /dev/null @@ -1,13 +0,0 @@ -#import "DFDatePickerCollectionView.h" - -@implementation DFDatePickerCollectionView -@dynamic delegate; - -- (void) layoutSubviews { - - [self.delegate pickerCollectionViewWillLayoutSubviews:self]; - [super layoutSubviews]; - -} - -@end diff --git a/DayFlow/DFDatePickerDayCell.h b/DayFlow/DFDatePickerDayCell.h deleted file mode 100644 index d14fc77..0000000 --- a/DayFlow/DFDatePickerDayCell.h +++ /dev/null @@ -1,9 +0,0 @@ -#import -#import "DayFlow.h" - -@interface DFDatePickerDayCell : UICollectionViewCell - -@property (nonatomic, readwrite, assign) DFDatePickerDate date; -@property (nonatomic, getter=isEnabled) BOOL enabled; - -@end diff --git a/DayFlow/DFDatePickerDayCell.m b/DayFlow/DFDatePickerDayCell.m deleted file mode 100644 index e565732..0000000 --- a/DayFlow/DFDatePickerDayCell.m +++ /dev/null @@ -1,144 +0,0 @@ -#import "DFDatePickerDayCell.h" - -@interface DFDatePickerDayCell () -+ (NSCache *) imageCache; -+ (id) cacheKeyForPickerDate:(DFDatePickerDate)date; -+ (id) fetchObjectForKey:(id)key withCreator:(id(^)(void))block; -@property (nonatomic, readonly, strong) UIImageView *imageView; -@property (nonatomic, readonly, strong) UIView *overlayView; -@end - -@implementation DFDatePickerDayCell -@synthesize imageView = _imageView; -@synthesize overlayView = _overlayView; - -- (id) initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { - self.backgroundColor = [UIColor whiteColor]; - } - return self; -} - -- (void) setDate:(DFDatePickerDate)date { - _date = date; - [self setNeedsLayout]; -} - -- (void) setEnabled:(BOOL)enabled { - _enabled = enabled; - [self setNeedsLayout]; -} - -- (void) setHighlighted:(BOOL)highlighted { - [super setHighlighted:highlighted]; - [self setNeedsLayout]; -} -- (void) setSelected:(BOOL)selected { - [super setSelected:selected]; - [self setNeedsLayout]; -} - -- (void) layoutSubviews { - - [super layoutSubviews]; - - // Instead of using labels, use images keyed by day. - // This avoids redrawing text within labels, which involve lots of parts of - // WebCore and CoreGraphics, and makes sure scrolling is always smooth. - - // Reason: when the view is first shown, all common days are drawn once and cached. - // Memory pressure is also low. - - // Note: Assumption! If there is a calendar with unique day names - // we will be in big trouble. If there is one odd month with 1000 days we will - // also be in some sort of trouble. But for most use cases we are probably good. - - // We still have DFDatePickerMonthHeader take a NSDateFormatter formatted title - // and draw it, but since that’s only one bitmap instead of 35-odd (7 weeks) - // that’s mostly okay. - - self.imageView.alpha = self.enabled ? 1.0f : 0.25f; - - self.imageView.image = [[self class] fetchObjectForKey:[[self class] cacheKeyForPickerDate:self.date] withCreator:^{ - - UIGraphicsBeginImageContextWithOptions(self.bounds.size, YES, self.window.screen.scale); - CGContextRef context = UIGraphicsGetCurrentContext(); - -#if 0 - - // Generate a random color - // https://gist.github.com/kylefox/1689973 - CGFloat hue = ( arc4random() % 256 / 256.0 ); // 0.0 to 1.0 - CGFloat saturation = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from white - CGFloat brightness = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from black - CGContextSetFillColorWithColor(context, [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:1.0f].CGColor); - -#else - - CGContextSetFillColorWithColor(context, [UIColor colorWithRed:53.0f/256.0f green:145.0f/256.0f blue:195.0f/256.0f alpha:1.0f].CGColor); - -#endif - - CGContextFillRect(context, self.bounds); - - UIFont *font = [UIFont boldSystemFontOfSize:20.0f]; - CGRect textBounds = (CGRect){ 0.0f, 10.0f, 44.0f, 24.0f }; - - CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); - [[NSString stringWithFormat:@"%i", self.date.day] drawInRect:textBounds withFont:font lineBreakMode:NSLineBreakByCharWrapping alignment:NSTextAlignmentCenter]; - - UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - - return image; - - }]; - - self.overlayView.hidden = !(self.selected || self.highlighted); - -} - -- (UIView *) overlayView { - if (!_overlayView) { - _overlayView = [[UIView alloc] initWithFrame:self.contentView.bounds]; - _overlayView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; - _overlayView.backgroundColor = [UIColor blackColor]; - _overlayView.alpha = 0.25f; - [self.contentView addSubview:_overlayView]; - } - return _overlayView; -} - -- (UIImageView *) imageView { - if (!_imageView) { - _imageView = [[UIImageView alloc] initWithFrame:self.contentView.bounds]; - _imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; - [self.contentView addSubview:_imageView]; - } - return _imageView; -} - -+ (NSCache *) imageCache { - static NSCache *cache; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - cache = [NSCache new]; - }); - return cache; -} - -+ (id) cacheKeyForPickerDate:(DFDatePickerDate)date { - return @(date.day); -} - -+ (id) fetchObjectForKey:(id)key withCreator:(id(^)(void))block { - id answer = [[self imageCache] objectForKey:key]; - if (!answer) { - answer = block(); - [[self imageCache] setObject:answer forKey:key]; - } - return answer; -} - -@end diff --git a/DayFlow/DFDatePickerMonthHeader.h b/DayFlow/DFDatePickerMonthHeader.h deleted file mode 100644 index 618f0e4..0000000 --- a/DayFlow/DFDatePickerMonthHeader.h +++ /dev/null @@ -1,7 +0,0 @@ -#import - -@interface DFDatePickerMonthHeader : UICollectionReusableView - -@property (nonatomic, readonly, strong) UILabel *textLabel; - -@end diff --git a/DayFlow/DFDatePickerMonthHeader.m b/DayFlow/DFDatePickerMonthHeader.m deleted file mode 100644 index 4199c51..0000000 --- a/DayFlow/DFDatePickerMonthHeader.m +++ /dev/null @@ -1,17 +0,0 @@ -#import "DFDatePickerMonthHeader.h" - -@implementation DFDatePickerMonthHeader -@synthesize textLabel = _textLabel; - -- (UILabel *) textLabel { - if (!_textLabel) { - _textLabel = [[UILabel alloc] initWithFrame:self.bounds]; - _textLabel.textAlignment = NSTextAlignmentCenter; - _textLabel.font = [UIFont boldSystemFontOfSize:20.0f]; - _textLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; - [self addSubview:_textLabel]; - } - return _textLabel; -} - -@end diff --git a/DayFlow/DFDatePickerView.h b/DayFlow/DFDatePickerView.h deleted file mode 100644 index 8700f38..0000000 --- a/DayFlow/DFDatePickerView.h +++ /dev/null @@ -1,9 +0,0 @@ -#import - -@interface DFDatePickerView : UIView - -- (instancetype) initWithCalendar:(NSCalendar *)calendar; - -@property (nonatomic, readwrite, strong) NSDate *selectedDate; - -@end diff --git a/DayFlow/DFDatePickerViewController.h b/DayFlow/DFDatePickerViewController.h deleted file mode 100644 index 5afac2f..0000000 --- a/DayFlow/DFDatePickerViewController.h +++ /dev/null @@ -1,16 +0,0 @@ -#import -#import "DFDatePickerView.h" - -@class DFDatePickerViewController; -@protocol DFDatePickerViewControllerDelegate - -- (void) datePickerViewController:(DFDatePickerViewController *)controller didSelectDate:(NSDate *)date; - -@end - -@interface DFDatePickerViewController : UIViewController - -@property (nonatomic, readonly, strong) DFDatePickerView *datePickerView; -@property (nonatomic, readwrite, weak) id delegate; - -@end diff --git a/DayFlow/DFDatePickerViewController.m b/DayFlow/DFDatePickerViewController.m deleted file mode 100644 index 1e934c6..0000000 --- a/DayFlow/DFDatePickerViewController.m +++ /dev/null @@ -1,40 +0,0 @@ -#import "DFDatePickerViewController.h" - -@implementation DFDatePickerViewController -@synthesize datePickerView = _datePickerView; - -- (void) viewDidLoad { - [super viewDidLoad]; - [self.view addSubview:self.datePickerView]; -} - -- (DFDatePickerView *) datePickerView { - if (!_datePickerView) { - _datePickerView = [DFDatePickerView new]; - _datePickerView.frame = self.view.bounds; - _datePickerView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; - } - return _datePickerView; -} - -- (void) viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - [self addObserver:self forKeyPath:@"datePickerView.selectedDate" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:(void *)self]; -} - -- (void) viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [self removeObserver:self forKeyPath:@"datePickerView.selectedDate" context:(void *)self]; -} - -- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { - if ([keyPath isEqualToString:@"datePickerView.selectedDate"]) { - NSDate *toDate = change[NSKeyValueChangeNewKey]; - if ([toDate isKindOfClass:[NSDate class]]) { - // toDate might be NSNull - [self.delegate datePickerViewController:self didSelectDate:toDate]; - } - } -} - -@end diff --git a/DayFlow/DayFlow.h b/DayFlow/DayFlow.h deleted file mode 100644 index e31aec1..0000000 --- a/DayFlow/DayFlow.h +++ /dev/null @@ -1,8 +0,0 @@ -typedef struct { - NSUInteger year; - NSUInteger month; - NSUInteger day; -} DFDatePickerDate; - -#import "DFDatePickerView.h" -#import "DFDatePickerViewController.h" diff --git a/DayFlow/NSCalendar+DFAdditions.h b/DayFlow/NSCalendar+DFAdditions.h deleted file mode 100644 index 027d6f9..0000000 --- a/DayFlow/NSCalendar+DFAdditions.h +++ /dev/null @@ -1,7 +0,0 @@ -#import - -@interface NSCalendar (DFAdditions) - -- (NSDateFormatter *) df_dateFormatterNamed:(NSString *)name withConstructor:(NSDateFormatter *(^)(void))block; - -@end diff --git a/README.md b/README.md index ec5d042..a6f46e8 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,37 @@ -# DayFlow +# RSDayFlow -iOS Date Picker + Infinite Scrolling. + + +> [RSDayFlow](https://github.com/ruslanskorb/RSDayFlow) is a slim fork of [DayFlow](https://github.com/evadne/DayFlow) with updates and extensions: + +> * Possibility to mark the date +* 2 colours of marks that can be used in the Task Manager (gray color - days with uncompleted tasks, green color - days with completed tasks) +* Design like iOS 7 +* Some other updates + +iOS 7 Date Picker + Infinite Scrolling. ## Play -Look at the [Sample App](https://github.com/evadne/DayFlow-Sample). Check out the [Sample Video](http://vimeo.com/evadne/dayflow-debut). Have fun. Make it faster. Fork and send pull requests. Figure out hooks for customization. +Look at the [Sample App](https://github.com/ruslanskorb/RSDayFlow-Sample). Have fun. Make it faster. Fork and send pull requests. Figure out hooks for customization. ## Use -Plop `DFDatePickerViewController` in, and implement the one method in ``: +Plop `RSDFDatePickerView` in, and implement the one method in ``: + + - (void)datePickerView:(RSDFDatePickerView *)view didSelectDate:(NSDate *)date; + +Or implement the one method in `RSDFDatePickerViewDataSource`: - - (void) datePickerViewController:(DFDatePickerViewController *)controller didSelectDate:(NSDate *)date; + - (NSDictionary *)datePickerViewMarkedDates:(RSDFDatePickerView *)view; That pretty much sums up what it does. ## Licensing -This project is in the public domain. You can embed it in works for hire or use it for evil. Attribution by linking to the [project page](https://github.com/evadne/DayFlow) and chocolate delivery is appreciated. +This project is in the public domain. You can embed it in works for hire or use it for evil. Attribution by linking to the [project page](https://github.com/ruslanskorb/RSDayFlow) and chocolate delivery is appreciated. ## Credits * [Evadne Wu](http://radi.ws) +* [Ruslan Skorb](http://lnkd.in/gsBbvb) \ No newline at end of file diff --git a/RSDayFlow.podspec b/RSDayFlow.podspec new file mode 100644 index 0000000..93f2cf7 --- /dev/null +++ b/RSDayFlow.podspec @@ -0,0 +1,14 @@ +Pod::Spec.new do |s| + s.name = 'RSDayFlow' + s.version = '0.1.0' + s.summary = 'Scrollable iOS 7 Date Picker.' + s.homepage = 'http://github.com/ruslanskorb/RSDayFlow' + s.license = 'MIT' + s.authors = { 'Evadne Wu' => 'ev@radi.ws', 'Ruslan Skorb' => 'ruslan.skorb@gmail.com' } + s.source = { :git => 'http://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.1.0' } + s.platform = :ios, '7.0' + s.source_files = 'RSDayFlow', 'RSDayFlow/**/*.{h,m}' + s.exclude_files = 'RSDayFlow/Exclude' + s.frameworks = 'QuartzCore', 'UIKit' + s.requires_arc = true +end diff --git a/DayFlow.xcodeproj/project.pbxproj b/RSDayFlow.xcodeproj/project.pbxproj similarity index 50% rename from DayFlow.xcodeproj/project.pbxproj rename to RSDayFlow.xcodeproj/project.pbxproj index 97539ee..da9ec87 100644 --- a/DayFlow.xcodeproj/project.pbxproj +++ b/RSDayFlow.xcodeproj/project.pbxproj @@ -7,14 +7,13 @@ objects = { /* Begin PBXBuildFile section */ + B8726564187C12BB000C1895 /* NSCalendar+RSDFAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = B8726558187C12BB000C1895 /* NSCalendar+RSDFAdditions.m */; }; + B8726565187C12BB000C1895 /* RSDFDatePickerCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = B872655B187C12BB000C1895 /* RSDFDatePickerCollectionView.m */; }; + B8726566187C12BB000C1895 /* RSDFDatePickerDayCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B872655D187C12BB000C1895 /* RSDFDatePickerDayCell.m */; }; + B8726567187C12BB000C1895 /* RSDFDatePickerMonthHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = B872655F187C12BB000C1895 /* RSDFDatePickerMonthHeader.m */; }; + B8726568187C12BB000C1895 /* RSDFDatePickerView.m in Sources */ = {isa = PBXBuildFile; fileRef = B8726561187C12BB000C1895 /* RSDFDatePickerView.m */; }; + B88EB3C5187BB6F100D8E2B8 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B88EB3C4187BB6F100D8E2B8 /* QuartzCore.framework */; }; FF2A69CE172D2C07005A1A21 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FF2A69CD172D2C07005A1A21 /* Foundation.framework */; }; - FF2A69D3172D2C07005A1A21 /* DayFlow.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = FF2A69D2172D2C07005A1A21 /* DayFlow.h */; }; - FF2A69DD172D2C64005A1A21 /* DFDatePickerView.m in Sources */ = {isa = PBXBuildFile; fileRef = FF2A69DC172D2C64005A1A21 /* DFDatePickerView.m */; }; - FFB686AD172E8A660027ADF2 /* NSCalendar+DFAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = FFB686A3172E8A660027ADF2 /* NSCalendar+DFAdditions.m */; }; - FFB686AE172E8A660027ADF2 /* DFDatePickerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FFB686A5172E8A660027ADF2 /* DFDatePickerViewController.m */; }; - FFB686AF172E8A660027ADF2 /* DFDatePickerMonthHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = FFB686A7172E8A660027ADF2 /* DFDatePickerMonthHeader.m */; }; - FFB686B0172E8A660027ADF2 /* DFDatePickerDayCell.m in Sources */ = {isa = PBXBuildFile; fileRef = FFB686A9172E8A660027ADF2 /* DFDatePickerDayCell.m */; }; - FFB686B1172E8A660027ADF2 /* DFDatePickerCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = FFB686AB172E8A660027ADF2 /* DFDatePickerCollectionView.m */; }; FFB686B3172E8A970027ADF2 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FFB686B2172E8A970027ADF2 /* UIKit.framework */; }; /* End PBXBuildFile section */ @@ -25,29 +24,27 @@ dstPath = "include/${PRODUCT_NAME}"; dstSubfolderSpec = 16; files = ( - FF2A69D3172D2C07005A1A21 /* DayFlow.h in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - FF2A69CA172D2C07005A1A21 /* libDayFlow.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libDayFlow.a; sourceTree = BUILT_PRODUCTS_DIR; }; + B8726557187C12BB000C1895 /* NSCalendar+RSDFAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSCalendar+RSDFAdditions.h"; path = "RSDayFlow/NSCalendar+RSDFAdditions.h"; sourceTree = ""; }; + B8726558187C12BB000C1895 /* NSCalendar+RSDFAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSCalendar+RSDFAdditions.m"; path = "RSDayFlow/NSCalendar+RSDFAdditions.m"; sourceTree = ""; }; + B8726559187C12BB000C1895 /* RSDayFlow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RSDayFlow.h; path = RSDayFlow/RSDayFlow.h; sourceTree = ""; }; + B872655A187C12BB000C1895 /* RSDFDatePickerCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RSDFDatePickerCollectionView.h; path = RSDayFlow/RSDFDatePickerCollectionView.h; sourceTree = ""; }; + B872655B187C12BB000C1895 /* RSDFDatePickerCollectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RSDFDatePickerCollectionView.m; path = RSDayFlow/RSDFDatePickerCollectionView.m; sourceTree = ""; }; + B872655C187C12BB000C1895 /* RSDFDatePickerDayCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RSDFDatePickerDayCell.h; path = RSDayFlow/RSDFDatePickerDayCell.h; sourceTree = ""; }; + B872655D187C12BB000C1895 /* RSDFDatePickerDayCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RSDFDatePickerDayCell.m; path = RSDayFlow/RSDFDatePickerDayCell.m; sourceTree = ""; }; + B872655E187C12BB000C1895 /* RSDFDatePickerMonthHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RSDFDatePickerMonthHeader.h; path = RSDayFlow/RSDFDatePickerMonthHeader.h; sourceTree = ""; }; + B872655F187C12BB000C1895 /* RSDFDatePickerMonthHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RSDFDatePickerMonthHeader.m; path = RSDayFlow/RSDFDatePickerMonthHeader.m; sourceTree = ""; }; + B8726560187C12BB000C1895 /* RSDFDatePickerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RSDFDatePickerView.h; path = RSDayFlow/RSDFDatePickerView.h; sourceTree = ""; }; + B8726561187C12BB000C1895 /* RSDFDatePickerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RSDFDatePickerView.m; path = RSDayFlow/RSDFDatePickerView.m; sourceTree = ""; }; + B872656A187C12CD000C1895 /* RSDayFlow-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "RSDayFlow-Prefix.pch"; path = "RSDayFlow/RSDayFlow-Prefix.pch"; sourceTree = SOURCE_ROOT; }; + B88EB3C4187BB6F100D8E2B8 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + FF2A69CA172D2C07005A1A21 /* libRSDayFlow.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRSDayFlow.a; sourceTree = BUILT_PRODUCTS_DIR; }; FF2A69CD172D2C07005A1A21 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - FF2A69D1172D2C07005A1A21 /* DayFlow-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "DayFlow-Prefix.pch"; sourceTree = ""; }; - FF2A69D2172D2C07005A1A21 /* DayFlow.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DayFlow.h; path = DayFlow/DayFlow.h; sourceTree = ""; }; - FF2A69DB172D2C64005A1A21 /* DFDatePickerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFDatePickerView.h; path = DayFlow/DFDatePickerView.h; sourceTree = ""; }; - FF2A69DC172D2C64005A1A21 /* DFDatePickerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DFDatePickerView.m; path = DayFlow/DFDatePickerView.m; sourceTree = ""; }; - FFB686A3172E8A660027ADF2 /* NSCalendar+DFAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSCalendar+DFAdditions.m"; path = "DayFlow/NSCalendar+DFAdditions.m"; sourceTree = ""; }; - FFB686A4172E8A660027ADF2 /* NSCalendar+DFAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSCalendar+DFAdditions.h"; path = "DayFlow/NSCalendar+DFAdditions.h"; sourceTree = ""; }; - FFB686A5172E8A660027ADF2 /* DFDatePickerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DFDatePickerViewController.m; path = DayFlow/DFDatePickerViewController.m; sourceTree = ""; }; - FFB686A6172E8A660027ADF2 /* DFDatePickerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFDatePickerViewController.h; path = DayFlow/DFDatePickerViewController.h; sourceTree = ""; }; - FFB686A7172E8A660027ADF2 /* DFDatePickerMonthHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DFDatePickerMonthHeader.m; path = DayFlow/DFDatePickerMonthHeader.m; sourceTree = ""; }; - FFB686A8172E8A660027ADF2 /* DFDatePickerMonthHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFDatePickerMonthHeader.h; path = DayFlow/DFDatePickerMonthHeader.h; sourceTree = ""; }; - FFB686A9172E8A660027ADF2 /* DFDatePickerDayCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DFDatePickerDayCell.m; path = DayFlow/DFDatePickerDayCell.m; sourceTree = ""; }; - FFB686AA172E8A660027ADF2 /* DFDatePickerDayCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFDatePickerDayCell.h; path = DayFlow/DFDatePickerDayCell.h; sourceTree = ""; }; - FFB686AB172E8A660027ADF2 /* DFDatePickerCollectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DFDatePickerCollectionView.m; path = DayFlow/DFDatePickerCollectionView.m; sourceTree = ""; }; - FFB686AC172E8A660027ADF2 /* DFDatePickerCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFDatePickerCollectionView.h; path = DayFlow/DFDatePickerCollectionView.h; sourceTree = ""; }; FFB686B2172E8A970027ADF2 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; /* End PBXFileReference section */ @@ -56,6 +53,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + B88EB3C5187BB6F100D8E2B8 /* QuartzCore.framework in Frameworks */, FF2A69CE172D2C07005A1A21 /* Foundation.framework in Frameworks */, FFB686B3172E8A970027ADF2 /* UIKit.framework in Frameworks */, ); @@ -64,22 +62,28 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + B872656B187C1332000C1895 /* RSDayFlow */ = { + isa = PBXGroup; + children = ( + B8726559187C12BB000C1895 /* RSDayFlow.h */, + B8726560187C12BB000C1895 /* RSDFDatePickerView.h */, + B8726561187C12BB000C1895 /* RSDFDatePickerView.m */, + B872655A187C12BB000C1895 /* RSDFDatePickerCollectionView.h */, + B872655B187C12BB000C1895 /* RSDFDatePickerCollectionView.m */, + B872655C187C12BB000C1895 /* RSDFDatePickerDayCell.h */, + B872655D187C12BB000C1895 /* RSDFDatePickerDayCell.m */, + B872655E187C12BB000C1895 /* RSDFDatePickerMonthHeader.h */, + B872655F187C12BB000C1895 /* RSDFDatePickerMonthHeader.m */, + B8726557187C12BB000C1895 /* NSCalendar+RSDFAdditions.h */, + B8726558187C12BB000C1895 /* NSCalendar+RSDFAdditions.m */, + ); + name = RSDayFlow; + sourceTree = ""; + }; FF2A69C1172D2C06005A1A21 = { isa = PBXGroup; children = ( - FF2A69D2172D2C07005A1A21 /* DayFlow.h */, - FFB686A6172E8A660027ADF2 /* DFDatePickerViewController.h */, - FFB686A5172E8A660027ADF2 /* DFDatePickerViewController.m */, - FF2A69DB172D2C64005A1A21 /* DFDatePickerView.h */, - FF2A69DC172D2C64005A1A21 /* DFDatePickerView.m */, - FFB686AC172E8A660027ADF2 /* DFDatePickerCollectionView.h */, - FFB686AB172E8A660027ADF2 /* DFDatePickerCollectionView.m */, - FFB686A8172E8A660027ADF2 /* DFDatePickerMonthHeader.h */, - FFB686A7172E8A660027ADF2 /* DFDatePickerMonthHeader.m */, - FFB686AA172E8A660027ADF2 /* DFDatePickerDayCell.h */, - FFB686A9172E8A660027ADF2 /* DFDatePickerDayCell.m */, - FFB686A4172E8A660027ADF2 /* NSCalendar+DFAdditions.h */, - FFB686A3172E8A660027ADF2 /* NSCalendar+DFAdditions.m */, + B872656B187C1332000C1895 /* RSDayFlow */, FF2A69D0172D2C07005A1A21 /* Supporting Files */, FF2A69CC172D2C07005A1A21 /* Frameworks */, FF2A69CB172D2C07005A1A21 /* Products */, @@ -89,7 +93,7 @@ FF2A69CB172D2C07005A1A21 /* Products */ = { isa = PBXGroup; children = ( - FF2A69CA172D2C07005A1A21 /* libDayFlow.a */, + FF2A69CA172D2C07005A1A21 /* libRSDayFlow.a */, ); name = Products; sourceTree = ""; @@ -99,6 +103,7 @@ children = ( FF2A69CD172D2C07005A1A21 /* Foundation.framework */, FFB686B2172E8A970027ADF2 /* UIKit.framework */, + B88EB3C4187BB6F100D8E2B8 /* QuartzCore.framework */, ); name = Frameworks; sourceTree = ""; @@ -106,7 +111,7 @@ FF2A69D0172D2C07005A1A21 /* Supporting Files */ = { isa = PBXGroup; children = ( - FF2A69D1172D2C07005A1A21 /* DayFlow-Prefix.pch */, + B872656A187C12CD000C1895 /* RSDayFlow-Prefix.pch */, ); name = "Supporting Files"; path = DayFlow; @@ -115,9 +120,9 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - FF2A69C9172D2C07005A1A21 /* DayFlow */ = { + FF2A69C9172D2C07005A1A21 /* RSDayFlow */ = { isa = PBXNativeTarget; - buildConfigurationList = FF2A69D8172D2C07005A1A21 /* Build configuration list for PBXNativeTarget "DayFlow" */; + buildConfigurationList = FF2A69D8172D2C07005A1A21 /* Build configuration list for PBXNativeTarget "RSDayFlow" */; buildPhases = ( FF2A69C6172D2C07005A1A21 /* Sources */, FF2A69C7172D2C07005A1A21 /* Frameworks */, @@ -127,9 +132,9 @@ ); dependencies = ( ); - name = DayFlow; + name = RSDayFlow; productName = DayFlow; - productReference = FF2A69CA172D2C07005A1A21 /* libDayFlow.a */; + productReference = FF2A69CA172D2C07005A1A21 /* libRSDayFlow.a */; productType = "com.apple.product-type.library.static"; }; /* End PBXNativeTarget section */ @@ -140,7 +145,7 @@ attributes = { ORGANIZATIONNAME = Radius; }; - buildConfigurationList = FF2A69C5172D2C06005A1A21 /* Build configuration list for PBXProject "DayFlow" */; + buildConfigurationList = FF2A69C5172D2C06005A1A21 /* Build configuration list for PBXProject "RSDayFlow" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; @@ -152,7 +157,7 @@ projectDirPath = ""; projectRoot = ""; targets = ( - FF2A69C9172D2C07005A1A21 /* DayFlow */, + FF2A69C9172D2C07005A1A21 /* RSDayFlow */, ); }; /* End PBXProject section */ @@ -162,12 +167,11 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - FF2A69DD172D2C64005A1A21 /* DFDatePickerView.m in Sources */, - FFB686AD172E8A660027ADF2 /* NSCalendar+DFAdditions.m in Sources */, - FFB686AE172E8A660027ADF2 /* DFDatePickerViewController.m in Sources */, - FFB686AF172E8A660027ADF2 /* DFDatePickerMonthHeader.m in Sources */, - FFB686B0172E8A660027ADF2 /* DFDatePickerDayCell.m in Sources */, - FFB686B1172E8A660027ADF2 /* DFDatePickerCollectionView.m in Sources */, + B8726568187C12BB000C1895 /* RSDFDatePickerView.m in Sources */, + B8726567187C12BB000C1895 /* RSDFDatePickerMonthHeader.m in Sources */, + B8726564187C12BB000C1895 /* NSCalendar+RSDFAdditions.m in Sources */, + B8726566187C12BB000C1895 /* RSDFDatePickerDayCell.m in Sources */, + B8726565187C12BB000C1895 /* RSDFDatePickerCollectionView.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -198,7 +202,7 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 6.1; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; @@ -221,7 +225,7 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 6.1; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; @@ -232,9 +236,9 @@ buildSettings = { DSTROOT = /tmp/DayFlow.dst; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "DayFlow/DayFlow-Prefix.pch"; + GCC_PREFIX_HEADER = "DayFlow/RSDayFlow-Prefix.pch"; OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_NAME = RSDayFlow; SKIP_INSTALL = YES; }; name = Debug; @@ -244,9 +248,9 @@ buildSettings = { DSTROOT = /tmp/DayFlow.dst; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "DayFlow/DayFlow-Prefix.pch"; + GCC_PREFIX_HEADER = "DayFlow/RSDayFlow-Prefix.pch"; OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_NAME = RSDayFlow; SKIP_INSTALL = YES; }; name = Release; @@ -254,7 +258,7 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - FF2A69C5172D2C06005A1A21 /* Build configuration list for PBXProject "DayFlow" */ = { + FF2A69C5172D2C06005A1A21 /* Build configuration list for PBXProject "RSDayFlow" */ = { isa = XCConfigurationList; buildConfigurations = ( FF2A69D6172D2C07005A1A21 /* Debug */, @@ -263,7 +267,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - FF2A69D8172D2C07005A1A21 /* Build configuration list for PBXNativeTarget "DayFlow" */ = { + FF2A69D8172D2C07005A1A21 /* Build configuration list for PBXNativeTarget "RSDayFlow" */ = { isa = XCConfigurationList; buildConfigurations = ( FF2A69D9172D2C07005A1A21 /* Debug */, diff --git a/RSDayFlow/NSCalendar+RSDFAdditions.h b/RSDayFlow/NSCalendar+RSDFAdditions.h new file mode 100644 index 0000000..2503446 --- /dev/null +++ b/RSDayFlow/NSCalendar+RSDFAdditions.h @@ -0,0 +1,7 @@ +#import + +@interface NSCalendar (RSDFAdditions) + +- (NSDateFormatter *)df_dateFormatterNamed:(NSString *)name withConstructor:(NSDateFormatter *(^)(void))block; + +@end diff --git a/DayFlow/NSCalendar+DFAdditions.m b/RSDayFlow/NSCalendar+RSDFAdditions.m similarity index 73% rename from DayFlow/NSCalendar+DFAdditions.m rename to RSDayFlow/NSCalendar+RSDFAdditions.m index 131105a..7ce902d 100644 --- a/DayFlow/NSCalendar+DFAdditions.m +++ b/RSDayFlow/NSCalendar+RSDFAdditions.m @@ -1,9 +1,9 @@ -#import "NSCalendar+DFAdditions.h" +#import "NSCalendar+RSDFAdditions.h" -@implementation NSCalendar (DFAdditions) +@implementation NSCalendar (RSDFAdditions) -- (NSDateFormatter *) df_dateFormatterNamed:(NSString *)name withConstructor:(NSDateFormatter *(^)(void))block { - +- (NSDateFormatter *)df_dateFormatterNamed:(NSString *)name withConstructor:(NSDateFormatter *(^)(void))block +{ // We can not use objc_setAssociatedObject() because it has no thread safety // Modeled after http://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html // Intended for use where there are a myriad of date formatters keyed on a calendar @@ -17,7 +17,6 @@ - (NSDateFormatter *) df_dateFormatterNamed:(NSString *)name withConstructor:(NS } return dateFormatter; - } @end diff --git a/RSDayFlow/RSDFDatePickerCollectionView.h b/RSDayFlow/RSDFDatePickerCollectionView.h new file mode 100644 index 0000000..9045311 --- /dev/null +++ b/RSDayFlow/RSDFDatePickerCollectionView.h @@ -0,0 +1,15 @@ +#import + +@class RSDFDatePickerCollectionView; + +@protocol RSDFDatePickerCollectionViewDelegate + +- (void) pickerCollectionViewWillLayoutSubviews:(RSDFDatePickerCollectionView *)pickerCollectionView; + +@end + +@interface RSDFDatePickerCollectionView : UICollectionView + +@property (nonatomic, assign) id delegate; + +@end diff --git a/RSDayFlow/RSDFDatePickerCollectionView.m b/RSDayFlow/RSDFDatePickerCollectionView.m new file mode 100644 index 0000000..956c5ff --- /dev/null +++ b/RSDayFlow/RSDFDatePickerCollectionView.m @@ -0,0 +1,15 @@ +#import "RSDFDatePickerCollectionView.h" + +@implementation RSDFDatePickerCollectionView + +@dynamic delegate; + +- (void)layoutSubviews +{ + if ([self.delegate respondsToSelector:@selector(pickerCollectionViewWillLayoutSubviews:)]) { + [self.delegate pickerCollectionViewWillLayoutSubviews:self]; + } + [super layoutSubviews]; +} + +@end diff --git a/RSDayFlow/RSDFDatePickerDayCell.h b/RSDayFlow/RSDFDatePickerDayCell.h new file mode 100644 index 0000000..74b1721 --- /dev/null +++ b/RSDayFlow/RSDFDatePickerDayCell.h @@ -0,0 +1,15 @@ +#import +#import "RSDayFlow.h" + +@interface RSDFDatePickerDayCell : UICollectionViewCell + +@property (nonatomic, readwrite, assign) RSDFDatePickerDate date; +@property (nonatomic, readonly, strong) UILabel *dateLabel; + +@property (nonatomic, getter = isEnabled) BOOL enabled; +@property (nonatomic, getter = isDayOff) BOOL dayOff; +@property (nonatomic, getter = isMarked) BOOL marked; +@property (nonatomic, getter = isCompleted) BOOL completed; +@property (nonatomic, getter = isToday) BOOL today; + +@end diff --git a/RSDayFlow/RSDFDatePickerDayCell.m b/RSDayFlow/RSDFDatePickerDayCell.m new file mode 100644 index 0000000..5d9cf6a --- /dev/null +++ b/RSDayFlow/RSDFDatePickerDayCell.m @@ -0,0 +1,266 @@ +#import "RSDFDatePickerDayCell.h" + +@interface RSDFDatePickerDayCell () + ++ (NSCache *)imageCache; ++ (id)fetchObjectForKey:(id)key withCreator:(id(^)(void))block; + +@property (nonatomic, readonly, strong) UIImageView *dividerTopImageView; +@property (nonatomic, readonly, strong) UIImageView *markerImageView; +@property (nonatomic, readonly, strong) UIImageView *overlayImageView; +@property (nonatomic, readonly, strong) UIImageView *todayImageView; + +@end + +@implementation RSDFDatePickerDayCell + +@synthesize dateLabel = _dateLabel; +@synthesize dividerTopImageView = _dividerTopImageView; +@synthesize markerImageView = _markerImageView; +@synthesize overlayImageView = _overlayImageView; +@synthesize todayImageView = _todayImageView; + +- (id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + [self commonInitializer]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)aDecoder +{ + self = [super initWithCoder:aDecoder]; + if (self) { + [self commonInitializer]; + } + return self; +} + +- (void)commonInitializer +{ + self.backgroundColor = [UIColor whiteColor]; + self.dividerTopImageView.hidden = NO; + self.dateLabel.hidden = NO; + self.todayImageView.hidden = YES; + self.overlayImageView.hidden = YES; + self.markerImageView.hidden = YES; +} + +- (void)setDate:(RSDFDatePickerDate)date +{ + _date = date; +} + +- (void)setEnabled:(BOOL)enabled +{ + _enabled = enabled; + if (!_enabled) { + self.todayImageView.hidden = YES; + self.markerImageView.hidden = YES; + } + self.dateLabel.hidden = !_enabled; + self.dividerTopImageView.hidden = !_enabled; +} + +- (void)setDayOff:(BOOL)dayOff +{ + _dayOff = dayOff; + if (!_dayOff) { + self.dateLabel.textColor = [UIColor blackColor]; + } else { + self.dateLabel.textColor = [UIColor colorWithRed:184/255.0f green:184/255.0f blue:184/255.0f alpha:1.0f]; + } +} + +- (void)setMarked:(BOOL)marked +{ + _marked = marked; + self.markerImageView.hidden = !_marked; +} + +- (void)setCompleted:(BOOL)completed +{ + _completed = completed; + if (_completed) { + self.markerImageView.image = [[self class] fetchObjectForKey:@"img_marker_green" withCreator:^id{ + UIGraphicsBeginImageContextWithOptions(_markerImageView.frame.size, NO, self.window.screen.scale); + CGContextRef context = UIGraphicsGetCurrentContext(); + + CGRect rect = _markerImageView.frame; + rect.origin = CGPointZero; + + CGContextSetFillColorWithColor(context, [UIColor colorWithRed:83/255.0f green:215/255.0f blue:105/255.0f alpha:1.0f].CGColor); + CGContextFillEllipseInRect(context, rect); + + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return image; + }]; + } else { + self.markerImageView.image = [[self class] fetchObjectForKey:@"img_marker_gray" withCreator:^id{ + UIGraphicsBeginImageContextWithOptions(_markerImageView.frame.size, NO, self.window.screen.scale); + CGContextRef context = UIGraphicsGetCurrentContext(); + + CGRect rect = _markerImageView.frame; + rect.origin = CGPointZero; + + CGContextSetFillColorWithColor(context, [UIColor colorWithRed:184/255.0f green:184/255.0f blue:184/255.0f alpha:1.0f].CGColor); + CGContextFillEllipseInRect(context, rect); + + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return image; + }]; + } +} + +- (void)setToday:(BOOL)today +{ + _today = today; + if (!_today) { + self.dateLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:18.0f]; + } else { + self.dateLabel.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:18.0f]; + self.dateLabel.textColor = [UIColor whiteColor]; + } + self.todayImageView.hidden = !_today; +} + +- (void)setHighlighted:(BOOL)highlighted +{ + [super setHighlighted:highlighted]; + self.overlayImageView.hidden = !(self.highlighted); +} + +- (UIImageView *)todayImageView +{ + if (!_todayImageView) { + CGRect frame = CGRectMake(0.0f, 0.0f, 35.0f, 35.0f); + _todayImageView = [[UIImageView alloc] initWithFrame:frame]; + _todayImageView.center = CGPointMake(self.frame.size.width/2, 23.0f); + _todayImageView.backgroundColor = [UIColor clearColor]; + + _todayImageView.image = [[self class] fetchObjectForKey:@"img_today" withCreator:^id{ + UIGraphicsBeginImageContextWithOptions(_todayImageView.frame.size, NO, self.window.screen.scale); + CGContextRef context = UIGraphicsGetCurrentContext(); + + CGRect rect = _todayImageView.frame; + rect.origin = CGPointZero; + + CGContextSetFillColorWithColor(context, [UIColor colorWithRed:0/255.0f green:121/255.0f blue:255/255.0f alpha:1.0f].CGColor); + CGContextFillEllipseInRect(context, rect); + + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return image; + }]; + + [self.contentView addSubview:_todayImageView]; + } + return _todayImageView; +} + +- (UIImageView *)dividerTopImageView +{ + if (!_dividerTopImageView) { + CGRect frame = CGRectMake(0.0f, 0.0f, 50.0f, 0.5f); + _dividerTopImageView = [[UIImageView alloc] initWithFrame:frame]; + + _dividerTopImageView.image = [[self class] fetchObjectForKey:@"img_divider_top" withCreator:^id{ + UIGraphicsBeginImageContextWithOptions(_dividerTopImageView.frame.size, NO, self.window.screen.scale); + CGContextRef context = UIGraphicsGetCurrentContext(); + CGContextSetFillColorWithColor(context, [UIColor colorWithRed:200/255.0f green:200/255.0f blue:200/255.0f alpha:1.0f].CGColor); + CGContextFillRect(context, _dividerTopImageView.frame); + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return image; + }]; + + [self.contentView addSubview:_dividerTopImageView]; + } + return _dividerTopImageView; +} + +- (UIImageView *)overlayImageView +{ + if (!_overlayImageView) { + _overlayImageView = [[UIImageView alloc] initWithFrame:self.todayImageView.frame]; + + _overlayImageView.image = [[self class] fetchObjectForKey:@"img_overlay" withCreator:^id{ + UIGraphicsBeginImageContextWithOptions(_overlayImageView.frame.size, NO, self.window.screen.scale); + CGContextRef context = UIGraphicsGetCurrentContext(); + + CGRect rect = _overlayImageView.frame; + rect.origin = CGPointZero; + + CGContextSetFillColorWithColor(context, [UIColor colorWithRed:184/255.0f green:184/255.0f blue:184/255.0f alpha:1.0f].CGColor); + CGContextFillEllipseInRect(context, rect); + + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return image; + }]; + + _overlayImageView.opaque = YES; + _overlayImageView.alpha = 0.5f; + [self.contentView addSubview:_overlayImageView]; + } + return _overlayImageView; +} + +- (UILabel *)dateLabel +{ + if (!_dateLabel) { + CGRect frame = CGRectMake(self.bounds.origin.x, + self.todayImageView.frame.origin.y, + self.bounds.size.width, + self.todayImageView.frame.size.height); + _dateLabel = [[UILabel alloc] initWithFrame:frame]; + _dateLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; + _dateLabel.textAlignment = NSTextAlignmentCenter; + _dateLabel.backgroundColor = [UIColor clearColor]; + [self.contentView addSubview:_dateLabel]; + } + return _dateLabel; +} + +- (UIImageView *)markerImageView +{ + if (!_markerImageView) { + CGRect frame = CGRectMake(0.0f, 0.0f, 9.0f, 9.0f); + _markerImageView = [[UIImageView alloc] initWithFrame:frame]; + CGFloat centerX = self.frame.size.width / 2; + CGFloat centerY = 50.0f; + _markerImageView.center = CGPointMake(centerX, centerY); + [self.contentView addSubview:_markerImageView]; + } + return _markerImageView; +} + ++ (NSCache *)imageCache +{ + static NSCache *cache; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + cache = [NSCache new]; + }); + return cache; +} + ++ (id)fetchObjectForKey:(id)key withCreator:(id(^)(void))block +{ + id answer = [[self imageCache] objectForKey:key]; + if (!answer) { + answer = block(); + [[self imageCache] setObject:answer forKey:key]; + } + return answer; +} + +@end diff --git a/RSDayFlow/RSDFDatePickerMonthHeader.h b/RSDayFlow/RSDFDatePickerMonthHeader.h new file mode 100644 index 0000000..2f6ec29 --- /dev/null +++ b/RSDayFlow/RSDFDatePickerMonthHeader.h @@ -0,0 +1,11 @@ +#import +#import "RSDayFlow.h" + +@interface RSDFDatePickerMonthHeader : UICollectionReusableView + +@property (nonatomic, readwrite, assign) RSDFDatePickerDate date; +@property (nonatomic, readonly, strong) UILabel *dateLabel; + +@property (nonatomic, getter = isCurrentMonth) BOOL currentMonth; + +@end diff --git a/RSDayFlow/RSDFDatePickerMonthHeader.m b/RSDayFlow/RSDFDatePickerMonthHeader.m new file mode 100644 index 0000000..b79a14f --- /dev/null +++ b/RSDayFlow/RSDFDatePickerMonthHeader.m @@ -0,0 +1,34 @@ +#import "RSDFDatePickerMonthHeader.h" + +@implementation RSDFDatePickerMonthHeader + +@synthesize dateLabel = _dateLabel; + +- (UILabel *)dateLabel +{ + if (!_dateLabel) { + _dateLabel = [[UILabel alloc] initWithFrame:self.bounds]; + _dateLabel.textAlignment = NSTextAlignmentCenter; + _dateLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:16.0f]; + _dateLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; + [self addSubview:_dateLabel]; + } + return _dateLabel; +} + +- (void)setDate:(RSDFDatePickerDate)date +{ + _date = date; +} + +- (void)setCurrentMonth:(BOOL)currentMonth +{ + _currentMonth = currentMonth; + if (_currentMonth) { + self.dateLabel.textColor = [UIColor colorWithRed:32/255.0f green:135/255.0f blue:252/255.0f alpha:1.0f]; + } else { + self.dateLabel.textColor = [UIColor blackColor]; + } +} + +@end diff --git a/RSDayFlow/RSDFDatePickerView.h b/RSDayFlow/RSDFDatePickerView.h new file mode 100644 index 0000000..d32a1c5 --- /dev/null +++ b/RSDayFlow/RSDFDatePickerView.h @@ -0,0 +1,26 @@ +#import + +@protocol RSDFDatePickerViewDelegate; +@protocol RSDFDatePickerViewDataSource; + +@interface RSDFDatePickerView : UIView + +@property (nonatomic, readwrite, weak) id delegate; +@property (nonatomic, readwrite, weak) id dataSource; + +- (void)reloadData; + +@end + +@protocol RSDFDatePickerViewDelegate + +- (void)datePickerView:(RSDFDatePickerView *)view didSelectDate:(NSDate *)date; + +@end + +@protocol RSDFDatePickerViewDataSource + +@optional +- (NSDictionary *)datePickerViewMarkedDates:(RSDFDatePickerView *)view; + +@end diff --git a/DayFlow/DFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m similarity index 57% rename from DayFlow/DFDatePickerView.m rename to RSDayFlow/RSDFDatePickerView.m index 0bc2f42..0806c32 100644 --- a/DayFlow/DFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -1,112 +1,130 @@ #import -#import "DayFlow.h" -#import "DFDatePickerCollectionView.h" -#import "DFDatePickerDayCell.h" -#import "DFDatePickerMonthHeader.h" -#import "DFDatePickerView.h" -#import "NSCalendar+DFAdditions.h" +#import "RSDayFlow.h" +#import "RSDFDatePickerCollectionView.h" +#import "RSDFDatePickerDayCell.h" +#import "RSDFDatePickerMonthHeader.h" +#import "RSDFDatePickerView.h" +#import "NSCalendar+RSDFAdditions.h" static NSString * const DFDatePickerViewCellIdentifier = @"dateCell"; static NSString * const DFDatePickerViewMonthHeaderIdentifier = @"monthHeader"; -@interface DFDatePickerView () +@interface RSDFDatePickerView () + @property (nonatomic, readonly, strong) NSCalendar *calendar; -@property (nonatomic, readonly, assign) DFDatePickerDate fromDate; -@property (nonatomic, readonly, assign) DFDatePickerDate toDate; +@property (nonatomic, readonly, assign) RSDFDatePickerDate fromDate; +@property (nonatomic, readonly, assign) RSDFDatePickerDate toDate; @property (nonatomic, readonly, strong) UICollectionView *collectionView; @property (nonatomic, readonly, strong) UICollectionViewFlowLayout *collectionViewLayout; +@property (nonatomic, readonly, strong) NSDate *today; + @end -@implementation DFDatePickerView +@implementation RSDFDatePickerView + @synthesize calendar = _calendar; @synthesize fromDate = _fromDate; @synthesize toDate = _toDate; @synthesize collectionView = _collectionView; @synthesize collectionViewLayout = _collectionViewLayout; -- (instancetype) initWithCalendar:(NSCalendar *)calendar { - - self = [super initWithFrame:CGRectZero]; - if (self) { - - _calendar = calendar; - - NSDate *now = [_calendar dateFromComponents:[_calendar components:NSYearCalendarUnit|NSMonthCalendarUnit fromDate:[NSDate date]]]; - - _fromDate = [self pickerDateFromDate:[_calendar dateByAddingComponents:((^{ - NSDateComponents *components = [NSDateComponents new]; - components.month = -6; - return components; - })()) toDate:now options:0]]; - - _toDate = [self pickerDateFromDate:[_calendar dateByAddingComponents:((^{ - NSDateComponents *components = [NSDateComponents new]; - components.month = 6; - return components; - })()) toDate:now options:0]]; - - } - - return self; - +- (void)configureCalendar +{ + _calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; + + NSDate *now = [_calendar dateFromComponents:[_calendar components:NSYearCalendarUnit|NSMonthCalendarUnit fromDate:[NSDate date]]]; + + _fromDate = [self pickerDateFromDate:[_calendar dateByAddingComponents:((^{ + NSDateComponents *components = [NSDateComponents new]; + components.month = -6; + return components; + })()) toDate:now options:0]]; + + _toDate = [self pickerDateFromDate:[_calendar dateByAddingComponents:((^{ + NSDateComponents *components = [NSDateComponents new]; + components.month = 6; + return components; + })()) toDate:now options:0]]; + + + NSCalendar *calendar = [NSCalendar currentCalendar]; + NSDateComponents *components = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]]; + _today = [calendar dateFromComponents:components];; } -- (id) initWithFrame:(CGRect)frame { - - self = [self initWithCalendar:[NSCalendar currentCalendar]]; - if (self) { - self.frame = frame; +- (id)initWithCoder:(NSCoder *)aDecoder +{ + self = [super initWithCoder:aDecoder]; + if (self) { + [self configureCalendar]; + } + return self; +} + +- (id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + [self configureCalendar]; } - return self; - } -- (void) layoutSubviews { - +- (void)layoutSubviews +{ [super layoutSubviews]; self.collectionView.frame = self.bounds; if (!self.collectionView.superview) { + if (self.collectionView.numberOfSections > 0) { + RSDFDatePickerDate todayPickerDate = [self pickerDateFromDate:_today]; + NSInteger section = self.collectionView.numberOfSections / 2; + NSDate *firstDayInMonth = [self dateForFirstDayInSection:section]; + NSUInteger weekday = [self.calendar components:NSWeekdayCalendarUnit fromDate:firstDayInMonth].weekday; + + // weekday start from 1 and include first day of month + NSInteger item = weekday + todayPickerDate.day - 2; + + NSIndexPath *cellIndexPath = [NSIndexPath indexPathForItem:item inSection:section]; + [self.collectionView scrollToItemAtIndexPath:cellIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:NO]; + } [self addSubview:self.collectionView]; } - } -- (void) willMoveToSuperview:(UIView *)newSuperview { - +- (void)willMoveToSuperview:(UIView *)newSuperview +{ [super willMoveToSuperview:newSuperview]; if (newSuperview && !_collectionView) { // do some initialization! UICollectionView *cv = self.collectionView; - NSIndexPath *cellIndexPath = [NSIndexPath indexPathForItem:([cv numberOfItemsInSection:(cv.numberOfSections / 2)] / 2) inSection:(cv.numberOfSections / 2)]; - [self.collectionView scrollToItemAtIndexPath:cellIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:NO]; + [cv layoutIfNeeded]; } - } -- (UICollectionView *) collectionView { - +- (UICollectionView *)collectionView +{ if (!_collectionView) { - _collectionView = [[DFDatePickerCollectionView alloc] initWithFrame:self.bounds collectionViewLayout:self.collectionViewLayout]; + _collectionView = [[RSDFDatePickerCollectionView alloc] initWithFrame:self.bounds collectionViewLayout:self.collectionViewLayout]; _collectionView.backgroundColor = [UIColor whiteColor]; _collectionView.dataSource = self; _collectionView.delegate = self; _collectionView.showsVerticalScrollIndicator = NO; _collectionView.showsHorizontalScrollIndicator = NO; - [_collectionView registerClass:[DFDatePickerDayCell class] forCellWithReuseIdentifier:DFDatePickerViewCellIdentifier]; - [_collectionView registerClass:[DFDatePickerMonthHeader class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:DFDatePickerViewMonthHeaderIdentifier]; - + _collectionView.scrollsToTop = NO; + _collectionView.delaysContentTouches = NO; + [_collectionView registerClass:[RSDFDatePickerDayCell class] forCellWithReuseIdentifier:DFDatePickerViewCellIdentifier]; + [_collectionView registerClass:[RSDFDatePickerMonthHeader class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:DFDatePickerViewMonthHeaderIdentifier]; + [_collectionView reloadData]; } return _collectionView; - } -- (UICollectionViewFlowLayout *) collectionViewLayout { - +- (UICollectionViewFlowLayout *)collectionViewLayout +{ // Hard key these things. // 44 * 7 + 2 * 6 = 320; this is how the Calendar.app works // and this also avoids the “one pixel” confusion which might or might not work @@ -115,17 +133,16 @@ - (UICollectionViewFlowLayout *) collectionViewLayout { if (!_collectionViewLayout) { _collectionViewLayout = [UICollectionViewFlowLayout new]; _collectionViewLayout.headerReferenceSize = (CGSize){ 320, 64 }; - _collectionViewLayout.itemSize = (CGSize){ 44, 44 }; + _collectionViewLayout.itemSize = (CGSize){ 44, 70 }; _collectionViewLayout.minimumLineSpacing = 2.0f; _collectionViewLayout.minimumInteritemSpacing = 2.0f; } return _collectionViewLayout; - } -- (void) pickerCollectionViewWillLayoutSubviews:(DFDatePickerCollectionView *)pickerCollectionView { - +- (void)pickerCollectionViewWillLayoutSubviews:(RSDFDatePickerCollectionView *)pickerCollectionView +{ // Note: relayout is slower than calculating 3 or 6 months’ worth of data at a time // So we punt 6 months at a time. @@ -148,21 +165,20 @@ - (void) pickerCollectionViewWillLayoutSubviews:(DFDatePickerCollectionView *)pi if (pickerCollectionView.contentOffset.y > (pickerCollectionView.contentSize.height - CGRectGetHeight(pickerCollectionView.bounds))) { [self appendFutureDates]; } - } -- (void) appendPastDates { - +- (void)appendPastDates +{ [self shiftDatesByComponents:((^{ NSDateComponents *dateComponents = [NSDateComponents new]; dateComponents.month = -6; return dateComponents; })())]; - + } -- (void) appendFutureDates { - +- (void)appendFutureDates +{ [self shiftDatesByComponents:((^{ NSDateComponents *dateComponents = [NSDateComponents new]; dateComponents.month = 6; @@ -171,8 +187,8 @@ - (void) appendFutureDates { } -- (void) shiftDatesByComponents:(NSDateComponents *)components { - +- (void)shiftDatesByComponents:(NSDateComponents *)components +{ UICollectionView *cv = self.collectionView; UICollectionViewFlowLayout *cvLayout = (UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout; @@ -187,7 +203,7 @@ - (void) shiftDatesByComponents:(NSDateComponents *)components { _fromDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:components toDate:[self dateFromPickerDate:self.fromDate] options:0]]; _toDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:components toDate:[self dateFromPickerDate:self.toDate] options:0]]; - + #if 0 // This solution trips up the collection view a bit @@ -237,7 +253,7 @@ - (void) shiftDatesByComponents:(NSDateComponents *)components { [cv reloadData]; [cvLayout invalidateLayout]; [cvLayout prepareLayout]; - + #endif NSInteger toSection = [self.calendar components:NSMonthCalendarUnit fromDate:[self dateForFirstDayInSection:0] toDate:fromSectionOfDate options:0].month; @@ -248,33 +264,29 @@ - (void) shiftDatesByComponents:(NSDateComponents *)components { cv.contentOffset.x, cv.contentOffset.y + (toSectionOrigin.y - fromSectionOrigin.y) }]; - } -- (NSInteger) numberOfSectionsInCollectionView:(UICollectionView *)collectionView { - +- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView +{ return [self.calendar components:NSMonthCalendarUnit fromDate:[self dateFromPickerDate:self.fromDate] toDate:[self dateFromPickerDate:self.toDate] options:0].month; - } -- (NSInteger) collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { - +- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section +{ return 7 * [self numberOfWeeksForMonthOfDate:[self dateForFirstDayInSection:section]]; - } -- (NSDate *) dateForFirstDayInSection:(NSInteger)section { - +- (NSDate *)dateForFirstDayInSection:(NSInteger)section +{ return [self.calendar dateByAddingComponents:((^{ NSDateComponents *dateComponents = [NSDateComponents new]; dateComponents.month = section; return dateComponents; })()) toDate:[self dateFromPickerDate:self.fromDate] options:0]; - } -- (NSUInteger) numberOfWeeksForMonthOfDate:(NSDate *)date { - +- (NSUInteger)numberOfWeeksForMonthOfDate:(NSDate *)date +{ NSDate *firstDayInMonth = [self.calendar dateFromComponents:[self.calendar components:NSYearCalendarUnit|NSMonthCalendarUnit fromDate:date]]; NSDate *lastDayInMonth = [self.calendar dateByAddingComponents:((^{ @@ -297,15 +309,14 @@ - (NSUInteger) numberOfWeeksForMonthOfDate:(NSDate *)date { })())]; return 1 + [self.calendar components:NSWeekCalendarUnit fromDate:fromSunday toDate:toSunday options:0].week; - } -- (DFDatePickerDayCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { - - DFDatePickerDayCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:DFDatePickerViewCellIdentifier forIndexPath:indexPath]; +- (RSDFDatePickerDayCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath +{ + RSDFDatePickerDayCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:DFDatePickerViewCellIdentifier forIndexPath:indexPath]; NSDate *firstDayInMonth = [self dateForFirstDayInSection:indexPath.section]; - DFDatePickerDate firstDayPickerDate = [self pickerDateFromDate:firstDayInMonth]; + RSDFDatePickerDate firstDayPickerDate = [self pickerDateFromDate:firstDayInMonth]; NSUInteger weekday = [self.calendar components:NSWeekdayCalendarUnit fromDate:firstDayInMonth].weekday; NSDate *cellDate = [self.calendar dateByAddingComponents:((^{ @@ -313,73 +324,97 @@ - (DFDatePickerDayCell *)collectionView:(UICollectionView *)collectionView cellF dateComponents.day = indexPath.item - (weekday - 1); return dateComponents; })()) toDate:firstDayInMonth options:0]; - DFDatePickerDate cellPickerDate = [self pickerDateFromDate:cellDate]; + RSDFDatePickerDate cellPickerDate = [self pickerDateFromDate:cellDate]; cell.date = cellPickerDate; + cell.dateLabel.text = [NSString stringWithFormat:@"%lu", (unsigned long)(cellPickerDate.day)]; + cell.enabled = ((firstDayPickerDate.year == cellPickerDate.year) && (firstDayPickerDate.month == cellPickerDate.month)); - cell.selected = [self.selectedDate isEqualToDate:cellDate]; - + if (cell.enabled) { + weekday = [self.calendar components:NSWeekdayCalendarUnit fromDate:cellDate].weekday; + cell.dayOff = (weekday == 1) || (weekday == 7); + + NSDictionary *markedDates = [self.dataSource datePickerViewMarkedDates:self]; + NSNumber *markedDateState = [markedDates objectForKey:cellDate]; + if (markedDateState) { + cell.marked = YES; + cell.completed = [markedDateState boolValue]; + } else { + cell.marked = NO; + cell.completed = NO; + } + + cell.today = ([cellDate compare:_today] == NSOrderedSame) ? YES : NO; + } + return cell; - } // We are cheating by piggybacking on view state to avoid recalculation // in -collectionView:shouldHighlightItemAtIndexPath: // and -collectionView:shouldSelectItemAtIndexPath:. -// A naïve refactoring process might introduce duplicate state which is bad too. +// A native refactoring process might introduce duplicate state which is bad too. -- (BOOL) collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath { - return ((DFDatePickerDayCell *)[collectionView cellForItemAtIndexPath:indexPath]).enabled; +- (BOOL) collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath +{ + return ((RSDFDatePickerDayCell *)[collectionView cellForItemAtIndexPath:indexPath]).enabled; } -- (BOOL) collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath { - return ((DFDatePickerDayCell *)[collectionView cellForItemAtIndexPath:indexPath]).enabled; +- (BOOL) collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath +{ + return ((RSDFDatePickerDayCell *)[collectionView cellForItemAtIndexPath:indexPath]).enabled; } -- (void) collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { - DFDatePickerDayCell *cell = ((DFDatePickerDayCell *)[collectionView cellForItemAtIndexPath:indexPath]); - [self willChangeValueForKey:@"selectedDate"]; - _selectedDate = cell - ? [self.calendar dateFromComponents:[self dateComponentsFromPickerDate:cell.date]] - : nil; - [self didChangeValueForKey:@"selectedDate"]; +- (void) collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath +{ + RSDFDatePickerDayCell *cell = ((RSDFDatePickerDayCell *)[collectionView cellForItemAtIndexPath:indexPath]); + NSDate *selectedDate = cell ? [self.calendar dateFromComponents:[self dateComponentsFromPickerDate:cell.date]] : nil; + [self.delegate datePickerView:self didSelectDate:selectedDate]; + [self.collectionView reloadData]; } -- (void) setSelectedDate:(NSDate *)selectedDate { - _selectedDate = selectedDate; - [self.collectionView reloadData]; -} - -- (UICollectionReusableView *) collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath { - +- (UICollectionReusableView *) collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath +{ if ([kind isEqualToString:UICollectionElementKindSectionHeader]) { - DFDatePickerMonthHeader *monthHeader = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:DFDatePickerViewMonthHeaderIdentifier forIndexPath:indexPath]; + RSDFDatePickerMonthHeader *monthHeader = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:DFDatePickerViewMonthHeaderIdentifier forIndexPath:indexPath]; NSDateFormatter *dateFormatter = [self.calendar df_dateFormatterNamed:@"calendarMonthHeader" withConstructor:^{ NSDateFormatter *dateFormatter = [NSDateFormatter new]; dateFormatter.calendar = self.calendar; - dateFormatter.dateFormat = [dateFormatter.class dateFormatFromTemplate:@"yyyyLLLL" options:0 locale:[NSLocale currentLocale]]; + dateFormatter.dateFormat = @"MMM yyyy"; + dateFormatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US"]; return dateFormatter; }]; NSDate *formattedDate = [self dateForFirstDayInSection:indexPath.section]; - monthHeader.textLabel.text = [dateFormatter stringFromDate:formattedDate]; + RSDFDatePickerDate date = [self pickerDateFromDate:formattedDate]; + + monthHeader.date = date; + monthHeader.dateLabel.text = [[dateFormatter stringFromDate:formattedDate] uppercaseString]; + RSDFDatePickerDate today = [self pickerDateFromDate:_today]; + if ( (today.month == date.month) && (today.year == date.year) ) { + monthHeader.currentMonth = YES; + } else { + monthHeader.currentMonth = NO; + } + return monthHeader; } return nil; - } -- (NSDate *) dateFromPickerDate:(DFDatePickerDate)dateStruct { +- (NSDate *) dateFromPickerDate:(RSDFDatePickerDate)dateStruct +{ return [self.calendar dateFromComponents:[self dateComponentsFromPickerDate:dateStruct]]; } -- (NSDateComponents *) dateComponentsFromPickerDate:(DFDatePickerDate)dateStruct { +- (NSDateComponents *) dateComponentsFromPickerDate:(RSDFDatePickerDate)dateStruct +{ NSDateComponents *components = [NSDateComponents new]; components.year = dateStruct.year; components.month = dateStruct.month; @@ -387,13 +422,19 @@ - (NSDateComponents *) dateComponentsFromPickerDate:(DFDatePickerDate)dateStruct return components; } -- (DFDatePickerDate) pickerDateFromDate:(NSDate *)date { +- (RSDFDatePickerDate) pickerDateFromDate:(NSDate *)date +{ NSDateComponents *components = [self.calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:date]; - return (DFDatePickerDate) { + return (RSDFDatePickerDate) { components.year, components.month, components.day }; } +- (void)reloadData +{ + [self.collectionView reloadData]; +} + @end diff --git a/DayFlow/DayFlow-Prefix.pch b/RSDayFlow/RSDayFlow-Prefix.pch similarity index 100% rename from DayFlow/DayFlow-Prefix.pch rename to RSDayFlow/RSDayFlow-Prefix.pch diff --git a/RSDayFlow/RSDayFlow.h b/RSDayFlow/RSDayFlow.h new file mode 100644 index 0000000..ac3a728 --- /dev/null +++ b/RSDayFlow/RSDayFlow.h @@ -0,0 +1,7 @@ +typedef struct { + NSUInteger year; + NSUInteger month; + NSUInteger day; +} RSDFDatePickerDate; + +#import "RSDFDatePickerView.h" diff --git a/Screenshot.png b/Screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..a0a9c567444dbbab65a6e2693a30fd8d23058aa4 GIT binary patch literal 34126 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ℑ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 Date: Wed, 8 Jan 2014 18:13:11 +0800 Subject: [PATCH 02/87] Update Screenshot.png --- Screenshot.png | Bin 34126 -> 50336 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Screenshot.png b/Screenshot.png index a0a9c567444dbbab65a6e2693a30fd8d23058aa4..61bad73b6adc42fbaca391a1ba4f133618e51cc2 100644 GIT binary patch literal 50336 zcmeFZWmJ{j_cjWM3MdVtv`9)xY*IpyE~Og;>F!Pi6r{V6hE2n!L+Q@F=@3!6yEzN> zcg}x|_k4LjopIjr`}91x?|ZFvuQk_Pb6)eh*5^0!5||jo7)VG+m{O9j6_Jooe36h) zZP8G`zZ`AZt05r?BT2n}rR<8lnR>sG0C9D^qPr%!BZr#(3GGwx-3P(Jn1)1RS>mC@ zkhpeJ_+%*L5nO#goVGkON*#^(h)|g+pHk&ja6YA2u&-n7gB;Bjpb?@h3 zD!vE0=6M zq^I>5i!uVsZzauRd){LQA;6p3{k?NU;3k-{gy#sZ#37^V@yg`zY_E$#LGbL?G|VDi z<%<47P1lVkEBo>_`3rsD{rLSesrKY8?gh_h!vo3Or5G8qvpP?Mvl4=Ln4cA41o*;N zn=iKc_q(6fEO>i(-RE;$wQa-XF4C%D$=Yu@{TUKO<~%7zq(fkHG_GYsX5alZijSs* z?xnzF&ViQ4$()Oho}|Y#m^HsU_vd|XuFBmQh)7=D2UZl^WFCH$p^+y~MsfgNg~jvu z3X`LMdCVqK|H5jzsxju(*>jiJr&+V9Uknsdc*bA3(tWO@!3UjhlnPz$ zwq0!1q@TSKJpJ+E3C$|+J{T?I_ltFC>C3zy-`~`vE!r*eq9#*mO`|X!aVL&_AM1)QfYE(q>t(?_-{^s!5evpe-2_x>{2xNhldB zH|(Ol2%a7#w`<20x;l(z^E?>fHe5<~o;E8%9avLR5TJ1&QRZ+Yl1)iey>^`^x+e?R6isrf8Wa=*kpX1*Mn4SaW(6eQPd{NC^nJ53)Akw&6Wpd zKOllAyeA8k=#;XSw<}NPJrvCu(4b`ntNmTw)hwKyldM%>C5KJeHo`D znAOZUb!Hm1hsu3mbIoVhoTkG+rY%aZx`eL3a^`f=UMUD&adK5`Ok$LsryPmF(l<&P zws+gGYxLx2K02Y>UY#Emb9Lo3hm=E!Rh-vFB@f>AG*f2pxlgl6vu+qQuBh<$XXxBq?KKs2qdTWl6&m@uzn^otWK{V2KDr^EdIsuY z){7QCnAcX8OO5p$wG5HA?RSQ}lnTo!_NAm)6DJKQq)2$8lrznD*}-e~`+W?xovQO- ztB)K*FULqX`Yi8o2=H8NR)&6-t~DLWRCf@dT2=1wIG!>wY;(Fyzqypaf8nJ6v$n(@ z!>cwlK;YIP9wIcpS}&bB zHE|r(IQBaBV31!S%gcTLP1rfqFo0fL%}Q3Ihih!l&0_GCDSDN~guKvEz0(G^(ixOAPP3@Ga8jSky>isUnUQ$8c=y9qT#{`* z`8kv@FKMpmCsq&C@tdj7r1fMTa_;bPO^IR)C@;Fh%g*H<@Wf$vxlw1>$7~&9qPXEOGkTJE($t zC$dvbex}OK`ucD->gQ;2bA(JbLojiH%89J_d?KMmIZDwA*A?gCXEH9;q;uUwPsn8o zRR|oVsQHOQx}x8}*at#=-b@z8126B@uR)fNWa60E0^oQ2a!*JcP$%~nDO*qv1C){b zC)iniSzhRDWysOSEUw3$UFr=1jV2R3117}rT5-<0&X}PM7B7W&wh6!gD zf9h`jnA0?3(TdnhTxs%F!EU*P!U z#Yl|THEa~2S~996+}4&DHpvs^D3&^7*aMG5H^_da7IC6xjW@DM_%c&q?aP3TPx#G~ z`CxzImvtYd81#{3z2Ub7uai`5MIwvyumWsVe5Rv}t%|7J=aHw2TCi|PW-i0i5++VV zF^(2a?@f$w0fe$5%q3^R+^Q>((E^i>F~B6vjh5@BhHklC6q$wTRJEidky4iSfIB3x zUDL;@$gPZ+gKL#g3BNXqM$GjU{_ylurE9l?<+bw7C>fTK_&0jtI?hvKFxH$Zr6>OO zN*p&w^hFYUH2E4>&g>5BhlG0Jt;bnE3-XgJpE5$GAmaEoB`l^Kp*LCKf>F*4XZ>LU&$hDsm)N-(NNLfd~KZ^m!!n766vJrWL~K>qbY`omE>uM z-*zD}hmypJhDoXuIP<#%*;c0vN{cCunk=?Tb3dE0{Wgl%iKBwB5V9Z(EGD&XG`K8< za_jnB9W5(I|AJu4>|gHpv07+~mg+WLUgS@~i9d~0rY3&l0b$hb;bBHga-+o&xV}BU zBSyB2KKAye8m?BI6r4l&#vPS{+d9P{&2dz!oDl_Y8V?N_O)|VNAfg0mL#Me8J@Y3=1#ZGCLm00w4;fA`L@R+#rCu-?X_$1kmrTKbAWmm}uf_Pckxn;);Gwt(Q z%Yg#ME^~a@gin}o92hZ07pcP+OgpmG@ype$@Ip21rSU34ZQI~wxbxknzKa^5b)A4{pq@GXkEfZ!F6w!~{^(^aJv4TE#w%|LDShP4ix4g+;x zpHb|lGQMi@xw&0T674jRrjoK|wPk^y3(RYPiU!@bf&h&b1*Q5xl&r4Ah?jr6Hp}jX z^V1Y>T+Q7q0dDqv9U*#wEwdp^jWwcdSY1+F!dnbQ?HN9Wg*W78GdPf+kmjt!aQCRV z;!Ad!Xxtx%Qh1f9=%&Zv?ov>vmpaICWoAW^4T1%gYW&yKvTAdE^%|z>E_1X5ua@2^ z>Iqm_+|QrfnubvDe67<6#Pwm&aJ7^b7~D{P&WIU?soJ2=p1x7uLi5xQUD4;_?zlfv5GYRwN&Vh`5ZnvP=0}%F zDqKk0ge~Q$a(2>XGYzy$7W=TP!44(wn=^FIClDC4E-CHeXD-9+BT3f-e@jc?3&MER zEmE`>{Zh=Q;}gTll9NQ>SYeopwd&}Tb$;b~FRp~)@(>ma8+C^a7v_Ws`&C>yrK>U2 zOc#!XG!rMNX;-gyVX1U}kE-##9I~nMNoW* z5GUtrA|*u^@DjUY_mjEIzGF$$)q`Oh7#8x&@T)$j{ujld1y{Q*ssX8 zoCL|GyJxkO({z_z`o%!^`s~=Cc6q4*yj+AJ%^2e~qbUlWex;|R9tSh`#JIAiQJ$X< z%<*@8eb`o*nY%y^E;A;2-kJ0(noMpAdNQX;Q(sXbwh6jjjq#HDH~2!;GEzEv?r{)1 z9DO22c~OyXFctGb>ECR6FzvCM{F^Du$gEeaJ!QGZrZ(LULjn{1%foFI_dZ*h6O%%W zqE6Qqb!4JAi$#?rtHja+i6=gllv42h=TcAg5+qD*Z zd{ot-hscRTLU&F>dGMBv@P`hCxh2LnN?P~^;VGwg<%Az>eYw}*y-xge9LcuGLK7`x z5nZ6T^WOB*snfUhM!TFfK7?&JBwVO$!&fEh6uS4ce8YE3h2voA7gVntbHZi;wE}CB z{r14?_vSfHUOO*;f1!M4&P^Ws^cmWkb^AMfMA)Ng!oJOKCOV@{qU@W~qN23Zol~+w zTx?F3)h-jdYP9W}j|e^?G4h9Ym{&+yPQ_%M-?LhDil8c;G)*M8hzy(-I8QEkx) z8+ZxJ?&>WgE^3Fc46R&ITV}OorPx;OMJJXX0rS*3e;vE16J7n8d1jnT`Y8;`GPwL_*mn^t^N|4aPvn{v*Z`ex!PtD0#>e2 zou`H-!Sd;XI@rtgAE>MLpX7U_6H}~X$3GrZTgIndHp6>E@n!jG;f(6s;Fnj~=%J=K zXc4~d32+5N+K2ZNEcv9?aJ4TglM)rz+PUo-AK0F|;o$$v=8=i~9@4(6W8w|?n_~-q z<3L88BL;mF zHldrdDcCHEgd&I@BSwXrE~St4A7CUGb=7|`=JDRYsYJ#R_PygPiT4jikp(lGi1$qJ zFH%B@1b`DH94VB4I0^$mOOy=SgZ{1xDgZ*Tkf@~o;UerbzDOq0UrztEganWgWMOLb ze|StTD$Wnt&$twSTf#vCEg^lPM*cghZh+RLFtGgu1HOG5h0+)4K2jw0KUgIZPuQ1( zM%?pXOGuz4B+4k%e?wFPL(Faeg#EWAG+!hXQl!^W|4^Lw(g3UZKlo#XLy<-$quK*8 zNmOmFENkYRk2WS2yf3yaCQ4GNOZa*4J{RdU9OtEbYgQVE7JYFGCDvdnZa~%GS*S4T z1CRc&RT)#0xo2yZHD5A34w0lDQZ zEcN9Hhj#q?)0&nmtDCD6mw=!fxKOk@1-I2S{HthCM+ni$+L*~`wp4jMPav>M9C;Mv z2fNDy$t@rryv4!-YWTORl;T-*@WkIlyR5?tpsK~vt}1?tOmpwFsx1?lM9|uZnAC08 z3-X$8t}l9eY4g&2uFs<7`4}`lLQCq`!5AV9XuiBrRdqi59e?wi)kn$|lHzxrSbM2> zFoE>iSLZzs@KYi(l={f36hE+qF7+F&#)}fCivY~2sO0*)Hx?{Oacl%YR$!(ht#`%b z=D|b5Rk$?I*R`!?Ys>l45f84G!iCo3tbWRrfK)jhK47ZWdnO>To}VQiPF~F3T`&f~ zly7&il~>C7&;e4{BthZj2mqA&Y~w4iyh&wbmjF*lvF~N*3;<9c773Rn$UIaO4UYOb zhWeAahqOoc%<@u=!`f~p=j|94*wRi_Hf z4lx?)5$E$a zt&J199v!-vTYDrnjR5A7$ag(jM|c3-CI`P<3?QK;q#E^(1t^3AtB#haPj7LicqWa^ zZvrQ?4)FZ9<;6Y%8z8`Xe|frBUuZ&hB(Q2z3#a=FNR`nAgc2C$0+S{;&8ts?aPCVnRW(;M~Vep%> zBuEdwd?s#Zs4p;#9=O;G<(@a~&CoT7KYy-$P!@05p=xbRf{G1K$bm_Pj1BsL>drkxS;91M9KVupTx5Y)X7tfXK#b5*~$e*xdL#=O<&K-qD3jG zY1@gl;$e~U41a`{TTr~R><9BXK$`BhoQPg-%5?-R!|LZ`_xQ_?_pcMX8Ju$RTV4;n zd+HcLb=#?Aw6OjIkAC%Bdlfy4wm{5iqf(i5*>M%-H^HHX3OU2Mv7{ada%c!b685Y2 zUf{8CNLat}u6!zAL0w!~N~azN-}Ri!f?3RjxKdt|IQM{==f;%ySdIj_+v_}HWmO4( z@qw)z9P-om1}{gILR4)#-1BxsTUkC%@{ry-ZZtx_A9s0<4D=wrUv4x>Ngs$Dqz@Fh z7aF$dbSb*vQ{{|gGpkXRbh`zu#hcWG|V?CcM*p@Z|38WE@ zQVtcIl!ake04+b`x>dzvHM`EA_ zD|9n)B^JD;v5IC=e2v-MNvvDa)MRbiogchPPAzrSEtw_}d zz4S?$@~)()@j?|SfY2G<&^{&7PnR_yTX_tQBH>r~U>y-PMGEGR%&Vu%b>p3~MY8wp>3;52u=GXUl@x_UFmhx6M z&M=K2I{)5M=JLbGU%w8A3!Zl~xvOT`{_2h_SuX9htQk-w;f6in@`p%~2`Q^_7~mB~ zDLuYDC%w^rN%}%`8INFNs=&doC7I>$N*hxuRXn#FRVCchEpW@@s=^FkfR5^7Z26&? zDnKWH7SR33O|}kJ)9Wa|^9^C`Z}m()dXh=RI|Vm7;zDHa*3|dV`4}p&7HJ^cu-qv@pZvb7 zVNqs)zYAb$pKkN~}>6MV#$7lDETO!|5(TlHoyEl7Y;e>>P28 zZd{`3xme{Ex8*k89P57NJAav_A*ScK7f`JOXQ7am+i=^YE`^U3FO6Y~e$u7=8Xz^z zDeBd+j#s;y8B)cNfI&+E`8=`BXclbFvc_`_d&Ht=i3%15XL;;P!pAAx-rLF%HdVo-<4$LS}u z9UW$hqu9?NtGTz8QOiV({yTAf{ZqlUhT6@7jp!XjWcrWIQP*&+v z8BlG|5pQtb;zZDUe~?l;<0ORo+*~iGeyG+`v2(Og%{bP5(^5sY%w$?#9)|t+#g9M| z>lb;`Ow-PU^zDNWC&Ea%yj$;(d{3hOqDt?_kU$XpAm%oZ7KWkvr++j$Cgz;cVepV+ zSFEX=^Q)Lfk#a!{6@^!+DwS}07cIU+uYAG@yRa%immLz#8iX%WPD$hRGR#X+mRTO=jC?##8$$bcA^ zcX!f1Unh}~JAb}6j-iHmu2~F&ejFe{Ggu1RRp+Ob#yvU%_?{AhLd<5N=~4Ymg0pIp zd%{wl>6EFW-V91L?XmeJmM1%UGJni%fzQ_j98G2JX)u}Qwbv?n<@3r}ZYt#hJq*$X zkJ6?a&a-uU%<~lKv}>ZNt{SzYip-I;(%~pf@x>G69PmT=2Nx+{pJ?@Hm&L>BC@j*L zyuI7J*n4aid&q7F?~CeBpx^YhyRbCS9y<4!aU2u9j8-N&Jh6(<13?OPn6YmE%1z!W zfu{Az>z%Jxo=7X+dQNqx(NWcm8q4!s_(_B)78@-nCcPKYx;rg%pTe_jZirgrS7Xq{ z`>2zBC8S$>esy~u4BR8mRrk6$9#BSyyK~HynTuNpwSL@A{Q5>mG2MCHg^QYV$m_># zd4k;w1OW){h%%&g-DUv%^wV_Ico-x{JQWR0_%MXY|-o%={v4$ejo8rD@{mGGaVJK)q!%mX#Yy0uK&jl;qzk z`1ab9%d1p);cO%nKq3gnytSY z^~GscXP5s1rA;&5=($eC22(QuyCl)Rz2E(IpN{cH8qfx^K0o3Er7h*TJ4sG7s!F-C zBlXWPJ(8(F1jZM^VO`S0nx`l z)1?}fj-5VwogXH0nkjmsiu{RELxuHGibA19&bdq3kBH68N*QyF52QbARpXUF`BV-x z-Br~Yef2mcFT=7|I`fO)@|H%JZ-Us$26fbQVXh;rH%X2 zYOV>=1g$&sO&*Qy>rq^hs^Qj`IqwSs zs4piC!x4f>?g#ppg4E^<>E7pS(_0p&yNf+=HC=7H4nlK;nMmBvE0hJx!F)eB>5?s(@0!_#X||bDnhTbx-XW5%aljy$zN=|av}ehjr6^I= z>7ul1?a7zKRP1LP8o3cw&HWamL`rLqb`g88hx!srQRLQW(9u6C`{KvN3g7+#HpK`I zTJD2-Q`;YC|FSG@kaW%3(h~jqoe(5lgrq5d9!5g77X?`sris1Z-@H)ysV|b+_wVTc zef9sVX@V4{*rE7E;3iZUcLqUeJs&XMDM@2JE3xN$MB@55q)8z2nZeI3h zZytSq&0a~#g=#ONzt~9=&g3aRn*4&hXE(qq5LSR-UsOT4g$q8WgXH>}?|BEFce(R% z>H&q0QaM+^!BO9a4&vHB?Z{agH%R8TMG+ZawjaZ)a%+!dtrpA?YL3)H!MWWzG8jWo zk^DqxeUXUlw+PLq5CFysC163aUK+1rAP8IR?VB*)W@9k>1Y=3e=RDd#| z1!v=uB3I6HXC1ywcpoDedHW^rKLEf1voQM~f|MVKgrbc}$+D8*dtBekDS=I!X#DCA z-rxt|qdOAP{>^BnAyC<^|F=#vywW&eC;CxlkNyB7I6R^p#%|H9BuO#pay{alu~kYX$p;NM0vaR_ZA1S(DLM zO-wFU!yf^XGzU%J-l7qZAkPOXTS7EBuXp)cGYh0i!FIy~&-T#Z9 z?7jk68Zx%h-+lhSyeaJK^{tKIPcxK1VgZ&GOX_^vCUCG60869Teen;ma|K|K2Tc&! zUmx)8K7jB3+vR^J_P^%y-%awr;|d^+#0K~M44&<#n-OAr<3y@S9MfN1`4yzerKcW;dvbo;hmX=ARq8YCN-c6%8QmY~07rT*K zs`fhTsw_9D`z8U0jg4@pPAYN+OCg7%Z$g!JqsVsKo7;ZrYXOzbq~eph3x!w|J-N5u z%|&@Z8w+19tM*n7dT*WuIXjgQtIy|X_{*x5&@ ztvB|2bh_Al((kJ2`Pfg4s{UhI*LuHTtXZn}oyQl}Iiw>{U*XW(q9h7bJ*urFpg=*! zNjUVX`dko>8>-gwsc0sq*d-c?tK(7F(hP`!u9qG3ii|Om5;Hz#N9QQ7-G2u5?kuan_w=DSd<-EdRm4lF^hPpn5eKQCW zDb$?C`8y_8`=jt%Tw&jkLOwg%8C1BfaS}+9S`Rz?c!LYgk=?q! z)I}|cBz%e97miDDpXy;o+5RsDsxBi+j3D0I+}rb+n|gUMF4n|yZ{?0_jBS*z&KRGW zhcGr;%dO;a^j=g$Lfs_11|^Q@Jq}NMXIi%m;q~*zIj31BueV9HzTP`Y!&cSamwr9E zz36bX8f;{ddWX;LMF;BtGkuo$Zwy@q#_h(J++!idYRyma_=PANu_m6$Zh!`*kzd~HR-iP?pO^KEoyKS zQj1?^k!nisBjmA3l{P!un*1`d8kwBNoG~=(xo>AnuSQO_s7At82MCc(cUx6rKVKTe zx3~PBw<Dx|C*J=}WE@@o<=_EVUyUQlj#fj@){d~sbKHYKpo9vs!hL`p;{J4;j z8+%8$RN04PL;eZ3VPU^NOGa;Iz8mce53~2J{-#f`c2reuHq5D<&c>lnwmx5-RCUMR z7dKC0S^L#NI-Mu0qeXB;el1^rsD#ghv3ZK`^rqSq1~*DQRmLV=Z_usjsng%7n46B3 z`hwr}i~xm3lyXnWp{F)H3#Z%n+o$5O()StHCWg6!^KA_h;gI~ZD(!I<<)r7MqN10( zH|gW*3c9O~HjCQLK1NcPc~TfS^rj#}ex*hcFhu4jr$u#>_=vDFZifGk^K9G>tM_(* zx3|3}hlh))_VLA?OpI)hVut+!&VhOEFsy2*Ga~KxdAzL;cI??sx-!P@_7CGsI#dPj*0 z|E9vBmaccm#K<}`9ysQ>x_p$ixZ|_Mq^?omJaX_Wz4C-SejI z8s{tb&T*PPVwga_j8P)ZHJ;d%{OjT zD!w`6``HVjg~Kl@N8#`dEv%VinT5kjq?<-v2D|FzCx%Lz#pmq|lW(ltb0A$!T52UJ z)r+LU8SUtn7aDOqXtP1W7$~FNC(GicC#H*=v!io?{D8{78lU?bo|i&J=24&(QW0|h z_1H*euEji>$ZyNhuq=pt*A-Ocpp_t(xg?Dr=9#xV(`%`q^!b^MBj|EeS z%l%~GAv54vZ4tvE<3EW*uXt+|+J^p7$P62%LfOzMPNp9ISs zG~FyP4mUV5b=r3Z5!CC!OCEQ3Ig13UIVYrKoCfG^7ODrYM0@$UrgEE~YZPxi4~cij zXLNwYwTMi~m3sT=Yix=NYx;gd^)t9#K@ZHObQ=_N_;j;TG3EJcva*%7m5QDIN;(aT z(YR)1c9Pb_JoG&6>w7+*W3@rC_wAI3x7XI}81a9`-7%l4Kx-%Dl@ z_@Wiz#?r~hzC z+Wr1=phTKzV!Tc>()egpTD#$W%0$a%`CcT&1V48(q1)I^J1We~Ca|oen%qBRm2aIE(-Uq%iyiWuhFPq$q?0Aj@9Qzi6ROEMkD059 zCSs#X2ZPL05uvj_m~~DgtG76^(r138rxC0Bn`U{*ey9iL#_N-Xe4REcqr|jY zi^R3mac{DfEu#-m-h3sFdPvu>Nfu_iP?Lt;(Ay{6$dCw2xJyvyU}auhjYUk=$7=e9 z>XO+{(j>3xESKc9l+QRvp)g4AsqmI%Qz*}rMCFj+C9S*NN}T*fF{{ERyy`rPPA1eA zjerUnwHC)Bl-+}RxXx@Uf%mN$n;eVUbBcbba%z~+&Yc{zY0oyMjuFi)f^}%ZbozdM zk~?>qZhyuE$Lr%$x1|SaEPHt#TW`25Ybs0x!I{n-pj?99mYW_U`WS+Nfs;8;iPUd8-_0$p_H5t|fi~a}l z@Hp*e>>1{zt}xTJGvSPH=(|mY46am?8~*7zOZ6+FGAw$Q6-a(`WWbXtFwvjuEPntIt;& zIqHcw5ic&+Feay6@$-1N6v3y5TEY{!F;|Q0_gF7NPV~IstP0`l=RPf8W^E<2Uu~Il z&g7PPZB+WLo%&vzuC+zN%|9eBjd0%{Z|vvlRVmxJAFIR5rwLD<4`$L) zvU?xSZdJ~}o`iSQI?h}QBm8X@bl{uz@Z}=Te^?Oo1SrI|O-{CFQ>?Gmt|c9Z+`kvA zhi<%H!PauI+$ft~E@d03j$vMx(941n3YL1~zFjGlE1dq|r_+0AFWO{YGo4V5n|pcL zJg>D-(7Ag!N6Pq3da-@}cRF)^#E0p`{rQt;=S0axTvpB2I5Xm%REv*MzT;0im!b<= zDSi|_MI#+9*o0N~URZf8HbNaWn+}%iemhqhZ0WyT@5^VB64RMcsDHRs@Mvz@g+qO> zS`8{tdmT}++@lwPV^d=7P+W0zIr6KNPX4*tlHhSx;Li3|irUa~AqN+0ta5#xK;d1~ zUeD$)G^coxRHzjS!g?NZv7?G9Zj4k%7QFnBkmkWsGxrdeO1*mRl`?0;_s8rKjM2S^bv2hdPRQ{W!%WiEgA?p)(Ibqze?XT1 zrAt(v7=*~zTaa2fWAgT}(``Hbi^qJW_C*S+(4;5$gQF1egDp8}@%ZM?qm(fKlYOK5 zAi)0?fBC;XJH?+zKSlwluGjqQn?ECevk4wGD1CSN;m@OQ0BR)q-;ex1ej(zjAgp8gYEAY08~4kewgUgUwbqK z_9&(Wc2a^x&>va_C`NZQnz~kQv*WLn9OCd40ALO{ZWzobl>pd(LIv&Ey@!-LB}fT2PS# zQbhFb&8bQ)AoZzpSRog1kKu`SRlOC(1rst7un0oTf4#!&ql%RDEJp))vxvO@Sgsry zpQC!Cs~up7(aI$e?2j6kx&pn)WvrSmug|ro+9SXi`K9AB2LpA(+SZWks?5xv+YLL- zpnx|~qC>J_>E?De{8bdxFWm()+5_V^%TGN|7lYgtas57E@#U))Yt~7;B68eLjD7~F zfV;hnrIKEEB=hy7)q$!p5hx-6RjU(P>Pal%UPUfv-E=hWe>5cX9gw(Q*#7tiEp498 zX_l60z1*xEI^LW*0IILUC`Y@g{NKDz>&jWpZiinU*^)0tLr`DhJqD^vyDqXCpy`{6 zw|wB*9q|x(k&wIjrarL$Ck_uC9q8?6O_t2%^ z>J?Ec0i#K2c9h_U%Yv7hoPg+Uk-v7YlVqU$>|%g>A^*WSs7el-RT>W%_a}@1e%&OR znA>G1i47^JhT0c{VCJ?T@)3i%6n>X&U5_o8IKD6jt1ZoSHf>P4qmsyK#K_m*)LII14kE9E%R~VFXC0(>&<~f7D zOur&tMWNZ=EBl1u=ZTx};+=nzozV5EVKW9!p(n&mB{e@+@(<^!0?@=ZeD7erh=0xc zF2w)?FbFFXL-KlF_asaTe)!!N4~@=9m{nMaPvkH$_tlQ!Bu#5pi8EM!_tPovqb z0ygA1KG+xP@mF)AGSy^;COWq=&xWmPEvC51CBSOB0+XoxNtM1Mkmz^$BQmSWvR5Te z>u@On8gws9z|2|}vEYg;@dnD1bvnt%#h>mRt(Kx_x~ePwF>HqW#Vjl@iQSKi7dj z8gf6WlExp;x#-EYN-u_p3&37XzrK|{Ij>0K*3q-d0rEAmc7wB(Tprrz4`{ZM&;1QR zc)Eu7<{7IP|4{ZmLQT)CvzB-K^`2ui%c!enYEH*@O@5Y}>1wMBz$GLo$dZ~HEeoiY z88Z^7LKJCmm^IGo3i~?rCC`F@ViW(3#ZHRDAe&*PCK{ARYHEnXkyp~Die?;`TK3}N zEgQ*l;A`N1cjPmf;xontNYGnIc60O_W=Tae_1w~{uQUA4XpSVzwxM~Jb6aWb=`w}5omR(*xm7h%wnep~GhkP{XN zO=2q%`_>scW8E-N(!^ld^)gl$-wTHQ*;tUo!fL*NxeZQ}!Bw7jh%qY3ACa);y6%ZJ zll2%yJ3@~E0}~mo7A^nl0ocYeI{m|?T)c`iCrK71c4CaFW7c!^1^BvJdIfh>D}7k& zSE)FT3ou(beZ1!z-Ew?IMxi=%zYE5-X|z&fC9r^s{MK(!;ygr#*>hH&01}HH%sf^R z?vXj~ePJaf|Du4%^?A|>bOlc!%=Cd>*7s?$^EfSQ2HToK*5 zRP3j23Q3ZyQEpnnfg3RJkcPAyB-(esTd?SnQ7M0f`sSXJ1975F(@`AT&P+|IuF}`f z&GU+kccFkjImPsKJXpOLJ`LE7A(IxBhDpR%fOqF4!X5f@BPwmOU$TyCb(p>QV`L@n zCnS>(&&>eIPJ=E(qghig`z}|n6t@O!s|pTD!Avcxv?U#YCpSu8%NH&3}h@H__3GVME6+^WurpSTJy64bkn{fwByL(Y8m7;lE&GJvbnIB9Ur_YBI7z9aYnxffCDRan+WOSpwJo^j>1MRZdLmW%PZ74>!);% zy$pGWI}3W``3|~W$6h_-d4On`3RK^;+U!cbjM>c5jTFOoQ%{~}AOYruG3ut)qc~B>3fDk$WB#XXb0){ms8{c0ooSKODy)MmEq4I$n$MVC*auUay>c*M^Dm}DJ;#K7}G>&D&u|VjCjbbUbc85F{ zr<)eJV6)q7Fu5{?%^{V>g1xW6$ZI8IaPXZ@D!#iI48YiwI3ghTMq>=1iseLxxh$Oa zo^`!mL9nJCC0}LcE4A?&o2(Rh4=&D`;$H-O7C`j};K2R9XgKAMRAI4zgI490A;Z*y zkS4mQe)|d4LCBrdXcwp6#M8(xxQjU50A}E+Y3#v7kwUxNVO$w~JMwhC$eUC0^4rMZ z4{MEqkL`d~Rt2Wh>>U*zYK4UUwe-sV4IisqpDxyRjKb#cS(lix=1Be&2M}(>1L#3} zl$I5(7Tq)n!TT&VmSlEuO3+4m=IjD}ghA62gub3&z7NFGJY`b91r7}Ei1TCnq$pq! zZEaotmdxXV;vQ(A|I(=k4UHCiyc~MwM=` zq`{%3Z4L=*IioAHjpaD)DUx+MUQVW!yxFnLlM}TWzdh^70aii&{oOre8`SLPJLC?{ zx{CvRTB@l@JQOM6_e>tJu8B}SMUF$IZ5N?Ltq>6w7&5;Il=J#s7@X~2;Cegc6fk6m zz@#tIslLWKX0zNR$(E=hs&|$4lqCg$F<67ysaup~!TB`khSgRCC4hYWSrBpi;w%sV zIMSq;8vidObKM_$-Q<1ug3H_H5P&$%eT z54q_ez;C15peppT*dYFontV}DMOiFKqp?{p0Rn{k7q=v6|iy#1ZLrY zu_sWSt-X#)g$u0Z!DD|6R-#jo?`VKcW`fStBl68{3A$_D5Gj9TYJpYv4KT;M@%)H2 zq`5UJKm=NtZ~eZYsHh0Q3m_2uxeKl;3I~@ufH41HWyl6d-2epQ4)B6%s~IZisozOx zOj_0bgbC+Wc1xY$UKM#VIz6=;Ha0!p`*Ee(JeeN)1x5^CC8^oLMKU1c?N4A6Z6Ufc zcb<1!xra&oo}mGU_F`0qRSsM`1QbH?+V)cC9a^=vi-&7td2%5o7xO?@m$1zh@`xGS z(-dosMaJ(eoBla;ZEQ9-`kZoN!x!YqORUc3CK2`$G{V8&BlinXQpSCp$L}{) z8it$?X0Qy(4`kjvry7hA8;l7U{3SM60n@O9%43?0K;*OdG^A#IGJ!bmiJ<2xP)Ox# z6*Iz~g}>ZCp0U}PYp7vtJe5Zjt_^=}``Hn4ak$1|Hk$27dimo6wxi+5K`^5|z?p8q zEjC*%H`gV*{`?5CBanj6)!JpHwSjbYLAGya?B&&_{WQw>hxK&?bc|Jdt-TTGG|0UU zM_hfJeB3t6yZV>5u=qD|DEuOZ@rJz>zZcqE1P<<;xD0OWz@drX)>iU(h+2pnANJkl z-G}y*2jda2lDxX5Zv%wr48*0hvbXp50G*o~xD+7_aKk_12Gi~Wj4JXxcV|#VO~+|S z;Dmbfa|#d{`Q0aX{g1X!=sQlQcE$V8@Ck?So=JJ>Hu85}x29pa;~NvDrD<*NbBf+R z%gd2g{gM)(=XHb-_xgPb?yP`-gx_rIWWnbK+|MEiW_?uusP|Tdw>epEj2iD)xx(Md_x8TD(JTVK2{+sIhD_;H$S6;SYzR6;cDAuU!FVi7DH^gIu1EfehTjH zO0cHE@Z7Fj3B)2J_JF+)PX{tBhe2M6Z9PC^U-VR-`1S5ch*bk$me9#&`wRbqnQqHD z98h_jn-&sDR{H|A#>0ZXenQA4>m* ztZ=94M0XQG#Ss zG_zT#$Zp$v=xkL>;v}KjDy8qlp`Nq&P`7C;oMMM`|Ag}0Dx1jmp*h+6B*8I|v5nus zeyNW)f}bGcMd&^J>b@D%!L2l4?_#H=R2+D-t!0j}hy9!=7B-c*l-iAg^qnq}na;PC`5pXO?xq*clnbD+zb_7m(3FW(GG*{4L%{nt@p!u@6@fzv9_rE z;3Iw-K%#H+?PMM<`%?xpjCn9cjRmER2WHzr3i4Xt#C?x;bHdX_h(e3WB|}+FQtZUp z^WaQeI>S9wG4i!(w&DESJjJQ`YNcu9h-AnEO%s1nUXJOLC;cWZVe+8~E5G>XogS$; zQ>*0OEV-|woutyqPsYuqZKY}?GA~aXC-2e=yWr)fn`NkyKEZcl%~SvA46ZLKYxetapWB^z$(Dxwn^e)pv`aex<}1!>OmO9%zYtPKD*tP3=k{=CV~Fg%_DCbXx!D z1W}A!{-Z%{ZZ9aAiF1Fh;Ex+d*-7!Hk&@<|r&nXLqJ}@9t1M*kx?bWZ;Q-`i< zvZ?2s;R-LVB4*LcERfU>mJuPD!cH_+Ek{{h5&o{z(iGO~2}$9`^{9uT;a2@#;JUh~ zCy;$k^VqUvdZ&sGca=6*%}AP^=^C5#5$ii{$n12r_f{wRpsr=2OV9I`vkej7kQ}(z z?x*RaP_UzqVz#|jn2R?y`MJ7w15o^EGI_uWD&do;5;^;&_xx@uWHT!;8(XSUA4^!~A>-yPmEnG@i@=xFjk6Z)Kw zrNa%4+X(YD@Q91+fH+5K!4!o-p&NhXaov++r33CuxhGq#xbT%Lw=fVP-C!QnSqeM8 zD>3GuQ5djasbS;CWYXOFay6~{aG6rr1%)BPYI?eP^OY0`@+6wFKD5M+Cx zI(2zy;=aXFe)Xi+23-$XjOxl%eIXx43T=wU*X^8ul3p{+_(G~eJM$%-P42To9QS$n z&zDP&yruj=|<- zK}?$&jyyfBm8=K1@vyVyrlaXE(z&)L9%&pIOVwyW~pT|@bp+4+H&J~aPtlL#WOJv?NKkLcJ`JwgJ7aqtf zPMA`ud)wJcJ8Hb=y}KJ>L#^G~qG|O`t8`h;TNF2^5?gBc>A74rpRJISXJkC9M$yYL zlg(ZDDsYRW*534%=hayt&#>t`v7c;AC=eUwvKI2cB`cl|%>k%tr<wW z>QPyeOHxG6XQcH+A0R)6AS5@uc50WfwvvlgTE%UsM=^Tr&_$zCAGs$jGGfN%B{V&W z8Z|C>{C~0c)3_EjWt$M8~9ye1@{ck z_>SJ~Vwy8}R|%{gDyxn4-;5y4ia_kqRYVHr75jYh!m{0!;=Tfeht~Lo8@0kh@#M1g zG_eB!d?uo9bSNVi_69D~CQ{yB^-WTbyL*VVICZrB^geFX&{wU9yqz8#{mBOSxk!gT zb$<}lI-q(@GeJfchoStH(W~FNwZy#E`ez+}Hwu0;K3{;E?=TD1nH&#$6gVVaKiiThKb<6eC9zImjkY>NqgPgq|M2SUnC2QuEv zI+F%o(3$ru5(^Hk= zHhP5CjX#QCvdqHT$rc!#RBXl|?pFOawbS-9s}!p@d!j4Klt$hIqrJZDXHIx_cl)+< z&nS!6DC$j^`(f+0RP9an(^Pv`MN{vwghgfeXJERO95Tb(nJkV@>9iG5yOT66evUpf zZBS%c@AGOz@;w<$jRP?}yKFwa1+jO=9f=yjqHG-_3$5!QcAyh#U4QTlmcTuMADxhv z^8UxD5chKOSk$Ndu(SK3?Y1MA?{>>0w2cc+WuoIMW2qLhf6aizmkJc%8)J0a&9bI72DnJ1uL$WyaIQY1QG23!<*+{y5Ex{H(96HXj=*|FkDN^;8x0&lsQ#W$*r#zxcfM z!df#&+;+dDuKsN`@%Vlq!Jo^vqKniYl=h7WDj%o!8P0a?`V>A|haiKPhpQrrdB+RX z!$#(U+ppBe#QTvRJB0U3w(8mWBDX$=21g~3tYZK5`CRK$pEfq_ZSCnw$z?2Q@`-F( z!+efNBO^X}f2y$JS1pP)TG}8dvu7fq_>|L#{IsLgA^rG@d8Q0=9O>6rMs6Pk87(p# zr3O;3ser+4e<)L~FHic@^Tg#)+tgzEXh^FHbkbOyp2|Y0{8&>^xzZCSW}RHOXRDf% zagjX4&*453eU5ismQAemK3+EH;E>5=m==9nE_q3`t4WgWHm3qv=dk|b!P%kvXZ0u7 z&Nx)HnTW$0&6PP3w(FGd#^NsYKd>Ag`X&)%tNGQ0ca4I8HcLmE z0P5o5uI-6J{0@g#!P_1;T;$Ja4B_Bu;^|;#$>=%Axfo_&M|xpu{ciAB6jXbrgkwy$(ymQ0$>Z?UP}b zHyP$dOj_+WlC=yI*R<{&w(hYdj1|!@#_BTmE6#J%Ys-SR-`JH>T6}u#t!((m?g8@v zu0&}Jh~t%*Rlrv2Zbm#i<45^B8;3B9D6dXfD7~Gc-`*> z)?e`|ez-;M77mY3$>#e%KiVw;v&4kYabpYP)J zSR4`7)x&H5I#>10RfDrggR9T3V>dG|6?wx1e(1R=9X%yc=DnDn;FHULG8%-4o+vXV z_>!`k#jrhfxUR1I;3lAnN)P+b4AK3+dTD+-CKJd=yV^h|ktai&9y3@|WRTMPY`sEf znlioNQ<3;W;VzX4x09M@rP=QH)KIZ;T|enmx?*}-+ng^!y7qcPG~vex0tR<=)i^}i zp^jLE{Z5#3Jgph=wbR`gQma6%5M$mmSHZ6vKd;_2wr5@!W*5}@v&o%ldbrSJeQ_$Y z|7>RcEH+1JLvVhaOyZ!hCRcN!(s8#|y1R0rR9(0l3;v60b7aZQSZ5$SKY`BnZsz!& z6Vg^AB1N?1fpP3jg^1o{rAp-KvjMya3B!8R(B>(1&qhWM+ux!ipIH;?kGu%_aQ|LI zet#Q^ZG&?vQ-Xi_6u!gwX{pK2{&-sliPMBaVgdGQ-;LKW^Xc@mxjPgSVs+CWKg0`Q zk6-tL{KIzbdCSBHwyElj;{7N_-H}hYd=2gIGhl7WoS%$3Z*D0Cxb8E}OHp4S@U=}@ zweq?<$3L56_iXHMQOAF&7-IK9MDM=Re}SB>Q_4vHb+u2%?IPD`=SPNLFmQ-UfcLb$ zTX^?wM03qnGbjGY93hYYoJ6UWdo zox5n*L$i5WAOon|r?`$2f!F$AU8?$XdUL!$RrOGWwXwL+7>Ah(m7cNDtztAB!SWkva)8zPAGxCIB8!e zKiPlab@BQ0cXl>yAuD=Gz~yCD7Il0C$cRRunc#eT7Wm+|`C51={S)68(ml$TKHuSP zM6FVJ%3n~6fiCvRia-QxjJN9i^dC;ae*jwHV*Uv~8{$e?(EEb80t zFkFO>vebCa%l~r%-x9b3x(<(y>fUAbe0gSJ@lL&m3Rv&N14bV;Br!-b9s$4#d@_6f z4O#V%_<-Uk3qLDkE3l&3=Bt!-=V@RN0Q@v^(3CeqN$3b|_^&d(u1&4FFGh!-6a@FW zraYV6njz1cAuqHMDBI*Kqtu+|9HGEG_HbO=U!I*WCOj}W?5q#@A4%*-#c?1j!jFhT zG%V$R@sv+AKwTZi`w0XH6d9=iJy^NAitrC~{6DV#`0G40z+C*l=+IYmg7fi;!U!c* z>Bnmos76(pO}RY_~3M;muSJM;Sv5Hi>moY_xCN}gv#Lc9$C0gG@w4?cP z7?1hC081{AORm+ar@c>np227H5zy_XYmFp;SYI(5W+mx)xgCPg1OHjy!o26GznfCu z0)b4qk>O#*Iq_*#i+Yq$pBpOUaTCi@wvhAs)=2sCD;>an0}K`U$c+(H7F;-A6|}Mf zQut9g$S#L@OEfU!ufti zf3*pOZu$;Z{!GUCR!3j+Q09*iJVV;L2-G7nmewJefD>JdjFT*zb1DeW2<_KnF`?}) z`mf@a8DF+Ue|OSPu}3@+0IlxUqMJ!UhOHq|C89H*zUALMGES61{utkgj12Vq`K!7R zHMTe&rKMo`5?ve#djwI9&&Wx2-Uj2FQs4@HmhFzR4B!yeYw!2_T~gSL-k!XLaA{{9 z^8$m+ezf87pz%0b3cIv4o#j_fg#X4D)apU2t|Yze{IddYN$gfv?*dV8AoPj^2x$6p z2ksW{r$oV7Er+DhIbgAq|8&te{vkH)!ddm5&1h~N;(H4<9Y|QYq@p-APBePLJ7OTB zwDrGzQ@}a^qWE%VWLV=?w@LAhDIZlR!erGNAKfcok z-!+rvi#|e~ukgT>%Nc3gFaHRVq5wEm$e#bX_dicGJ%ElFR7ZsVv2-v2Y>@D3S!MuD z0&d6$U$!QXacfRsMQUCNTOduC7bF?(A z2`je6zZNrKKtJdGclZ9kHHP?IUgZH29B`AY@Hkk2LZ1>}Fv$g~mapdl;;}nd3(%!S zw$Rg&7gQ&}yf{P1*%TnSoS%Lr@jCW z{REih*HHZA2r#v^j504#LJ1RblK^<4`ZZ%3DI7V70h}{O>@C27XJwhUgWb|1I)Pa#j|-q^_lLfnJIfPEkTV|{%O&Ht-9{=< z0r(hCP>Sj=9*gt@sgeXXR@P-uuP2sVP{4ZJ7!azJ27K4LLwT)6W45UTC%#UHhG zH#}6=EPxBUZ;zWCulN1yRMjLy*aLX-HvmF31higz^Cd_)7Nrl!@SrQ&d(lu?4bkVn z2SrK_0I!p3(an7@ks-8(FP#UH!g{Cdk{(j6jp{(~+>vT5L7sJJqgs2hdK?WHG1lM`^HVoDVO3lpeIXTvGO zpbv3lTjKTS*9smLR*mKArON3%42FIdAKi8)0X%Iyn)PgO7@YyC0ssiBuHF(q5*CFQ zFh=|`t-W=fCj5y#4Q|k}r&mMrH(twt-7HouXge)u+6Kt}cXDpgs%pCdfCp}p zlJj!%X~pj}02NQTdR}iqs|6_K+5)0KfUVwv3M+rW%4(P13t*2>d>T0HqJMw(J8KG* zPU&_)24h0g4!rI+0E`ClD#wB6wJ1PVKZ#(JAq9ydo>cVD@GR<#L3vEtcM!Kcs=kI% zVY{Q%E)ifV_+QZCr9xohE8wxO!yl0(h3@Kg4Vlhd`0D@Q=9@rJUMj_nekzbz{-^9W z#8cx%384Fvu@bT^InI!CEOA#>ui06Sv|^e{&V-Zj*abjfW>>9a z+KiVc!0?Q`H<(V&4`&UdBMT z!(W=gHs0a)b}%-HUc3eBh z9!oU<>a_e~?SyAYa)leu@=D&*wtxaWlC|(u@U!+-{AyxlwPc|m`Qr|N!7QrSG+zx+ z;-o41Ov;lmg#_BRj-_$;Xt`c95Xkb%D2~1MAycw0TQkA0xret==@z2FI31?Xe`Lho|=Oi$Lh1*YMTz|4@~-tzL24l*Zn9S4uO zTb3rpNnFJ<__UykTFn=2gJ{)?mW+O|BTWgi6(>xybdeUqm|ACEBxzti#ryGtV81>` z&h3V)a05)C2CFX!1PYC@MR_Bih6yh}T+e-Fef`1@QP|uf>+fK1W5CQ?jd7gUXM5p; zP}^R$scBK|kLMaAru=sMHc}LqCW+lrOSaPkB^_Ezfq)`nq0}Xh`^-L7bT5vATTq3P zUc+dkyxp7*Sq5t1jK8eO6FCAN{av&ei6*!#pZRnLeSO+v`A`mNGu9efoBI!2YMS61TItd{epOnh5^H znE0*B)b@Ueaty-fs>xbFaO!3IPMW6n?lk&$y8JFX-#3fdI-4Jg!G7g*;Rh8~O9^z% z?wM7prTG?b2W7FMBs<~uKk4Z0SK*H6PyiEJ>S@YsuIJo{w)2gQCdEf`D;Ofmh1}#L z)Q|cQP*u*G?6u=u%@U{_r}F`;Wak4T>Gt=$Z?XZ!Vi`C!lKggjR)$af#L%{{*p+J4 zrKjHUZyDADK2g8G79WHzU6sxe@Qc_o420C2}5 z!V|Cwl&t6q!3%FyMhf3lhH)*ZATjp+ep}3^a%b-G%%|aH7fk6i_&)=;BD)TpoN#TT zqu-uBOJM(lD5!1L%^VKjyl>OiL5kLo!k!cDK4$<`+(dUvKe#|hxS2g9ADU1I+t*1gSR^oiV8`|CO!Rlk z(%RMWNzZceP=#8BGchP*r@egt4dP;P^9g6cXEG-+~yS~b^=3ilaoO{OAc`9Ak!Tmb6^=R@fZJ#Pu z9ui8HQ#a}$KKHuG-Cmil(H~@5yX^>^oD{gk5MJSd37EpaK%|C35romo7GcK#2Vdz6 zX8A;!ud#;c=tJZxjB#$xta#+_&-xA^A3D+4ssg?z^dVM>psD9jZ17S?Q3dv!*=WYY zKB-BFe+Tq*GtA8;nyIubKM99*omxT^Od)EQ^0~>lP6^i{$sFF2OFMirlO|n?A>|#f z22GeWAVDfR3H%Zo2pyQ}7Vi2!kuH3f{Ds{durlN2f<)i&?o zTACWE?m^!^LT&q|8LfPk{-3=};>W18XX{&bAm%w&DoK3Nk$wAx;4HlcguUpJtZS7s6DA1h=m>DGmkb>m*EN1CEo)6>ZX{JGR+ADGQq&N=)o*s*hJouP3{N zRET7wlvr+AlX3CO&erU}=f6MTs#psv<2Co%YMM!_U4|$g6&>etJlk1l$fkmYi*Y15 zUNzWn4EZeY>y`A^0FBR->tYStzg52CtOWf%stC)vLy2qusC9KRj%ar&idXQeIUR9s z7a)18u+A2J_=OUd&(Rely~{xO3sVsVQU9=BpJ-=zzs|zV;QU;kRqa>W1uOYUD48j7 zwOpt>d$c}x4MW%VUo;E8VX+>{=hL|2^c{J9bVzKs5R?z(;hIahT=-e`HX$~sv&5yM zxqnG4_A=W(c^C8SZdOMzaa_vkbPjkLB=W?HVr3fElf}x5^moNh*XtL1sn@*;F@Rsx zTX{t;h~e6~mNuXDMnzTRswgQ&)p6)r*1fLF#1uQ&Uw!{0_ZMY%f0o$v zcmVBwA_3euN*iqs5;mJMKL*EpLgW~4Eq#Y3oTN}vOTKRpcuh40u(B`0ZexDyyr9t7 zyn;%-J=^_!u1G=h66L_^RiGoOXI<$(D&RC zYdM(u(wi)r>gm6}(9+4iS5jQhnB!71RQG#pCxETW{4M9lAg7{Z(@Z@<&&uVfc}{^t z8lkg5j7N|M226n_tIW#Kr@Wr~Xp=8&eA3=ON1c&})ZE_aFzCPevmSTVecXl>}eVPi2!Fp&TJ}?wDg76 zs?@#-gKH{%-;L}uy%&s^z>njT3B+Lt z{~&LPL{8h)m5^5S>A)K1lZJ({6P<GS$?6w9r9$IYhJf3K*l8LH%k zS72ePc47F5Z+|%ajVWSM)ntqe|07SW3ok3;8BuQh5KGd zkvV)^IfqOAI3=Z+$_ar5>%s&B1)S3Qb;f~gPR}10(LaF=wdOY% zC{fmAKl*I5XTt1F%uJ+)+2qC+jI^EwbDv8;PHBJk#3eDCp9gIx@BMnmybyel&Ml(> zQjeY$_X3?|(AV!zzly#{XcZ$W$>=Z$Gl%~e!D=ez_KKc$xq=v7aUIXLjfAU_4=TWAeU0Ju6ZgmfY*Xp?A%j=RBW7)o`!2 zJ;V>&PL41e9S8-sfZ`HE_uETx`S#O)JfgUUozbR}QsgO;Ap2;u`>bwhHG~ddSFeXGGmq>B6qpzgRgf9u z6-%@Z&_l=54~E(CdOvi~rqu_7kEw!zOSUdVcI@Z3v1uiOC<=R9WY_P!UoQ)LeF&74 z4syRo<=(s?u@JQug+;o{ua%X^Hel3q;98T}ug5WL)ycs9q(TB4zN$%JwZvPgl;{a} zs6K0v4Yma|3B?E|~b28+ohDct7RJow+Vh7p12BF{_RQ`Z(XQ zw7k>|sxxI5s_{sXd0$R$Vv{|49;@5T35T(iHnVZ2Fc)$luN%>~M|c6Fs@=NhoXs7L z|D_(`xno@ylDq1NM~WPb=N>2!+shbTRh~zu=yk%FY2TgtCVkrcSNLJbQti&%Gvin5T?6U^-T8Al0%KSo{PnltQSH@2?bv zlma-F@Q;PS%s2qHyth8;ANbPKrgb}*_C4X;M~QLYN|+;e0D*QL?J9ydHP{9aggGeo>PYrDN-PYP4`05 z2QKu*6i~l!GB}8BEvUb-*HBi$!Jj9&@0`tke(LjOj5Yt($#zq=@87|~bEM;bIb35! zC&qfGO2*Vq+Mcr1RCe+|_=*y0vw}xbp5kXcX3rs#Q6xsG8zOR|B5o$?y0H(Wm`BVv zxf`06h-85T!yAp+D-5`T^xs8p)`ZE3w^Gd1May_#XTO@pq*oeO`eo6aj7fa;Xc?Nb z({bp*RceXBft770%U`Kn+O8)!M|GTIoEXS9u&CzRjCOKoUlV7`a3C(3OUHO;P4Ds$x??z$kQH$QvE&UBRGWOv7w=k5b*phT^^u zx<7>mlw?%EVG;q3|7=|6Dh8J-UiOyXqS}izT89P*Xn<@M_!jpoY)1Y)_?CNYiFPkv zuBG&qAsk*AT_BYqmKZ@f9qHn0I=Eoo&MKkZ6h&;A&tjo}!FefBPmf%-^W`W9e{7NA zl4QYR?fHFqKJ_A@W>;GW9M1CZ;VcxH2E@?A-Dylk7@+Yl2?tNjB?LcgsJ*lce*Z=# zzYT%@)k`?BHVPkRwU<22pJWk`tODk3KI(Id5$v2341un7ryuY6o*z!@PH&cJCvEJ6 zl;)T7Wpna>|M07!=h|NsY4^iPZQYpWHBd1U!L3S7p1<~^1s9Kj^R)={%Q>+QBI)*~ zPfh?`kp#Y63?)=16gz9LnwBbV(BYMA~-JuY?niIUD?7GC^-G02SlfPOj|t z?;a%ISg~vbG6)!e;HPgkG|7Wtu^@K=9vg=ogdaLPQ7*+vNo-X#Xan;}SMl8ISRbG0 zc*z443^%M+4>$X|f1hd980vPIT_&{giJhS(rNsHy5p^ld%f;AY| zbsK(skHDgyMg}0Ysu)*mJ-#UD<7Fh_vt$ND|Bb3#6zhN+gjw5vpD|q!Q~!M^bdLRh zMmNPAs<#i?=KAbD)|cxJK?Pm}#ynyhUO<;u3(A>;Mfxr90ea;G=vwNUMlz)6*_L0l{T92b^aCOxsLKcdRWfP6-|jhr9Q24$ zTSg*cx^yw;=j{TZ-0O6$Z9k8S3*F1qC z_4UWfm$lvyJ^pJ@j^sLXf}1=h0=?KhQ@9BRAeDI{3-$DtLG13|GuKOEDrwYbR;q7JEHF%a|M8 zEX-|>Gc~;(5LvDVvI+l9HlsCEg_60=R+OY>;d^kedSGi?_xji5T)JJ&r-dlZX9>rH zK(-VBtIUtr)1_&NlB%F`-?medY3O_0XRfe!d^)A_6%g|E;{Bzl3G)qFOM73Rj$n;#7;O(6?P$vcTRSs6eTllFG z_4tCp<^W*7uup-rOq;{+5yIck7_wydNkm4+XfYXH)ylgh)C? zf%8>1fyuNW`_hdF+&i#5A&HYj9vPs3b;bV)hImcYr0%_|d-J?yPj~?FbttjnsxI2) z_UD@B1>582C+t_yZsiLglb(2tLA6} z^<}`JmGN=d{ve8b5&}f4MnO3|sK}2ddIRV?o147&)zNt5Sq==IG-tNrmJ62B!wNfWF zYoC`D#tEN}zcAA}knJ266FV8^&A-EEQa1l~^T+cmx!JJD8jvzYc5H$bRtx34ndv+5 zfT>Zq22Vs%s38vr^0+1_uwUbE7+pU>1K8(T2M`g0oz4C4hr0>nL2=x_Qs*G6S~!-7 z$G8cUiQYJ!ZpAKaHz%Ma@3prnq9{%)PT0i=+g-!pZl#QileN0-nGn5{ zwRA0#4~zu&fW-u6wv;({D}%K;^<-H*MzH5C3LGu-hC0|eB@u+9V z3CL&2?|k!$c*%%T1+d@ppF{WT--@aYPbHjcf@p7l2M{aj585*RO}zD&-SSV{QQ=R- zrNm#9fj&S{iIVGM?DqLiO z$DY0Zp7jv?fMde0RQk=ZKS+q^dFTXPcEf#sg!8i=OO*V82jgRauS71GB5W=5^CE#6$Kr|GZa>&)8T`ng0r4|uH8yj=) z`my-V={C0*g@zX}mqWeXuM{rUFpQU96u==>pg^siJ$!fZ#Q~8uM=k(YmWj_LKa|LJ zQO}ap5~Skd2{Dz_c$8trg!ifjPhlxi?E`ic*MG?0%Os^&L!@C?EWJfg)m^`>r|;0K zXP=U|pLJZcI|6m?;dC9LmJW^inuOdCm)P*WrJP9|Z+fz5obIsw#ErbA<`D?+JltC4 zpJ9Vvg?^Uj4Vej)L#KxU`{h>%Xsmr{jJ+G|ZAaa09~LU&eP>qP?by`IdxIc)?j}LE zA}d!|JHrtz*%S^OYE2)w5>zVFtiN&Pa8R* z|9TLXgjI%3iMh`%$q)^q;)`)2wstkR5~zo$TR}wy`OJE7=V|N8fzH=H#5*h4XDPp zW-6oMeZuc?-KO=#t5o)pVq}qtsF(+Hm%O*8k`QIS zTTCfpMG~?lkuOFG%f%&5bTAi1!-UodZqvUml@9W01aZ{Gh**eau9g`O?#b>l=lXypk zHh>ntIGdso({euvtyueeo%?VC+n>p83w!>~iS@c66e|Z87hVcpMsr$t-X||38EjPv z;VJySpNb!SX+G6XnOkz+B(KkOrRbclrc>Q79lj&ZAwU{p7c1*K62xxLf~1u#fR|yJ z6L<+>#$Agh&uJhr?k|1!Ul`+hDvK-QUI4q*9})Rup_P=tLN})uC0sJ8IgBM`cP$U( z8cp7%ee11)D>#^q!8lBmlEr<6ZL6J+f{%^B6^^*t7*6=Ie57Ur!HKoK=~$JT$R@d5 zW+)9}n=kVz_A$C#+*vA{sXi1~`FEo-(UW%?Zy)twJI0)i42H}xW*Sc5nrNf~sAnq1 z>_gvm|0bUO=W((%a!f8(vz+4y||1lS7 zEWuST%+Xzd-M!DqZcMPxhdi-6eQYT8l4x1xH?PPUfTLZGRj{j zYIN=jHnz~^Nov9Ko#fLhf*#@+&SPDg^C-cmB2&j|{iI)hm_{crk4kB!0DW9WtqI~#nUVN?zJ36sb-H$!Xp9{F;OoZ`$#RE4z zO|Ho1GN~f~XQr?T)7dOzweSsL1PkceNZlr(Z(~J7yB{XML8tepGNF@fECmEB&ZzHE zAFgK6zZ*i;SyLvPX9~BXna|wxWb{50ZEF1>#NQIS;zY#kM5Jta!rUUJS%%4YDwnuI zu=>RnoxM)dZZY1R5Eb5HxyPCIDN8?fJSQ0v^ROM8cst#pxr_!Yb#Zp~h3NptQ=hU*FWl$# zm#?HQw~XBoUvZ3KME(@Kj9cfkYLCG*;E??cp+VS-_5d}S@!MmSXNjxL%!L|6=Isl? z6UAYa@RKS{qiFNaP8J##7b>;1{1@`&K--#qF#n=w6wq+CE7>Qf1CtK|QCA>lMDLFZ zfS);e17BSU*1j~CNeP~nY-0!eN7~Vvq_dHgy4GxhSthc)+df`;wqHS5)xA7xR$JKm z(I=!5;!`~&TU<{lQVlljVtIQ>cQxsw-%T+|Tn*;l?OWxG`FbWDQaf9j3qHMu9KBto z-yuN2W)|+wuh60Yvc>xAyuS#I|$L5@>Of()jW)lM^br1QKR-@{3t_oVF)98h@X zvH#G!W=qS&5r(;Kb{%ZbE^t8-stD|s{PncN35Rahb~?DHaP*oM?uoU;9g^@;mDIku zQqmA!GSRzr6Goo4snoi<4rheNIdj!{48mHbsH?>KpYu~rGHns}seZtPI`#q3k=Mau%QkJ@XFA{q2^@L|4933n66I3_sE1Rq;OtZgTb#1adGgH zNyliH#dB4g5I!c%#0|Zvm9aHh@5h^<)6eWws~_tvxQ#{%N9@geF7Qb1n|EgfLd$Tj zNnz2uPO~w%bn}J8uj*JJiwhM=IwA7zVA5njOebJBtl_kn(UN8vw*B!T>~4k^dXT}&@ zY^FU=22>Y+!77Kf;v%oD4pt3OzaqWt3~ug--xgKx(3j)r1*Dtip+*hg`X83 zPL^M;PDOK(`r0A8_Cp`(CoyqLImHob^(|!ZREs&;?g48KJ;6!sM)r&A!7A+C2oj_n zjWH4s?Qs+Ub5&!;m$lu&bPOzs1y{4pqm>gATD1N2Zn}A6fh!2XfRoiA!s%{tv4R z?A~`QTbhIkbJms&3ID%Ixgn#ywhz~P`3Y4YjLX%SzfHDl%!OoH0`MQ}6Bm@g=_Aw^ z5KUmkvxIQ9=I1J)jAsMM+u+w2fdXYseAuv$=#N3R>ZqcCya|iO4()XxKjL)T0 z291Z*33Rz|N_=RYImBi$v~7OGxRs(OM#p;EHrQF5HyZaReay8&ZfV&N1y|ZQrUVRH zAx8~O2d>hkkRjr=pA*d~bsjxj^+D-QgA_J{;2Sp?d&8Wy9U`y<@4*tG&m0<&+NW*! zMn8$(Q{N1>6&q|D$z9V=Gf{g*!k+r{FTeg6RzXQ@rN$o{)lv#wJw~^DeZo(m5tUEA zQq@~Jw3r?z!iLqn>|-Y@Ck^V`x1EfN=z0=dG%?@^H(|b&;A1red+$E-S6yW5>)h*g zmmR;-IDYjw4<3^Tzx#tmYfdWfS~*T*mWwG`6;tFKZ|w7f9Ie#8EQRu!f+woRH<%6m z-+`aN(s64lZAvCdlON?LNu66{;xdn^KE*UlEas!~sj z+!4j@3jjaGr7%{2tl^#&} z@tUY$+qtOy^?F9bhu@#bN=>Ofs*#m!)m+p-Hnf^X;c{UVgxBPRjlMM2>S<9Of`#k8ubKjtrNO&dxKxX8_5<3q>hdS%Bl3F@h z#Cr&c-#L!r>*_5aRez--Ar)1Y+74{ciKr$+m}~9h2UAkE8{Ch(weD<4R1D3brf=_n zW9hR|KP*TWm9hp=5|y&SJnd;^;_;wZOVYf`KGt%=Y_;$FLc|QS*Q;w2Kbxagp^iVF z&hD7yDoKte%Ja412-X94K22M!E@D&XD`%ZtP6ZiQr9bn8>~JRB^Dk#Ga7n{e`S+3F zD|DmDQc*l-vo-Mym$TkTdL3bA01g3=t~H!-80_#bR>_Z_aGCO8 zsgB7d&mJ?9#zG(=*|YXX_n%L_sMY~5Z;@X4{c{m4Sj;1**0);!eaZhb9ovunyAh1Y z6^iJ^PgfOyQvnR~0dPEDnSwl{>oE5KNboT#XQkD`6+^Sl8Xr1afk(4uqm6)FBWfGS z-GIZ!rpwhAP1ArgO{%VCI@qdxa;S-f0umJ}lJKwZ?D(QMdjAukdIj*QW8k>nk7xBQ zjR9n<^FAVE!Po2;lP-mEpHogEM5H9>7V4Cwq^Gi7GQqFU4 zXn+)h^QFd3qoLy(_o=pQzGa>~VEF)zz*oYsm`*!#)pa<5b;~W4tUk<>ns;abJ;K{Y z2H!}O>6QKin;2t&>vF@Siy6c1yU!eu{%@TE)+1xT+4n#2t^foD5YC*G<%C4Eo#JCl zDTn_7l*LQ#fQA;+HFZBnxcpDh2@SUepgUaj;5syc7meAdN6Coi-hZ+l9$ax=TmqJ% z92A`M13CLW*J|04V&9F3TJ{*5;GO}JTk6SgKZ#jc150p^?BtZb6vR#pjNuAwsZ~TE z(2u7841j|Ozw&v2U(UQuVtY;Z8}ce4+O705w%>l0E}{0};74rWZfk$BGyQ`jFiUnm zTZKDf{})o;P6nsYc1igcRUn`S_XRUn@Gtme2p-J03|7w`pTu}cSa1XXeJFTn{$JQl zT=zg`!TIXve+=y(l&X(ItV@K}Wv9^RpI?K21_~}iXN1%MprAG+*Jpf;7)-`I*f&Rg zn*5JJP{s+O$-Op~;~zQ$5_tLqFV`zF{^Llb*3WbODUWESWH5*xa$jdnrN`Gpg(8?b zmh8;FKVn>YUEn#v>}aj{=OQx|I1R9dj>;L3TjKgSOEd1bkY=Jcw zXhHDPnu>oe;tnoS`PSiIJ_TPI2YvumD1(2l<;za(WS)}Nu=$J+pr|9j99eS&jdUOEVEuaIvF8$fO15)$)+VP88 zJgdDmX+;bDN-lu9E_MWf4Dm~9xzyXamA5N5%O7+O-VvGb0HF(@)?bc_9JT@Q<~N{f zLv>Dz7(z|K@%Bgm2|x+`4*&|6)4jhTiJd$y7tnp)0$>7oQEmO^dANpGuGEQDi{gzO zGIX1eQ7?f6{s#3Q2=T>85MZh1CLeMDR~1-2q&`gjy|`ILxDEDmJpaeb0 zksZT4zq8u%^^Rj!STig4G{FCE&&ZQibMtf^lDNrA!aKQEwImwCoJ0rpT?H4emFt903UMN6`D_&S=Lhvvc^J@r0qpEuIW6IXZkD`47YG%uqY0SOZy2k;g+?cK z{_N9GO7sJpc6>DDEFou*mGHgzvNDo(1}cyE0yK+cA*>3ZDPv%%?65bGdI{n!ojnKB zS9&^NF`dk*A9zz1=A*>T0_7BGU^Bl4hcgJ(4zTceQ8^3HDS*kn@0Ykcoe~668(`QG z^*)>3ZEX|4N92s;Du?fY1*2Svn{a=%(p>m!pVRrLRe(Dy)NaL?pZ)TQ-ziNv1zsHK zz^Y)+gn|T;X=#?r5I8B}M`fTGBl|QR#g(r(w3t-G5yfltBK+{hlWUwF@!JzYfM)`6 zkCIUcI~Bv5O$OU3=FL>b^!rdRkz7G&$DU0hbAQ5Yz@Mu(6|5fpUJz0M~cbE>L_(;MC z6x1pA;8B!06#WNcdj0ONa0Yk`gJC*gKex$~zKPM)(q;IirsDYC@MCuu1+h6E`Jhe& zEKJJ?2JbKq_0bBh(=Xn-U><|R>bkU2xPL=E~DeP2D;;lU!um0Pj1LU zi1n=Vn~R-@Mu1#_hD}H;(ezX&_(?Jr%YA{lmMB&i+-;VyyDg+@A9l$$%Pij;LuIk~ z`mtkwhl@LUAFfn`TQEW9=$akvB{mP!n&~E~X&Vd zZ*|P7LR4J-t^idzIsp^}){eq7!{gv}$a>YYn(5}D^_Qk$wB|Bv&54Ba?BD2-vfclZ zBl4T2;T=zkR!`jM;i8mVuC5o9D$&AbmRDUSkyH1(PY%THP~a#9Suqz$U%XSJw!}^9 z!wf!*mEUZxT+ma*WCQrt_`cQyayE9sVp#EXL~aWo{P4-}u9vl?euB`E(gB8~56U!s z6g|W?4E==)(M?E`Y{z)dWN5L;bdAh|bd;iVM$DJ=W0ko9@;%shF0-Nf+p@&!Rb+bxuXxg;ixH zciOB@S66UV1?L9jDAbA@p$<pTBPtzZOcl!xuhu}Z#PUc?er9&^AsS+f)ZOB<+|j>vNY-2`VayXOG+mbup(Pb=)*H{Z-H;l=# zaP@LLE$agY+~uvDz$gxu)Huh#WYhF(X8NaTW`Q`j^z3ei@8rm^Z7*W%(=;q4A$evb zVy?qPs=b*-mI-#AcSkiF;ug7W<1SiCF;67UHv_OUZ$fBaQo3s_(G=C_y<-$A&^k!0s%XIP%~^<~JeDpyvh=LmE)6~n6~5#6cXjjJm{kP*caYsdPL+#d*J z!>%}~OLe)rxqp_w|l0Fp`#tz9c{ z2WoJH59zt`eT1YVTW51H;rXb+Z9-?!b9}wF#ZCj(vXkDOI_XI+JSSPNxca@u9q77sGpibqYBmD`Tf0Cu}1VO+w#qUI+?ggM$qoH?kf8L*z)Oq?s zI4j9ZmwJ#5wOZaJw+a~Xa|qFs&lBRWFRbHvGfE$G9RLo=e(xus5N2=r>7rvK+#0`D zgI*fZJ;wUvK6}C#L>#@uyX8G4@Ox!ssP;f^o@#?*@X|j@4c@IFpCjOW9zC4<$ zHr^kdLI_70GK7OnWs0OkrW_8*oS_gh4;i9YIOciIn4yG>p$s8&W zLc>J~Oc^Z3^!<6rO}_b(6DqC$$Sd$1D|hMiQwkzQ^1x>bA4{-mvLsnNV9>3Qw112K zHgY}x4LFE78Q*6}QDq!N41)vSt*6%6Wxwa*>KO?30X>0p?ZjdP@Zg_)d$?qN4u%kA6E_G<_a&y2*30G&w zm^Y`Smhjl#ph&^ejM&GQY7~4aS)bFS1y~yEhJ}jqmwo*ln!=&;M8S1!-hs-8&h(IS zGspM~zK`l5f9T2y>}PxYOE(e5n0kS@0VINpdm`pQM4iWHN38gm_Q)#Ng zkSEQ~(1s4J7{M2gyt}0};xb2`G)h`L0>2`}=kEQ0Lm{@A9gCM>d0?V`-SG6pTnvTa zTN|0Ul?bAUducAL&Fb%TjE{9&Xv;Q`WAiB9xR4TXsYes?r8y;chyHBCM53toy~&x! z%vVNwdi8UB8$Z_Cnk~c(i^S6Z==zwpqG~aiTu|9?cIhJ`{#oyOu0>}j;&IMnD<&$G z{tKfHX{&U|N1s6~8y9tG+nvq*f*Rvz%KYw6Gb3<%WdRoQq9uoHUGsPzGbkHGU2G^( zEw_KgoT2$`-BQ~?Emy-iMm9@X-mJKmO~R-pjKl5ps#B2oDxzNzcjT%!?O^FrIE5Ol zLqww9<&t~-V@X}T=B-zv55*w!f7i_Mn!mN?iu(nxS`F;i8V*6Zm=J6ZPvDbYHsEG@Nu>Qy{W zo13i4bY;OovHUq}tf>}@j-PZA#;A7tRH1;~*S(K)v~KUG(?nMWM>>M``K>8s9-f=C z8Riqxy<^@$D*Jt8r~ggx8SRdsGD}YFhB$WIbdQO+&P;!qHZ#M=X0w-$+~d63sqp`N zjBx+EmSriu%s8tyzil#)BdN8CalFFg>3yax_PnocDUH*N^Fo*0?lJi$#SSA6PhodHk3?EVp*D_r*C|%GGA4GpKTzvgy>skfrw0% z9@z;_|6BUB?S2|F(pZQ>GT1N&1ZjU&cFnlfQ% z%qLUHVZ#D@gS>%FvN7y7FH_)8PKWR$5`p2gS;ptIRS)_r#A(EmNg^qHFV$wM4qsa} z7?+nLYW+5)I&uF7EyIqZBbQAWQ{p7;^a$4SopeFcpesoIcxmj z$X<+1-!rYDfof-YaRi@E$8R4c9PhM2#ho;2N~f2Jd=SDAZfYkQ87g9#pU@dKYQlh< zKJX0T8_zs?Ad=!^oPlnsb$`;tkDaZ(ks5~=_>OB_rpvjI()F&8dqug`>==&z6{V&} zdp2)w&yCFv)`6tW;@fF;LX0i5OlK(V`8GFRdP&xp2JbUF?Yy$3fQe`iDzsDK`S{su zn7txot?>O(QVXUhC`~C$Oop7;+{#Fk`b4|=$$O3S@x`?n;_r{HOo}_7>_W&d@?RhOv_-$vv(Jm=#AaA__lD>QWd767nY-GdJyuR8(8avluUf89u z%9wAD zCiOT#oujN4tF+tByxeHmTrh9_18zj^S5g9=vSN{4h!cod(eJzBJ%H$uqWrq+dw(o z!p-}^?2bsFCq%wyT+DfP1iuQO=6wH+bD^Y;btvOvEw`|&Al&>S3ot2NKL)Ey3oqSe)2l_y;zyFB4fm;s^GG9WcunbAz5~UmZYEVQ0Gp3BgbcY7V=bS zOUz`ys4*2z@vNcFGbVSvWt%mfom&NvZe5Ah?QZ`ZzQwzeD_C-I`WI;*x*+H%$-&6^ z@E)b*>W{x=UPYg4NyJ|j(GY)@G|^pLUD&aD8jqc)`4F5FP*pjt?-I;&G^zRF6?$6y z!s$t4>Xn+ma6Tawck59}?|_HL{{s54Ksls1iw?>k;-gkT=NY6Zo5>!sav4|vPgSat z7uXMB;4(HqXuGpYpZ-B;5iWzvP{jqzGQjnX0@pV*r#_Y(X+&Z+V`dd;SkX%LpeKHQ;6Z!&Rt& z*~PAZP?PQt5KRFmu|5Bo;t#*bMGZjoH>Uhda$hQU_)D?PhrnTc1_)jEn6*A6({8Nq zue+-Xdco51ghn`olf-YM)=)Gnklk?bWihG>IE1D6MDU{>_DM8!J7sT+Q|PFAZ_?r+ zt%`e#e_1+1=qnHWm5qT`M5Bf+OUGQ-)t--Oa0}pz;F#*hEFkODNQoBL#%(VHYl!fP z(mK#j4X4x*GaHJqwzPL}DTZX%I6%qZ5@R%L2BB*GvKs87gk3-gx{rqbagx=u!rdjt zjyVBWkwrbpc-_Oy7{|zTwPlhxT4}~k{tH6teJOd(MXG2tiP~eDs*nDsu^(x;tff3O zyqKi;y~t&i(jl#3Ti;XHo3GHge5v_aTom-R8^-FBz!>4b7aKz=PHZ5omj9Q=n}xyJ zBa3DDJIvdm@tjA>B>rx)z+Jx*7k4;x2}$FC75Vp2mj9inMLipK%#A_c4)6qnxu6U{cn?RkKUuKhfccDD~k zk(|YuNGVlD_%CS?l30Kv>^y(U2>~*Zn7n^rDhty=Mw&GyL@1NKJO1@HU?2xOFAtuj zx`%LMK&3JHX5$7CMt+hHvPJe=>8A*C^3?~tev}Ob_&`9C)LOb7n4vrX`mcV=gs5}C zFg5fr9=^}JV9Dsww|_fW-iVZ9rWw|=YGJr{1$ep%m^+te#RNmO_B-5=Mv-&&!x~eo zh8M!RVP1xzlCRfOJAB`5jl0QK+{Pa2d^$w|Mb0_nDBh-Vyd5;dB3e=DbAQD3ODFBk|{0%N7gJ_gtNS!ShiD-=D z(GZNvEuAeYZafYgt(sywkcWuK5D48h5NCQqXd|V>JZs+D#nMjotQe^SxR!%NjAs7vkz`vVQEs=;68 z5FDruuvVmc*7SQo)NFuVJYll;(+Y*dFeJB@MtEbiC>6r%>s(r9FjIKYZ5cP%U!0iJAZ zu~cKP(|gj61E#SUfqbRGn0jO(KN?OZkwb*k`HE_04BN&%ZhS#Zw}WJY*_3V8IxX! z^meN6uFkg7)FJAljX0D3s{wI(^|`{L>NXf2NAuqHEAbgW5~`59E^?nj7!g5>4@2)9 zi-$5{w#B8UY;QVv^HB`h@yN~P`a)WPc;RAsMp|FbBH2UC{xJS7OH{oIP2|HLqiNfH za*-aNhs|I|nW(K0gZJl(3OjkoHQpG+>w0z@aR{)H**nFNo;7)^arPB+YJUkf&d@41 zOI>yi#-|$)3qgbCX9OGelHPj+ObW2qXhW029LsCopdrA8!eK_BG=?&f{7mhP&7idN71v#Rv{3ItDD^r`UtsHcnndwE! z8)YWH`~LbE=|D0}I6o%5Z=qxN=3&$;M0P! z5TA(dYkLxn)s8=9_L|q6ZM;2@$&{pX2ONuyE3@sf!E48Zx5631?vJ}Z)r9sU>)@AHMV4N%XQ*;U1WeFeYOKoNFcF>I|1OYuUYl6H`qaA? zet!;SYgbSW>vFId4Np6MZvgS$c`$j3e;wuR)#^ZSbnzH-tUCWL3|_yP=Nb}o0Y}Q` zO(HhoshX%b@a6}mH+xNaWY63O8?KP7PHaJzxRc}o%Xa4(+yfvXGYIs*PVs=+?npb3U^ko{U9`E`FoOBsyJrZ*Hu_lqTsm(hOXc$(lk=5h>f&}6${~!% z`X32co%o=fuSHJE>wMuw8-=y?XaHkH8Qyg447@80%h1*#z6oC>8+J+~<`GK{IDLC6 z2@)8VRCA1K#mF-<9nQAvkAG1kAVA4t<*sQiu7l`>;o?@ZbrHjQ2d$V6QKmvY_3{ft z$Bn`ZgjcUCieFGMoe0~b;M7j~k>41S2_;gdeOgvsR#`Ch+)Uq<M4ruY5S0=Yt=cTYeV`mv7B$x?4-!;jvQ* z<5@IgE`Jrl=<<%AlB3rKmJjB4?v&*-;I|&t3)RKapKQ{pY3EAuQ}5cEBNv&I^`kek znpF0;r4an~)RW^Mt{{!n8*ZE*~SvPe;;-UUDD zy-JxJ@rAfF6g^Ukkz-XT;K@fiW1CI*I(8CPYY17WUdjhc<*nL4dR0GD@%gC(Ca123 z(mB#k0o># zzC!KIGY>YVs}+!nHru*v!bn(RlKouDab3s8Qj%Z^_=aF}Qgc#W_43eO09tUOVMR^y zAy2`Fz}j}3QDYFkv9*H)cR!bsnP8GSx<&S~(zZ%&@1XX~hPw9q`v@@GBkw)qDNjr{ znEw`Pniq_T5G}S`yI8vt{={xsx8n$`b@|}A6*=(m<7=rBLCI0#>W3-u;J&wY>PIDD zgQ2ej+$;-(&&)r92w+`zraY5L2VO0Q)=^a)!1KpA(a%Z2q6DJsn8JmE8~Lm0^Wzh9ppF4yf~rCiOK z4e2icS}10qps{FHJ^#O(`mkvi%p-6JMWMOz@Ulh)X|w&=oJVA^`X)#+46+fPOEpL6zJd+l{X!2tgufM-et149rp z6A_V@5)mPlx3@7ivorz&lSEEWbXHVY!VaEn=V+h8ASb1~!FPivo#Bzhg8CUMnX2;Y8y-Y zjSEXA=bj5KVDc}1P(2Q+;67~Gs-Mn|yEQQ|NBiy}aM8d~RKdGI#>P+*526tNUfTKo z{wd9ZSw3@)-sUL2T|DuNM{0F2o;&+I~Eicc_t@gs&_? z%q-a1@Hu7V+kKUmcZGYjt;5MlR6E)DY7=;EY#9-)^6M#-pxg+kY|UiKO_N*?Sfh4D zsT8o?`!BPz4{1NZm_Gg08QZ7IwhUzv`-FEEdIbRn_ot7m%^oHEk;^m#%%#9&Ck!f7 zO1}VoA=zyAV95CCvR2_ypPBYguM8-}<;Ubr9a0n%j!&gcq8K=(n$=&^*wb>t(^Iwi zJ=4d|r43>)g;%~Iw`ZkGs*}kKp@(XFoL_FGP!e7 zuq$Y=y7jbc;vh@yxV|kUYQ*r96U*P=nHCJR2OQ6tel{bWL0tELN6(&>c?xg@d?}=` zSdGMX3knOQMaRaFP?9DMU+>Z0x4XE^#)o_9(lWbnE&~sgejfaR4+u4F4dnGzjbSiE z2=JZ*dEhBY{u2qJW|%eThY-2K-W^i3p*>{|9bWE6fMquXMhvV&76O|u0}}+DE;6AHt1aX@ zDOiAyBpPHQB!eV`nIKe+5dR{u1eq7Xo&3#h!T$NWO+m@}eY1tpgi`53wnaqpkq|@( z>Xv2#U-vbG^SeO9$`LAw!OlbdD?E=zpbqCMA|%iG39?@#GzKkB@NtT&2$#mcBwIwD z?}owwzXeXq|0xT0ij)oJ72GobJsDzF4|x%+!Dp$8hY(JpXLM841uG2}r)vfDy$PEi zrLhMGL~sE{7pT({4<|ST2RSXS3P*4$DjcKw862I=B9=T4qF5{?1|^T6IZ`s#ZU+)3 zI9o3n7kdD2J6J6Oq_3epW=ohuepH4M6W<`{`RG=Rh8W=Gv#J z|Ft@5QK(IdkV-cGlT^@WoL`^6{;l&>lrksRqT-`!CyO8EHk7c(RTI>ftN5HrszZqy zCm{dl3)LsN?}TE)OR`+wn+073T}ASLAs1QyQ!PnuNmrL^7xnz^$tV%enslACJzO4N z8f%eooa9a^_h%u=IZ1~hlUj$&`}~V0xHzA6S3kUGhW8X71BmdWltu+&?CBDsw&aCG+PwhSJE%!b#_h$#fmI_nnvEqpFrr zx27la+ukF-qj>xj{0@9Pd?oxOwgGm$6zi1Xl--nlw!u16b;Noo^{CR7oeB}m3wW=n$vb7VKT5${-972tnjS9}fa?*^dj5?J+&$Ib| zW|n8>bxL$SgHVf($51VoRrKa@BKr1~?5G?7}Yjw>7A$ zLer(^S>(HIjDbOF&k*IxDgI2YwJF0r>UG7V<&@%8G3^Ly~sGTTS+p8}xrr&VtJoV&B z(W+X*Zk27FyhFJof2Mk7hUE)(32sNZUvzN#(i-47hkkqjYMQu=*oLKcr>>rrD%?m{ zoA^3`JdultgmZ!Oj~>^4+78r2Xdla9$Pl69Vw?R>X(eG>{rG82W+8Ilsn4o!ZIN&3 zwdt7_RT?!`B7E>qVf;S+B%*dmQl(0)N@Zi*z5coRc_BYHe<*(>KW2whN2w>{gWfB| ztJBlk^}@ye)55bH6em;}`~gB9lsJ?!EI%R(JO;EQRBtzUcdH)>Rld@wy zN;G^u{OrYU%E7jWixqmTsNS|4 zw0YgU6>-NbJ(Oq7ZGM2_B;&f=8hju*&p_f`at-q=Ii!Bgyla?J4^z*cU!4za$oppI z{=) zdPP;m`lxSGrS@gBeep{B^NUhasYwNw7LRATXZvZ;Yvep}Yeu5ZiI>@7{kc{9p>6GJ z;&ypd2ejw@lh!li`dy3XZq$1^0c1GL(-}jD`@8lk-=XLF>ojaJsb`$;Kz6*=# z3kt*5OFIPad|$Jl4Q>Ww4^QMC?I?gOr$S-91_089yQE2;Jy z3=9$T;|C6wl713Ph^IW+GhuK_7LYa2Ex^ksDy-Z1p zBxiV77(#1@(P-jKyZgP%u;H4`^WEvyy8HQX6cG>9V=&P~qtyzPNH9tQF`pZ5!^p^Y zwK~(-AIVHY#^Y&}r^}7;o_9+UDEtq);AbAqKWzQC7i+RJ*4>Wj57$~7k#L#1j>x{r zGK|!Cre3{z8GA5lx2X<95>T_6O#IPqcN@-dKl=(x?2@IZq_hj6zsfd^vhMx%#gX))U>WCx}6fRM>yOX~h zWqMn))0n1EXI%RPMp`w7p_YqP-Ero#1(9owGO6E?snhT50;$p(zzR}J{AD=2s{4Mg zb}(XV7Tf0ebEIJm zjHMx-xo8@m8C6y#FP)o(O=Ke897L5Hy{I0XT;Nw&t!}dQv|Q5P-r3?+Sk;T_9c=DO zq#OTXM?tUY@3b`-8G0_P%bsKYt?1a0!9&iCS2NeSH2p|R{kY?n^YCmIL(nEhjZ%7a zP5$B%;ZW6}x6OCp>ALL!H>CY*S#_{D126CNxGzROB5g+;Ml5U0LC5XI)0x8By%aQB z))sr7=-Vyy-^k;cZbQ3^9k{h0OGBw<|BOh}pNia->@zj<{_;u$?fLr(&s+4M?=cna zjwX%nXL?&hwz{9UH-_qSw();1*Xh)DI$Qlp#O+Wtxm#ZWZ=hDKALwznWa8It_P}8_ z(+A_q48I9^1bV2)*pgC5(j~?BpK#$E*q(W13iYREIs!w{68p#X!W$LrI&d)vl``lr z0MnAnVM9D_GoHfkS2yjH!ft^rgXje(@{}A9a({8>(Zq-X(?+DLZ}9f=I1L{ilyjXO z@p``@z|D)!INk(tkoC=Goz8j9F=^bM$YDz8svk#3wfFth#+z2F#i2SVShPKR$&m~Z zaUWz$n5&mN-T8dh%3`z5+x&7hx?PBwQXZKUMX6aU^p>3Nbu%roYa;Nh#`(p~V<%Q( zguZc=e2~PuZTH+LLVQ!`7mP>R@tlfI0;U}Aw6VpdJor6v5Y!8U2Zb92vd&w~JoXB-Tk@1!C_PJIq1#(2KkST*2pVe~Z2l^q_LF zaBStwim$iO5ywdkTIQ#iw7hLv^HOpI+QNmA3{9_hE0EB*k=I?2s8GvUkXSWEBt4B* zYuJ3zd`0VOL{LuxC-dbRIAxm6Gi{$V9V$5lIn~RzZ8JbVu@n-*W~cX+-mkRsdXX>` znW31}FdXYHxq&)POGe$mwxe6UjuhV$(u7HKK7|%_eS6rBrmx^{_BV*)qQd2Ivb<5( z%0YWs@P19|_uP);7}H4_fC?sdGrbtqd1HAv$c^?}(DCM*3f8S7a@8tw#3OV+srC(1 zy#NK1z|fd?hp33Fs-yBhWc9zFzrWe=2)w^sThx#9oHg~nbl%lhLTfZyM{a?H>{zpu z-I>h)6>YX%Pt-nLyEkV)d%s<0`ZmsrBK@ldW6vq3nm2fTyYIxo3Rjmq2xsh2okAXn z$6t#E*0r{xkKy(}}ZTT=JH|KMl)ykvFb6rT(2d zsOY@i)A&WCD1EG4ZgdgTeU-ZLA}-6d`>FZ7T& z=U~^RW=jfjbe)KknAfH1M<&0P(^<%a&1&6G#igUjP)Mr|1ReN&T;0c=N9 z&*IA7si8cn_!Ij)R<9Qqjlq=$tCbch^MU#_fm0p#)B4Tljd!ndChza9)LUupXU*Ul z4>UgA@YHE&rb&Z-dS;&61RHQ!J#Zwq178%JRbzC#9*w}HWyFTJWYf9Xn=X0~=e+H} z!cR*|D-hN_uE*66c>%xquAA=Rg!l3~=B`z2p43i8J%0lD46-wfd=O}L!FY3m=N!qp z<8e<=Z2Vy^uyY!&YPo$af|zf)N2Nj)&lHDqsv@%AKd`8rQ63aFkGc${*~Fj=-jgG` z;-BAPK1WjvVMp&qF(e&0O(#XP0Z;7ppeGH9y}K#o52+g3f-4}%?GWkjTW_%dbMUpu z&d5q+&?DCh>NexBQm50)DH0_fs-A@{{`Yd^`L$`xbtiz1x?Ec;-_>IoN zGfS#)BHeOpteiK%!1CHm?3cgTJQqa4%eVM(j9Pe8|=pXgS0Um7%(IhNXDNdx{ zf{H)SwHe>!dtzXSU4Sst&ezB7d}gVoQOAmuoSUAFa+xKH1KUes8b4bgQ%goL>XRzo z57swwywTcoOYb9)X2-XDepr}kjcLz$&ufdMA_2w+Q4p>7Q_m7bPM6meV6o_Xa-MA_;a&pP2%Hi7y4dK@-B+-3 zgVkzzQ!sCmh`2lsC%W4~xU}}c`OHnBff+61Ae9iJs7jYsH`8Tbm%@ zn7c8x2Cbk*b*grrL2F=Fd_ug1FbNy1SiH690C<>+sSZ@S_ z@t!TF?kmJ#%$wzPg(RCy}~##hbzyA_)ioWLoRA2%mQLolF&zggwkNq)g!mf?v1nNs{V zo~&*Nx)f_v7D>9UlEj;WSDGG1vrxdD4=KNY>IyQ>RtaV962*^^2aDCq3ExCb!j_E0 z_uA)JuMfSd{$c*@u-S6;1`Uk2JZvyTq;`@wTDV56~qJR0>ZDfJkN;}>g zMz`Hv!_4$dvQSA{%Y3fPOqfW77(kHdF=$@vSk>V-@aK9?Spi)GNHM+x6M{XCK9TLZeR42EV0e=KV9-ohB1qJb zhFOMqSzw8lb2Ylajd}V$5XoU=LGj=$@-;~EVA2idYD_GGFu#}u!GH9l^$vsKeNlt? z;zOxXPlt;~3R#Ss1y-OR0s>6`&_RCciYr&gjsRY#2-qqx_t^rb-xI+RbcdDc5yfGK z1Ze=$eYm`R)V!>Hr!T?*EAY56% zbeKgDoNlSasQdrg=PLmyh<>T3T6ak=D&xjN@1Ttaw!&vm)OO4h=U!Ez~P_i zZF@PGkyu|hPh=Pl{Z;3XORc|)j8y%X(k`A+7NkErE?;JEN0|+!`H8WiK3_#6OJh&6 zYz86y`3iZ9A-HdTy*K_*Lz+$J1lCzD&9on%G}>%15O7%kp^{0FJf1HiZZcqBe0iPuAR8&IrZI}gWEqSKhqgs1ITACp7S6=r(1+?=kc1fh~J zpard1x5~_ysTufzntXQ>RJ56^*KImqp#q5 zcc=I#cN2MBbQ?dG155z_+k?SUgJ&wC{Sevo*`-OQ zC)EQo5x1h#iWSFFgH`HSGPB4>!9GarURGzb!M~pv8V*O-@lo~5@?MJm<+RIjIQyqo zAe%}*Sa*1tKt7x1#}6*pNdVMoDislFMDHu zDLznEIq!HXM|5I1EU;hun6e;Z6K4rVx5m?XI9vdP4)OZOtNeIxJl*7thHbA?uQzBD zDEyEVFU2juD7{K!#uFfofaBkGopZ8x;9 zx}2}mWv*R)DG4D^Ja#|sXOg(2Om`6yx)2|3!31z@c+8IY**~Fr*=A&<+ls&p`7p<* z;i#UMI3CYS0V^O+tJTR3`*2Txqri%QV5K*iGz}q3O)8zox#4%Fl+|)wv6}yA5+hFg zS9-c6g2t#R$~FKsBN#MI%%te7c zUZ`w5OOgw6@rX8syw3ir?~p%DdG|ofxZ*x&ch)$O@OzSPAuiY!g!(#`!amy4~Oj~*ON%EVf^g%`n0rOIS5ZByqU|5(sNl+pK*l%WMU86_C1 zm}OYxX^;#p!5gd=l(`)a(CWQNKUdxHzuqXMDv99|mWhr%Jq5sSfeM2115+{ec$`kE znwsnK=pfe=*~{ZfN@#j7Ualusyntk%_)(r!w4SvbjMZsWF$j9`-JR{*ksdWW728sH zU%*-}wkn-sTUA^#d$LR=<4LYSAmPl|a6SlaG8IoXSZOQ){182UPqkqlfL^E~nz*WW zpn5JpxPS!=)&VrJrmz?zQ(~?~mn0ll6hcmUZMQ?pzub-`s}8d=5M-iBILUn4EO1|R zI?}eK0-k|tjG1=%`144yy{rTf&+TDYumwA(Np%6#82@;^KME``N?>bNs;Lr3Su!81 z1NGzHM5=|wxh*RyG4CRpkVg*dAJ--oEnJ_;qy}AOoWa6$r<4PzV2|5UoyahI&1G{3 z)Om{zO`6qYM**OO&Q;d!uw^D;kw-u>{OrSEo&2TiSFG`P$}saFAw@d3BMSrXYH0U3 zkM246jQ8Z5@oP3B!gMOXXNxY&XB}Y(5D}|!giHq#KHE?kuddh|8XsqRLW98zxGg8$ zX{e*cd<8QjW2JMb!M4#cuhuG>AkK*8?zqE{AQw~28*Y}mKodysQRs!KHN4(~0fv;8 z4h}cGCqkUUVx_!@Am%6q^AzImGvRN$(Hh{K;`; zr#3aii|*-DfD|x~hnoXa5QHxI9|@BcW(Hf3Y)SL`+jA~r z2f9!H%Ke&irl$An?N74F-6^A%CQnJS2I3dcmOCvW2M{y(8p6!?EdW&Q6}s zJ9R92z(7?`q!GqgM@_`q9RBr1;dbTEp-cK@@4bszm8fG2$Zki)g(E;1HM6lxvm3x` zFg^pSQZ^RSC^W$kxQjF(!sUe5?^gAq#M4$Z^=$E8bV1(X6Rjf+7fQo&Q01=WI9l=( zoUqQHP4WT2p%r)NzyJ=dD-aPUWvXADP!hw7&+VpaNf8H=ZqSD^#L=&+Z_4wg-lA1^ z=WeJvtCdHu2deh_Pn0qBZFW97Qm1`8vU!(DJl0jTWWCqQtnTop%IqoJR ze;t45N%j3`0GT%M!P2 zqE1bf?c3o1qE4>?i#!UFA)Qat-?(OOE%nH=Op_~%<36cG-Natqesb@Z6WmfX+T)5| zaOIaa3%m}7(U_U<3~AmhtJ8gd?vHd;)N60D_I?7pTbspyY^25WGwT zo)3UdUvK~jw)<KBVaq99Y742{y_vFn0>KXVm$CVZou|fUKkZH9SQWU69`sf z2w-cl-{L#I;F)iJle93{4t5z9WPy2Luw`)y;~e8>irow^8}12fk_-@sxtai@?`l(6 zzd-7RxbH7;tuY+^C0*wpZe3$i%Ky+IvxCSB4^;z#ONPMvf((34WErv6%QqF9gh6Zp z+UN>`ucM_L>R(%w8xj$h)4%NBb4sf#A8qJNd!Jx%)F4o;wgFIZjCKuqats=I%lY_d zaCfo5{rmaIL?ROukX4dyxudsCegK&TgSAU-vv2j27911`%9^&S7h30Ox9k$WWg|%x zD440w_uAqlfB+b!Ie>4=#3bx8A1oOMUZzfOtNA5PwX_2so3eDa?V13XtcwHqM@#b} z1aJ?Ffe*xD2+ityB7(6yGYEv8iPKFl96*MW_P^i!=`~i)N4FT!*nQCQT{uOVEp`t} z<}}#gfeguR^CcyRkq|u27lNrPa0;5VolLD|ZqSGcSub`W&KC}NnfM}xCKNc|y0Ga( z@b+d}6!7Afk9o15`Qi}=uUS(i{*%-1GoeLe8AKlUiPVetR7O}ga7{*{NHdKx17h-7?4mrjq zH*zn3M(qWZ9_WD>)s-^r%noCB_Ym|XYIMoD=c(rkTaDsRKuM-^S_PcOqc%Ni{q-FhMqI~FBRt;^PnW_LDut)6tzDNItdIbTBV4I}n&1sGg55q`uj z5&FWP1F-9ri5A+GQ3zRxqs!yug8~Zl)T^aiY&n`}X;|d%ueS9sn@b^r!cBB- zR6RpqeF-1GJI*j1b`GdWFSwWN4pNlv9_*JGO+GszK;fbI1)ZH_Zj>eR-z$&Gy(`d* z5SJ#_lB|CXSC$aP0fj8&6|ldX*w+(28P=bab^AE1Hb0cFkk>5eld5SDR&y*ZWruwBZgQ!Hbm zXoZ`pCaE)_3K{Hq@m2nkvvT%ZW~Iu=hH>baI!5>PV~rq+ce8p%2Kvx65!+;oI$^ai zd*}jxaUvy6GHRwg*(e9ix~eTNBLNUFj1=bZKC$I|rE-!R!{U+;G!bk>I9w1j94ln^ zWgiwAD&YuAUJhyz{7!oNV?f7;)^>Cg0%WBp2eb2(X8}OOa8MIrcD*9m;N} z`0Co&Ag97-Lslc&+HDJaTOMO&&e!qsN@agtjm6>=ALb&tM7qeS(Ai@99;?5t8mcnX}Oti+LTsaXBf#U5se~_C+-kc{e(x`_!u=-EDdt! z&BOOc!9l1@qSTHOO&8I852McSsa2*keKoP((JG&o9oL=j5tf>iqHn!f`GSATSgdG9 zv%TF}p?imD%%;q*D!y_ABS2hUOC_XgmnBk17soJ^(;AjXLADHu{{l6ve(VH|Na`;( zij1~d`ZZF4yW&LGt>Wd}IHA3;=3Q>FUw`LTQxu!gF6ZPd%F@>?0LqVR9i*M`{8-Ma zMNJP3L#ueID%{2swB~#Eba_0ip@-kJ`Q>5jd-%TLsX;xL6`XhL{(~Lj()6Qn7_roj z5jF7zt|Pv&#?kg>7!F2bV8p8qMgw3ctg8>z90C(E@;AC8FM^5mSgw|F48D&Z`xO;A zPI5X*qZcvYvCKTGCbsLle0sL|nmm?;t67QjwMp!;dnKYgn!e;ek1ffp6&$%nxVRx# z)iid-ENF}b@8MeZWY}AXVVK49L5iK~J-E$%BUlp{^PqihMPI-mq=f0J zH+I9(TI@f-3NSL{9oMRE5HO=0(Ooo%%)1ES7+VG%?8FVOk zEEA#4Z{G8_m>RcUQdCexU(GUbvqhr|nfspJhE|W8YQT+KVT{97-1;iGKtA#GYlns? zS2Isb2kzROsI_d$<7uN)LHp4-|71aAG*c4NOYF%1n*9j$TG)}cZR=myV_~*oDJ^4QjrDS zMTU?hwlpaP4EtviWp&;=mapld(;`bNue!Ej1}lw3n<$O08O*8k%8O)kli3OJx~!ER zUwTzVBgCtRDcm5V_6a3nC7Pc{Va*7MJ+_I^?8<9>@m%#W=dv@+r&FxvSEg^yM6HZj zHxKMlbCZ-OD(f>cCu$LCc6Xj`dO~cS>?})^3ENu4k9GcuG6=FWV+DME`V^_r!irMy zhl|!}#5ej#1E)pu5%E;}O*<(ttxQWFZnD#{crD7)Hx6S zw>OOhd)ZPxhachw7K-g2J&XjFqsi<{E}5w=@aYU@!Ib zwiaYt7lR}?7}mXr?t#E95G4QPs974ISFKuPaiDz2sTzGpuC*fELcUe6Mc-n~eU>PR z7BldzzKWC-ZSd4Bf+0VgbcXroG+&SHD&0gbws3Rqz^~fX>f&ZJ*R0m#tx~dY*v*Do zx;?8u>3=rax{ir(90VE2kd4HQ>9vzpz&f>D83Ow%=$2THO;CjV{pputuF-9K+q~mt zRsVIVBf8v>AOaAlzrxY%>cWMDE0SAOE{>p%*+xR!K+!k$j{qT4)gq_~0ER@;duG%>rI{*@aTVlpPs+O7$Dz`yt(hs1M1;GsoKFSr#54PEAu67eZjq+ei z{~2q1v~OoS2{f-c zzOuIdsU8-b{@|aNOTH58qICf6&hL(n^>2LZVO!whpAEBokuJ_5IAR2~KbY!mBOh$t z?ef+(a+79E6b7!#%9sQ^+{I>I!BvnPC-%ld*3P=xfhI~>mB3=&0;o~|^G0(5E3y1~a- zQoXp0vT9gnPBL8g@VE}L{0;Xf(z(Vf$wFI0#?pCI7+Ma<50`2Skx2M8-EI!Z-meAT zDMl0NS*05mMW^g00X|n&;ML)9rLhupw%*>l3b3d(0JoFVmtIs+Ad^Z32oXlzG(h`R z7|gQoWvo7_7@d&>93w?Pb9VquNMmZP>L9q5sB)z?{p-_hJUArG&|5>`QA4lvT*=m0D~l;%DJHGP+U z(Ira{7;PUt`b+V+K0c4MA~LQ70k?xG8?G?F$pj(S?jMC6K=}{{3}T^2lQb6{(L-KI ziSj{+GsFAMbp@b1*8$B&(vahVmdOF>xBeZ?7p60A_d82GH^G4WEN%|YuRi^X&qhAb zRg4#vvE*B-Rh~#1?#GTW|jl{Rt=TW;sB5Hx>rO7hhe$}XpUgOO!-wzSUu#ML> zfh(Y0+5t3l=nlT&Q(gsPk>0IlLQ3r@U?sL&yJ0Mu3xJRuz?tZZWr(;Y&v z*qW`jEYH^qn8Yu{49S;)zo!S1NsqDt4t}OWtF+5Uv#xISem&NK zxeOw(X1nYi$HV6TlbcK^nrk*&aMgz?H`LhqYW2A3kGca0v>GovPFEU6bEEmqZDCP~ zEuZx<1TU6bozJ-)wz46?Z{Q2L(T@&=z{{xZ+R8vkn=*ly+k+DH@j->jYoBx@56G<^ z0ezAUJc-j{_B_^|qXR&hZLY4$ZqC`&{d91xH5OB!gfq2LF4+pnNA%EX(^ z`VMhWRv+e)hy!Kc7LTx8)l+Jq%C0C!AETEYBo+j zq&DoLFVU}mBW&8fxnAU>6M6|7=c3wlj&O>&r?s!EU@##pqAbds8RDL-1N*IP@FN+> z4*Djf?&*j6j9)K-JR=CB|B*z{dK5mAMKF*o9{;gRe+QBU5|9*dgZ~~hr@ys`nodd? z?+_}bi$>(u3~>n_-}XCeM(89EbpI;3@P{LU5W^Q6h{(g|Lp++l8y*|iL){WqS)|K2o;@{jdD_wKEzQ8H2=4n@Vi8BEKd`Wsvx5F{w7Q;?9hLXwdz_Z%0ra1^;TC zZx8^YEOEWtxcht%|IuJo!Rp{VE`32(tUfLW`hz_QH1;e1EP~ZT+*C(}P)pflS=XHB zF;zXT^}d#Tc{_rN9qpu=k%InrUF66NU|~K0ug=GFYAdIL;}rZ27n^tq9{T4>{_6O{ z#vftHUWsSTXh#t-zZ5}_fG@e+AjtnYg!f)6w%uJGij_PrHXcBYKfa?v&gymb+th@u zPr=?IuwOrw)_-d?j-yCti|aqET-#eZz%F%t7~Um+F2!}r7_KnD{a*?Vxe*^kbh=K@ zv$>*WqtpCt=WvHinFZrpOxq;>#uxH0?Kant=)tN%K48n~N; zcnQe~M>8W%Y+{B(upKc(fO{|`==m|ABra_nt)r_=Z}Wkdx|LL`QN|yvGvW(wVNUhT z!w~zUR^%ptC&zGgahie{+b|<_px4#9-t{|b{~i6Tld|AmcxXQk&u4&LFYn1iOg1r@ zI_;0g5zvfl`|KFLq|@46>nL;^Kq8Si#F^N_TzigbMZL^#KW-;7#WOK7()SHzOLUkq z=bO#F9{#;f%VpeUa&o$%N`h)KX6V4L>{l8#OAEq&^@)@LgtSnv=AfuE>b_%8qhqdL zz|y({VPeb8{6l;FZv6t{)1jTtYqx-wiR&RdFgzd1g^3l&hX$u#zx`XhE3PL$zuLOX zI;0O)-)S3K5fc_}&qOBCm6xgc%+1ZUgw&takq82ToeeL@FVK|&%qM|XW#r}YI{!nZ zUnobi65NXj!y-EXh^Z3+U^iDS=!0`R1%M?$+^>{ITf4oBz3>N`o5DRQ?5~qFPG0pt zXlZrZQz{QXjLO#fsmv&nuy3hOL`q|99tQZrVJilxSW}POD4dV#v1IN$PRffb;7wWp zY%Ei+|9-bjq9IsB-kO57=)L_nM?3iO~! z0q9ra9|!FRtJuh4`>%GtIa#KCKOUN}P^vJrHO-tKlsi+^sF? zyQxGhT4h|`P7aoSe795HS!s*G!KD0jdEUTPc0fU&A?c+}=Wet3pFRS}@_sPChsc75 zS{#peR63s$knmVUKl<{mrwtm@yrA~jG}|8dD?m8#z1DafiQvH+kh5f6Y621o7Sk!x z+@;ZEs|hmxhbr*()Ba;CmtKm$76q4=B?NRG!$~Fm^E?#UuX29u^(13_ZB3>OZ?H3)(MS>oh<2btg#UXR8LDHCNB?{_7hzD$q#F8 z$K?%^pHD3Zp_O00S+9O!;$`T3vFCcdnVs8OSK`vns5TfJ0Vcs^lW0)&IRYt9=96w$mhEeUUik>WHx{(!`_aHc?p;IW_4E0)!P z>4D7W_f7YT4z)nZ&07zrJ4^RbVe}H$6MBHRm&6XwV2I^>KAkr)rTx93XTOy|EbT3O zV*^c;Tw5+E`Z!q^C${+#Imxt{w8UlNY^u%V*icfSeV|&5g8e2-Jp29p>^+`D=h;9F zI9lRxJWro;1QbwTH{R|Vp*gmJGK|9a?wq+m87{bD`>#pHS4O}!Y|jd^Tw)nOGx@+D z167`vjnQhKW4bo+*; z*SY`VCB}%^G@TnjLRfYQ9GdCJ`Vk(ZACHBI=JU;Z@yqM;edCGz7g!t5+@8A705NA_ zKxSYN?oVyBn9UqKxR_%EFF~`(eBln+MJ(6ddfuVo^}Mo?0u5%WJz&{eHVyThht+XZ zmM-WzT{ZB)fM0z@TFj zU2N}jU-FN?t^8N6^q7K?X>$byq1`Nae8zRR7#CGgm8R!SKZ8+-%rEvP(h1N7#VkwV zFnlMn1(v&zIaW!58n8Sv{B@h;Jw}fIF)zv}j2Hz9rT5DL`@_Yjfym01BbsBORp3y{ z46v%w>a&@U(Tom)ej_k2e>-d^>bo_7+urQ4mt=y*f67{hH%W76|uCyq$Z;)!r+#)u2D^@H&xA!aju$n<(D zX7}KgVvf-|2LBfmv8APX)jGVq>qq*&1-d0IExhK)&l)Z#o9iT}$W=}4QNgJ+>v z2^a34op4>T;Z`B@i2=f$7+$}w>ZY1Ma`2MFCT`kO z!!x5Yok)+)J?NL8ZjY@_kd7j$;X_3IyOBe?xAh&m8g09U%eMs?T2ELWM^rkI`T5ZCRG=gBHB+Tw-; z?LIAAR1QaStea{{=)m}Z>mj*phlUMAH$9>yFm)&nM#1}E0-_dT+%(`7`_C)Zn`sOQTy9Dl~Ew>Dm?;+SM;r10o|MZ ze!8D9nBSP|AS z^O(;rlC3s%^FYYtq5-%AP4E})AEsI>s0`R#w}M({IcxL5ju<<20--Ov<3o8vQoV|# zjG=wK2m@?!;w9MARiYC$Ezn7(ld9Jo0C3=X*z_+iwCw_iU5twbGRq(pG8)SMDSs(x zO&admU_gaZ5#<{Z}CLo;cNY%y{E3rw%y5c^`B zR+3qABRsF}6tcK8PI&P2Z&Tm^Ks`F$iYeU$4(=f9_xUm!ME+5Z9eR5$!}4Z zy@<9|lAEg=vi5a$k=-OrJsTHYCMWUj1IBkj1BYe!pall4(uE_{4d18UXWMIX5!0Zi z_<~Toc0~i$Axu|Df4ylDxebhwo`J`{fF59TsYs)5O|?4P@Z2du;Xe6Z-`P-$HP~6I zUPL?QRCd0#kOfq4!63feEn6^Z;0FnwTVt#JtU)Lgf;d2ik`r!o@^}1YOG-fQfBO>+ zjgIQudl|=1>2JV+Dj0_q&{UHZl?DOi>h+`mW2tgQoPr$R+=Ld>X&&6SDDNngk>2c9 zl>IlSxZFtPa;}%#Z!h2!>HgJ|i_{|%^RVAA|5pEi-6K;ydedlaO@{U&z>K5GqZYea z!B&wI!JK)}P>6sx`!xD2+7Cu&8%1wFe^K6OQ)b@91dol|s!M-qp2?6l7K6h^NE?&sNrhhwWsuY$*8 z!mc2EyKs8K_0!X0^V>6s*uo8*<^$DOPsb~RCC4Yd*?w~OVl*ceTC}rE=i9l4KzyC@ zenr;qhgPzd8%5c9mY1YC&1|J7qpz!wBG>| z$13{n598bH*U#(FZ@?M1oOTGC>!v&4kW&N0i(W7hm5QcaAmu%99&a&~!lgAI4TW{0 ziZdHeRW@nJmG>gjr6Y>@=ZoT-nmZz$G7XDC0$Vv0sSn}2_Sdx5YUXv znX@954$!PQqZQyhhOeLoaRY(_iL}`>Pf{!cLH;lyz=?#cK3JbK}ghT z=zjB!aBv zrb849n^Zly)oN-f$2t{CMZ&~Rw;mj4X+WUT3y4Pj{$kGx1E;tni{HExSH$!(156hQ zW{UkZp%yA`MCX<@xCGI6`lp(__pFSf1b>xAy?unPuJno`pQB~uM)hz!^Or*QL-R}c zX7je&AA3Go>S+zca@JP#6TwNH$_73tv)nk6ZLi5nqr9z&lXZm3jArWx@6&Xg(FKh$ z!%t4ORbq0hq%^kt*2zgbOBwa)HkPNooP61A@LX4Hm-FaI)gUZ~JReeb*!f?gypNxhhrqbF@VcAq9lkgZ@Tb7yu{e5CT; z{47_Lq$GajPfp3SVrJ;m8**KQDW1G4WbbQEyCFx#&5-PkgZPar-;MYEn?PeuQ7z@K zPmN6_P1{DFH8)SOR@QZE9m|=0mk6DNsQYo39RaI5tiiVuKW0{4acr>rv}^|F2f3@{ zQq3BMR+D4wBewBJ(<3<*M&V^>LM?T);T>rk3^yF3(DSYHzja)*YRWwNVKiMgg1PID zl-M;@%;_!_w^EDha%>%sy5;nE+JhtPWV$=hx=5uvG&ut=KCBtEMar7u7yW2Rx-nEA zTrnIh&rF3F@#zWxc>V{F0Tp~+Ekm?&=M)NcerdfB9)zTG(yym#rINY4F;55`@3~xC zdauSv9gm-C(6FyOlEIn6b`AE?dmV533W+;9eEoQ^pzqg5-V02XexDjeKRR(*U(?gW zWUW=}0XO%8_&2JD{qZU)n!wq>k1bE6S%6L>pNuc_xuD_CG)JpmWy5@v63%bi;GWR; zflJn(pyj3`R2@4mGjJ+y&z`CI;9zP^b`AbM&&x37rkVV>STJfFpshOd$EY(8$Qcw? zE3GdHG-@nrG64(oHO`jP-%JXV3XHQk5%s92+9i z-rV|M8L90~9v?I`iBeP-fbysG*XZ#%BnQ)C7NhZxBC5|$WbFgSSdu*Mb^#(&{^W33 zozC5(T!^QF;BCSayLWsmnLuKTmY_e3>_?CmOyhr#b2y+CiCh*Hnad%L9YOb-y5zD0 zjw|~#bhp|3dzY#F&(5fsUAvU5vbhK7pBJ6=RRbQE(rjG~Cow&uhPu64I~eMi&plnt zSNmmWzWDv_^p`ZoxRsp8}_Zr9?V`^!z~+&77?X* zPM!tnato@~xg{I+y;`CLS#t)l?>(9Xbsj`1B%+@}$BXE3`bn2@f5IP&9l`~!$zsLa zp;2e+eHunYVt(cNnFqSjZ%WZ7=3dbrD>l;Ty-6a(L+!S{5;_0*Ir+POcf`n)yCgdx z18QB}TIil!6saYPc~4tf{0%(HOYExw`JobiRDS5lqL3SVgokY4%&HU4BU9zsh(`|I zEHnl2uxnmGSY&R9>Yr&dtK!OHH|!j=qK#%6e>}F zUqsBeA*IkWaIuGNdBO|XxF0|%?-M4aygxX$naYS+qh~*6#q1uCnqO@UNK+ePJMo{)&PYXcElhh9gq6qnH!0VeBZK7mlag;m| zXJki*k_SM1i=UV01RPrUA2z<)WE9^IG=JJ`>Od5MPl6)wi?R$=0D->@o_)z`gwiNE z0T(4FX!moof-!i|eV%FZahgLz9Rbo}c@bZLx}FtCXD9>yiyH2Q^#2}LA?KMIbWPhK zE1d{#&pfeMInnRm1=z!BC)l>nQHwsRx;NQ_yfi@ilC*PDM*7JCK{`4g2H~5EceJYr`R!zqci~-Jt_kdF5 zv~=b;8Df;gUSKq7bj{nH`zG|UiCvwW5Z#p={Wuz*Vpo+;bD|H+bukaHB&f!T8W6oI z?qTGOf_xxqmkqlKhVT2VFI`TRF3$>t?>usvpxv0)b2s};diE)5c9vk~q{6V)X1Ob& z#-{HM*Buz2O4~DDcg6$UwnN2$qrKd6?-Lu)aS}_hX9M(S;%2@_D>&b_#!7L)Og*r$ zt4G8BY}J_NQ|z(QKm&DO12IIpJf5 zYtTMI*8-Xts3%vH`36?xrRJd1PM9KmRIc!w)l99KZ&!$(VMKu79H(bTW7}z^QLy9z zD3UOehq8C>neZA^Ghg(Gwml=fy8XLwi_Jk{QZ)0Fva!Kd3{g%BH!{ex-$iMTmax(# zf(Yq1`M`=GD)*jN+_S`yAazOKT)#>{ZgAkW-{Eq%AW)?pXB#S|_mID$6va|EhTd~! zKG4XJkHS$!JsA3qK=7#_#W6i*^mz@!K#%TD@(wKFTW(M+^QfHEHvCaF zC@@&13TlEypj7G_kT&a`wlClT5@q_?-fTY#VpP-)WuRj1*fb`uth4;?7m)dpIWCx; zx1X-Rce{HY`sgbvgmt~|_g!cR2($b00n@Bu2A*XnSWBDrMH(ktV~A=HG#kEtC+f!A zo>JFRu@ydSfW|`md3C&8pWg7r3!h9hw2zwsFB8eBSh`;5DwFVxjzh z$F@+efN9J&a8B>&?)=rJ6L65yf2b#=)!oP06YXUxBzufk zh&V;+UNvpMSthU8=j)y0qDeLY+d7l=aW0w%DJepWV7#{GnhYq z>J{Yb=soYDcYD3_wOJEccY%<-VS#}D62?yET{0JgAa|JKvxlzAEDS^aPVC}yB}w#T z?E>7HzzCw{3R}XVkQL@d=DKC$y9$RgT2=R?yr=#Sd@^)4d^&AN1pIFwdx6r&xhFV3EQ zkGxEfXnXh--Z}j?LvZ&t{xZyq_|R*1(xEQ9OwZshJBWpb&9MAM2`jP0^u>nX_~mRy zLX^&FNp3ER3IXf?X2?|HG5w2^Wd^3g;-7oIabLyrvr;F|tDo8r>mub^2}%CbGIyB2Nf!! zsczras3{Z-v?O>P6xrivx4l)8dQ~eZ??1t<@}MQyY6haLuN{C*^*c$zGy>`(qSc9!x>!TRf1It6rti z=5{i5spRXqmE|UHlOBwCrF49TcJ}9HpT%9}VEmuo3fcdNO`*4$LR$KC4zR}2BNB1Y zyy)*S?vSk$+jJ*VdEQ)ZB$3n^3Fl!!_gmhulm5m;WRbYK)qTI{=Bps|1#*Q!Bc7vw zNX$;h*wC5`b)&J*lGIP1AP~n}iz1b&j#~lRjJ37=0>I6KMsc4{#+V+W)@H$D-k(XJc}Jyt@eC@G+F1BWpJesNuG30HU8hWoUtW1@9_*Ch#Opv1yuvsT4N^V^@B<~{HH_>_x& z${AICah)p}4P5g3pYf{IPC~xAKKAGi*#!~?aIH2VdZG_Zf2z#_ zu5-^`x?xKw+0TiUZazz#r;CLiU_Q z9v%UI%HXxd+xFG3q|;e)S)%?{n1nqZn$oAbbh4o>b*{f>l!EPjlzM*`AI846#XEgE zbTP)&@d%5Ql=cFh%e^>47DU<}aOV7s<$7=pXv-^5k;8)v@vLUVlF!bJ8%nA;J1(ewFVWI$?_frbN-5Kma0$NV_*&ebe!bK3a<#d^8NH5bVHLBtz zZm!VV^5hKfb)2bl6d@UJbTbzRV&aESFL@}H-6K^9iUn8`O24H!b>8hFrQSh#nJ8%S zBp7hI2=}hnJ98c|;B*9?Y+7RWgMe=~F}F1iz3s7BC?+Lk5V6l9bt@)~i~(~_L^OO+ zELTfvS~cCdIu~omo{drVnm>u4(QfbVEX^#A3%V=daT^e$tYYVlnfInIq+_qh`B*K) zut+tKDUjHiMO>%Z1H2H{S-WWEeuUM5Oe8z4iQNIBGzRAWOW4N4Yu6u=qUuv~)Z3$9lZwz_-i|lP5Kjr{ z#j=nO80>$)y_xvT^0E z^02O?hILmfv=m_*M1VN~%ts(%c!wQg01rTGB*eJRljJUqgv&|UvHo3(Jhb8#>Im$~ z0$mEkt`^vFu<1}>`J26_$YEo8@ z5Y!(rVJ^eIBe;Gs8C;uT;ULn!@^L#k5S(DG9J^N&Sk@I*#A9wuPN^npv|^7;D3-k| zaw8#wl9aDbR+;m8tq(yDACeK_x>u`f<4GM7uJI?~60#-}BHB+uXmiSwX5fh#2#B7A zZdj*D+huW27F8R

`*bGNZmIB42u#h7;98f=hUR4mKd9_1<7Em999R&LaK< z=#0+6)>6ly3?>V5dx1FmeGn?Dg|}jlIR^ zbm#8%BU)~%4qf3UEK4+lxx}88P)j)&`Ohc(dM`NQN+Hz{5Ynz!>gek+V6GtZ9vrDY zhtzy0l68k^B>U$oSZGB{GEpP1Cyd>ui+#K&6Yq%TC(W2avq(tUxHS(Zs|t8TC4g_$ zIk}Y9L-K*tHLzEj1~C$5K7z-QHY%TNn)>JZ`(!$OSK8|mC<`J-XxU2u= z#QKy?MCJjr0DbZjhlNTSy2SH>eZEoGYP22GD#whChwMe!&7AE5IFUS9*o$6WXQ<(hz1Q#g(zh`>cj{eZex97SZ@B zM_!F{4*H8F)Vh6-A?{LBR}^YHuol4C28Ts_fF7C>xv-jqEmH7Khs27>Ky6Gnh?-iK zTDTz^+!@x+c*FlZNB4*1h9=Ro#KO3l0ANeW0f3P8tCRw&JH!$oJo+9;)dR3ij^c^B z-aOs}2uwH`>;%798Aokf0l1d}JHpEY(DFacIq$%>$^d|$6L3p-ab&fMg`8-tB6jaS5)X-&Q-Vg z?Nj%P=p*>MidZpI($O0ZdJLSlEL~rr{kdn)?bG4Rcca97jYK#j|4}9Vme=o27C}yv zg8}rvOt%s0<9-_wcdBhS*v6n~Ci;X@1c)9?Vq5;PVa_J14%x`~-T5)^R8$_OUFZI$ zFV|}rZPssJe8`@}kfuF2(%$UfU}E`S)$>+IA?tNQ_g6SVhotEo2Ef6h>oet`=GVeh za}zW;$i3wsDKuOZT#D~T5duo!0%kdM*Px=IC3YZ(`i`{+Wmo&}d;K5DkU*W%4T7uT zL~QnjFZX8Z`>gqa{}2!r#YD)U@cTwkZd8D?jP7&d-%gipHQK0uKfFt%dzg9p@mV@I zHu&jVRHS%7dFVz-P7_qO1D%IZ+14C(1RnU?-a)K$Lh5`J)cL z-wEz`CC-d)uoJTvxZ~e?^>Crg{^Vf${_}KhoPX~C(gL|cX7b>)CZHIX^h6s0uv2et z#FqiSvLNhvcFohLdEdQqIn93msy)EuP8FwPf;0SDHD`I)pA%A2ucJ=WX#T>~)FmhL z&Ciu}&jQ~4o*#a&;6*4D$@uly>Lu6ZD&M(zR7Ch^|7ga$>N12|0qj3S^TV1#^L=^G z538BKE8RdX`1k68oU> zOSx7tNgyB|BHaiYoTmjt1vx`!8{M*j{|7Pgz&p>I(xH%;6~KNQB(MSDRJ9yE zMFI$hHB)`hW5?_{dy2EaScACNIu?zYKTAH>&jo-*DY;FXe$^cMi_r;KDG8?{!T@@# zMQ7g=X3%;7lRgC9pY%7thcVcqO>^nFwd|`tB@62N>M!;|?f_YEd(CeCil;!`V+Stl z53J@dm-YcvMuG~f$)|jiF;8e35nfV5vir~K4gnGwjhtIpS#vh`x-H+th6E!cwlHV7 z_FM5O9$*Wem<35Y%e{`^g3;}-niI)rQYm-ZD*T8^bmBYfe#4p)*h$A5g3~pCTMZ{8s)ZBQe zJ`yL^_IJ<+9&J(XskAq!Bwh2H`wWXPP?$O23!~N@$|R)CwqP%MDPr|F|-AH z-F;;R-k0bzOgT%w3n6~9Tt6ES{_DV-&pE?U0=T-L&{%M1_5WwHPD;SN8c)~B zRjW*1*JR0WI_1iB5%DsGtKT;Ay$)LT$GZ1|ojzot%3h!dCMU6Hd=6Z+Uea47nKqz( zc%seIG#+&F+@hL_0pq1kDM~V8x7ZRa(`K75K2?$=Ij5-`yc;?`pFHOdC-yuZ6s2GI z<~*E`n0ly_3~zLr94bbmH+kRS;;gPkOe%>`N#UfAJBMEI&m%ofB85o=&2XX!_CQCg zup^Oy;_h?t_iKb2xYqnSl^tD~>}7Wb_^(mS7b>bFp}kG)h03%%2Q|pf-@y}YR&jMn ziYfK#WGgCf@zb~f=LALvx(5TV=6`u`E{G8tLSj0ln)T@FE`>g$ z9c*|#3S_vMWGDx03Qa1VP>-EkU17S@wwV!oWo#f?0fDP9odsGIuv3{-d#l<|(?-y~ zj}G%cYDZ{XzXSEWMiToF4Pji|twj>A14K@tg7}d%&L$-rJf*`)43QXkXiem5ZO1ev zAfDlt&Aaa|m8@?iaz|)-rXMesh|a1uXGw6qiNR8;w||!Nfmp7a+pWz0-Z|vD;~ex4 zTl2T_dZtW|k#5A{6AxfmKVV$h-~ZyLHya!|eAXljLn!Tn60=n^y1k-`Q!ht6W-P09 zd!b4X3*;SaMRYLPv*SKqlVi>`D)>pi3yOgVyooxmTRqg@O5KN|rKZMzB3;~2M$=g& z5oMz68YbiocU<;uX=lps0ℑ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 Date: Wed, 8 Jan 2014 18:18:21 +0800 Subject: [PATCH 03/87] Update README. --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a6f46e8..87ba15d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ # RSDayFlow - + + + + +
> [RSDayFlow](https://github.com/ruslanskorb/RSDayFlow) is a slim fork of [DayFlow](https://github.com/evadne/DayFlow) with updates and extensions: From c9a63511af5d933cdc1aa8b1b970baa7bca1d89c Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Fri, 10 Jan 2014 01:25:58 +0800 Subject: [PATCH 04/87] Add LICENSE. --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..484e78d --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2013 Evadne Wu, http://radi.ws/ +Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. From 48180cda05fd32be6fbd9427ba7e5e314ff473dd Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Fri, 10 Jan 2014 01:26:29 +0800 Subject: [PATCH 05/87] Update podspec. --- RSDayFlow.podspec | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/RSDayFlow.podspec b/RSDayFlow.podspec index 93f2cf7..2d8c06c 100644 --- a/RSDayFlow.podspec +++ b/RSDayFlow.podspec @@ -2,13 +2,12 @@ Pod::Spec.new do |s| s.name = 'RSDayFlow' s.version = '0.1.0' s.summary = 'Scrollable iOS 7 Date Picker.' - s.homepage = 'http://github.com/ruslanskorb/RSDayFlow' - s.license = 'MIT' + s.homepage = 'https://github.com/ruslanskorb/RSDayFlow' + s.license = { :type => 'MIT', :file => 'LICENSE' } s.authors = { 'Evadne Wu' => 'ev@radi.ws', 'Ruslan Skorb' => 'ruslan.skorb@gmail.com' } - s.source = { :git => 'http://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.1.0' } + s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.1.0' } s.platform = :ios, '7.0' s.source_files = 'RSDayFlow', 'RSDayFlow/**/*.{h,m}' - s.exclude_files = 'RSDayFlow/Exclude' s.frameworks = 'QuartzCore', 'UIKit' s.requires_arc = true end From 5fff99a7f1cbe544f3930dad13ab45a47a652d23 Mon Sep 17 00:00:00 2001 From: Jerrod Putman Date: Tue, 14 Jan 2014 12:09:01 -0800 Subject: [PATCH 06/87] Fixed content offset when shifting dates The content offset was not being set correctly after shifting dates for infinite scrolling. This was due to fromSectionOrigin not actually pointing to the first item in the section. --- DayFlow/DFDatePickerView.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/DayFlow/DFDatePickerView.m b/DayFlow/DFDatePickerView.m index 0bc2f42..64cd3b3 100644 --- a/DayFlow/DFDatePickerView.m +++ b/DayFlow/DFDatePickerView.m @@ -183,7 +183,8 @@ - (void) shiftDatesByComponents:(NSDateComponents *)components { NSIndexPath *fromIndexPath = [cv indexPathForCell:((UICollectionViewCell *)visibleCells[0]) ]; NSInteger fromSection = fromIndexPath.section; NSDate *fromSectionOfDate = [self dateForFirstDayInSection:fromSection]; - CGPoint fromSectionOrigin = [self convertPoint:[cvLayout layoutAttributesForItemAtIndexPath:fromIndexPath].frame.origin fromView:cv]; + UICollectionViewLayoutAttributes *fromAttrs = [cvLayout layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:fromSection]]; + CGPoint fromSectionOrigin = [self convertPoint:fromAttrs.frame.origin fromView:cv]; _fromDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:components toDate:[self dateFromPickerDate:self.fromDate] options:0]]; _toDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:components toDate:[self dateFromPickerDate:self.toDate] options:0]]; From 2988f6e8297ee70fa29a78c8d5165065b3d43420 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 21 Jan 2014 13:14:20 +0300 Subject: [PATCH 07/87] [Fix] zOrder of the views in RSDFDatePickerDayCell. --- RSDayFlow/RSDFDatePickerDayCell.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RSDayFlow/RSDFDatePickerDayCell.m b/RSDayFlow/RSDFDatePickerDayCell.m index 5d9cf6a..d637668 100644 --- a/RSDayFlow/RSDFDatePickerDayCell.m +++ b/RSDayFlow/RSDFDatePickerDayCell.m @@ -41,11 +41,11 @@ - (id)initWithCoder:(NSCoder *)aDecoder - (void)commonInitializer { self.backgroundColor = [UIColor whiteColor]; - self.dividerTopImageView.hidden = NO; - self.dateLabel.hidden = NO; self.todayImageView.hidden = YES; self.overlayImageView.hidden = YES; self.markerImageView.hidden = YES; + self.dividerTopImageView.hidden = NO; + self.dateLabel.hidden = NO; } - (void)setDate:(RSDFDatePickerDate)date From e9d3edced016a74a5620a3075cbb70ef9f14ed54 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Thu, 20 Feb 2014 14:18:38 +0300 Subject: [PATCH 08/87] [Update] Font size in the label of the current day (RSDFDatePickerDayCell). --- RSDayFlow/RSDFDatePickerDayCell.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RSDayFlow/RSDFDatePickerDayCell.m b/RSDayFlow/RSDFDatePickerDayCell.m index d637668..4abe5c9 100644 --- a/RSDayFlow/RSDFDatePickerDayCell.m +++ b/RSDayFlow/RSDFDatePickerDayCell.m @@ -124,7 +124,7 @@ - (void)setToday:(BOOL)today if (!_today) { self.dateLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:18.0f]; } else { - self.dateLabel.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:18.0f]; + self.dateLabel.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:19.0f]; self.dateLabel.textColor = [UIColor whiteColor]; } self.todayImageView.hidden = !_today; From 00b83c70ff8710bec37d31bfcd4f831bf49de557 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Thu, 20 Feb 2014 14:27:20 +0300 Subject: [PATCH 09/87] [Update] README. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 87ba15d..bb3498c 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ > [RSDayFlow](https://github.com/ruslanskorb/RSDayFlow) is a slim fork of [DayFlow](https://github.com/evadne/DayFlow) with updates and extensions: > * Possibility to mark the date -* 2 colours of marks that can be used in the Task Manager (gray color - days with uncompleted tasks, green color - days with completed tasks) +* 2 colors of marks that can be used in the Task Manager (gray color - days with uncompleted tasks, green color - days with completed tasks) * Design like iOS 7 * Some other updates From 432a05439249d472c067886cf8390e535f311b4c Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Thu, 20 Feb 2014 15:06:32 +0300 Subject: [PATCH 10/87] [Update] Screenshot.png --- Screenshot.png | Bin 50336 -> 50620 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Screenshot.png b/Screenshot.png index 61bad73b6adc42fbaca391a1ba4f133618e51cc2..6a82c95e047631804df1ddb7dab39790d4262839 100644 GIT binary patch literal 50620 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 DxN}>; literal 50336 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 Date: Thu, 20 Feb 2014 15:11:47 +0300 Subject: [PATCH 11/87] Version bump (0.1.1) --- RSDayFlow.podspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RSDayFlow.podspec b/RSDayFlow.podspec index 2d8c06c..fc66fd8 100644 --- a/RSDayFlow.podspec +++ b/RSDayFlow.podspec @@ -1,11 +1,11 @@ Pod::Spec.new do |s| s.name = 'RSDayFlow' - s.version = '0.1.0' + s.version = '0.1.1' s.summary = 'Scrollable iOS 7 Date Picker.' s.homepage = 'https://github.com/ruslanskorb/RSDayFlow' s.license = { :type => 'MIT', :file => 'LICENSE' } s.authors = { 'Evadne Wu' => 'ev@radi.ws', 'Ruslan Skorb' => 'ruslan.skorb@gmail.com' } - s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.1.0' } + s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.1.1' } s.platform = :ios, '7.0' s.source_files = 'RSDayFlow', 'RSDayFlow/**/*.{h,m}' s.frameworks = 'QuartzCore', 'UIKit' From 988f37433f7bee59b3ff84acfd2dfb971cd31c4e Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 18 Mar 2014 21:58:01 +0300 Subject: [PATCH 12/87] Version bump (0.1.2) --- RSDayFlow.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RSDayFlow.podspec b/RSDayFlow.podspec index fc66fd8..1ce119d 100644 --- a/RSDayFlow.podspec +++ b/RSDayFlow.podspec @@ -5,7 +5,7 @@ Pod::Spec.new do |s| s.homepage = 'https://github.com/ruslanskorb/RSDayFlow' s.license = { :type => 'MIT', :file => 'LICENSE' } s.authors = { 'Evadne Wu' => 'ev@radi.ws', 'Ruslan Skorb' => 'ruslan.skorb@gmail.com' } - s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.1.1' } + s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.1.2' } s.platform = :ios, '7.0' s.source_files = 'RSDayFlow', 'RSDayFlow/**/*.{h,m}' s.frameworks = 'QuartzCore', 'UIKit' From 5ece163e426d92bedd67c833907083e088734ac6 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 18 Mar 2014 22:25:11 +0300 Subject: [PATCH 13/87] [Fix] Version bump (0.1.2) --- RSDayFlow.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RSDayFlow.podspec b/RSDayFlow.podspec index 1ce119d..38426fb 100644 --- a/RSDayFlow.podspec +++ b/RSDayFlow.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'RSDayFlow' - s.version = '0.1.1' + s.version = '0.1.2' s.summary = 'Scrollable iOS 7 Date Picker.' s.homepage = 'https://github.com/ruslanskorb/RSDayFlow' s.license = { :type => 'MIT', :file => 'LICENSE' } From c0016899e0db5ff1242b9e539573d96289326df8 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Sun, 13 Jul 2014 12:53:51 +0300 Subject: [PATCH 14/87] [Add] Abbreviations of the days of the week. --- RSDayFlow.xcodeproj/project.pbxproj | 6 ++ RSDayFlow/RSDFDatePickerDaysOfWeekView.h | 5 ++ RSDayFlow/RSDFDatePickerDaysOfWeekView.m | 102 +++++++++++++++++++++++ RSDayFlow/RSDFDatePickerView.m | 45 +++++++++- 4 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 RSDayFlow/RSDFDatePickerDaysOfWeekView.h create mode 100644 RSDayFlow/RSDFDatePickerDaysOfWeekView.m diff --git a/RSDayFlow.xcodeproj/project.pbxproj b/RSDayFlow.xcodeproj/project.pbxproj index da9ec87..d0587b0 100644 --- a/RSDayFlow.xcodeproj/project.pbxproj +++ b/RSDayFlow.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ B8726567187C12BB000C1895 /* RSDFDatePickerMonthHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = B872655F187C12BB000C1895 /* RSDFDatePickerMonthHeader.m */; }; B8726568187C12BB000C1895 /* RSDFDatePickerView.m in Sources */ = {isa = PBXBuildFile; fileRef = B8726561187C12BB000C1895 /* RSDFDatePickerView.m */; }; B88EB3C5187BB6F100D8E2B8 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B88EB3C4187BB6F100D8E2B8 /* QuartzCore.framework */; }; + B8E5801F19728B6000D766B3 /* RSDFDatePickerDaysOfWeekView.m in Sources */ = {isa = PBXBuildFile; fileRef = B8E5801E19728B6000D766B3 /* RSDFDatePickerDaysOfWeekView.m */; }; FF2A69CE172D2C07005A1A21 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FF2A69CD172D2C07005A1A21 /* Foundation.framework */; }; FFB686B3172E8A970027ADF2 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FFB686B2172E8A970027ADF2 /* UIKit.framework */; }; /* End PBXBuildFile section */ @@ -43,6 +44,8 @@ B8726561187C12BB000C1895 /* RSDFDatePickerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RSDFDatePickerView.m; path = RSDayFlow/RSDFDatePickerView.m; sourceTree = ""; }; B872656A187C12CD000C1895 /* RSDayFlow-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "RSDayFlow-Prefix.pch"; path = "RSDayFlow/RSDayFlow-Prefix.pch"; sourceTree = SOURCE_ROOT; }; B88EB3C4187BB6F100D8E2B8 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + B8E5801D19728B6000D766B3 /* RSDFDatePickerDaysOfWeekView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RSDFDatePickerDaysOfWeekView.h; path = RSDayFlow/RSDFDatePickerDaysOfWeekView.h; sourceTree = ""; }; + B8E5801E19728B6000D766B3 /* RSDFDatePickerDaysOfWeekView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RSDFDatePickerDaysOfWeekView.m; path = RSDayFlow/RSDFDatePickerDaysOfWeekView.m; sourceTree = ""; }; FF2A69CA172D2C07005A1A21 /* libRSDayFlow.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRSDayFlow.a; sourceTree = BUILT_PRODUCTS_DIR; }; FF2A69CD172D2C07005A1A21 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; FFB686B2172E8A970027ADF2 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; @@ -74,6 +77,8 @@ B872655D187C12BB000C1895 /* RSDFDatePickerDayCell.m */, B872655E187C12BB000C1895 /* RSDFDatePickerMonthHeader.h */, B872655F187C12BB000C1895 /* RSDFDatePickerMonthHeader.m */, + B8E5801D19728B6000D766B3 /* RSDFDatePickerDaysOfWeekView.h */, + B8E5801E19728B6000D766B3 /* RSDFDatePickerDaysOfWeekView.m */, B8726557187C12BB000C1895 /* NSCalendar+RSDFAdditions.h */, B8726558187C12BB000C1895 /* NSCalendar+RSDFAdditions.m */, ); @@ -172,6 +177,7 @@ B8726564187C12BB000C1895 /* NSCalendar+RSDFAdditions.m in Sources */, B8726566187C12BB000C1895 /* RSDFDatePickerDayCell.m in Sources */, B8726565187C12BB000C1895 /* RSDFDatePickerCollectionView.m in Sources */, + B8E5801F19728B6000D766B3 /* RSDFDatePickerDaysOfWeekView.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/RSDayFlow/RSDFDatePickerDaysOfWeekView.h b/RSDayFlow/RSDFDatePickerDaysOfWeekView.h new file mode 100644 index 0000000..8d17150 --- /dev/null +++ b/RSDayFlow/RSDFDatePickerDaysOfWeekView.h @@ -0,0 +1,5 @@ +#import + +@interface RSDFDatePickerDaysOfWeekView : UIView + +@end diff --git a/RSDayFlow/RSDFDatePickerDaysOfWeekView.m b/RSDayFlow/RSDFDatePickerDaysOfWeekView.m new file mode 100644 index 0000000..a7d9b37 --- /dev/null +++ b/RSDayFlow/RSDFDatePickerDaysOfWeekView.m @@ -0,0 +1,102 @@ +#import "RSDFDatePickerDaysOfWeekView.h" + +@implementation RSDFDatePickerDaysOfWeekView + +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + [self commonInitializer]; + } + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder +{ + self = [super initWithCoder:aDecoder]; + if (self) { + [self commonInitializer]; + } + return self; +} + +- (void)commonInitializer +{ + self.backgroundColor = [UIColor colorWithRed:248.0/255 green:248.0/255 blue:248.0/255 alpha:1.0]; + + UIFont *font = [UIFont fontWithName:@"HelveticaNeue-Light" size:10.0]; + UIColor *dayColor = [UIColor blackColor]; + UIColor *dayOffColor = [UIColor colorWithRed:150.0/255 green:150.0/255 blue:150.0/255 alpha:1.0]; + CGFloat yCenter = CGRectGetHeight(self.bounds) / 2; + + // Hard key these things. + // 44 * 7 + 2 * 6 = 320; from collectionViewLayout of RSDFDatePickerView + + CGFloat dayItemWidth = 44.0f; + CGFloat minimumInteritemSpacing = 2.0f; + + UILabel *sunday = [[UILabel alloc] init]; + sunday.font = font; + sunday.text = @"S"; + sunday.textColor = dayOffColor; + [sunday sizeToFit]; + CGFloat xCenter = dayItemWidth / 2; + sunday.center = CGPointMake(xCenter, yCenter); + [self addSubview:sunday]; + + UILabel *monday = [[UILabel alloc] init]; + monday.font = font; + monday.text = @"M"; + monday.textColor = dayColor; + [monday sizeToFit]; + xCenter += (dayItemWidth + minimumInteritemSpacing); + monday.center = CGPointMake(xCenter, yCenter); + [self addSubview:monday]; + + UILabel *tuesday = [[UILabel alloc] init]; + tuesday.font = font; + tuesday.text = @"T"; + tuesday.textColor = dayColor; + [tuesday sizeToFit]; + xCenter += (dayItemWidth + minimumInteritemSpacing); + tuesday.center = CGPointMake(xCenter, yCenter); + [self addSubview:tuesday]; + + UILabel *wednesday = [[UILabel alloc] init]; + wednesday.font = font; + wednesday.text = @"W"; + wednesday.textColor = dayColor; + [wednesday sizeToFit]; + xCenter += (dayItemWidth + minimumInteritemSpacing); + wednesday.center = CGPointMake(xCenter, yCenter); + [self addSubview:wednesday]; + + UILabel *thursday = [[UILabel alloc] init]; + thursday.font = font; + thursday.text = @"T"; + thursday.textColor = dayColor; + [thursday sizeToFit]; + xCenter += (dayItemWidth + minimumInteritemSpacing); + thursday.center = CGPointMake(xCenter, yCenter); + [self addSubview:thursday]; + + UILabel *friday = [[UILabel alloc] init]; + friday.font = font; + friday.text = @"F"; + friday.textColor = dayColor; + [friday sizeToFit]; + xCenter += (dayItemWidth + minimumInteritemSpacing); + friday.center = CGPointMake(xCenter, yCenter); + [self addSubview:friday]; + + UILabel *saturday = [[UILabel alloc] init]; + saturday.font = font; + saturday.text = @"S"; + saturday.textColor = dayOffColor; + [saturday sizeToFit]; + xCenter += (dayItemWidth + minimumInteritemSpacing); + saturday.center = CGPointMake(xCenter, yCenter); + [self addSubview:saturday]; +} + +@end diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index 354ab1f..0645801 100644 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -4,16 +4,20 @@ #import "RSDFDatePickerDayCell.h" #import "RSDFDatePickerMonthHeader.h" #import "RSDFDatePickerView.h" +#import "RSDFDatePickerDaysOfWeekView.h" #import "NSCalendar+RSDFAdditions.h" static NSString * const DFDatePickerViewCellIdentifier = @"dateCell"; static NSString * const DFDatePickerViewMonthHeaderIdentifier = @"monthHeader"; +static const CGFloat DFDatePickerViewDaysOfWeekViewWidth = 320.0f; +static const CGFloat DFDatePickerViewDaysOfWeekViewHeight = 22.0f; @interface RSDFDatePickerView () @property (nonatomic, readonly, strong) NSCalendar *calendar; @property (nonatomic, readonly, assign) RSDFDatePickerDate fromDate; @property (nonatomic, readonly, assign) RSDFDatePickerDate toDate; +@property (nonatomic, readonly, strong) RSDFDatePickerDaysOfWeekView *daysOfWeekView; @property (nonatomic, readonly, strong) UICollectionView *collectionView; @property (nonatomic, readonly, strong) UICollectionViewFlowLayout *collectionViewLayout; @property (nonatomic, readonly, strong) NSDate *today; @@ -25,6 +29,7 @@ @implementation RSDFDatePickerView @synthesize calendar = _calendar; @synthesize fromDate = _fromDate; @synthesize toDate = _toDate; +@synthesize daysOfWeekView = _daysOfWeekView; @synthesize collectionView = _collectionView; @synthesize collectionViewLayout = _collectionViewLayout; @@ -74,7 +79,12 @@ - (void)layoutSubviews { [super layoutSubviews]; - self.collectionView.frame = self.bounds; + self.daysOfWeekView.frame = [self daysOfWeekViewFrame]; + if (!self.daysOfWeekView.superview) { + [self addSubview:self.daysOfWeekView]; + } + + self.collectionView.frame = [self collectionViewFrame]; if (!self.collectionView.superview) { if (self.collectionView.numberOfSections > 0) { RSDFDatePickerDate todayPickerDate = [self pickerDateFromDate:_today]; @@ -98,15 +108,46 @@ - (void)willMoveToSuperview:(UIView *)newSuperview if (newSuperview && !_collectionView) { // do some initialization! + RSDFDatePickerDaysOfWeekView *v = self.daysOfWeekView; + [v layoutIfNeeded]; + UICollectionView *cv = self.collectionView; [cv layoutIfNeeded]; } } +- (CGRect)daysOfWeekViewFrame +{ + CGRect namesOfDaysViewFrame = self.bounds; + namesOfDaysViewFrame.origin.x = (CGRectGetWidth(self.bounds) - DFDatePickerViewDaysOfWeekViewWidth) / 2; + namesOfDaysViewFrame.size.width = DFDatePickerViewDaysOfWeekViewWidth; + namesOfDaysViewFrame.size.height = DFDatePickerViewDaysOfWeekViewHeight; + return namesOfDaysViewFrame; +} + +- (UIView *)daysOfWeekView +{ + if (!_daysOfWeekView) { + _daysOfWeekView = [[RSDFDatePickerDaysOfWeekView alloc] initWithFrame:[self daysOfWeekViewFrame]]; + } + + return _daysOfWeekView; +} + +- (CGRect)collectionViewFrame +{ + CGRect collectionViewFrame = self.bounds; + collectionViewFrame.origin.x = (CGRectGetWidth(self.bounds) - DFDatePickerViewDaysOfWeekViewWidth) / 2; + collectionViewFrame.origin.y += DFDatePickerViewDaysOfWeekViewHeight; + collectionViewFrame.size.width = DFDatePickerViewDaysOfWeekViewWidth; + collectionViewFrame.size.height -= DFDatePickerViewDaysOfWeekViewHeight; + return collectionViewFrame; +} + - (UICollectionView *)collectionView { if (!_collectionView) { - _collectionView = [[RSDFDatePickerCollectionView alloc] initWithFrame:self.bounds collectionViewLayout:self.collectionViewLayout]; + _collectionView = [[RSDFDatePickerCollectionView alloc] initWithFrame:[self collectionViewFrame] collectionViewLayout:self.collectionViewLayout]; _collectionView.backgroundColor = [UIColor whiteColor]; _collectionView.dataSource = self; _collectionView.delegate = self; From 9dc5e0183abdd736b8284224ec3284e6035ceac4 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Sun, 13 Jul 2014 12:56:37 +0300 Subject: [PATCH 15/87] [Update] Screenshot.png --- Screenshot.png | Bin 50620 -> 52982 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Screenshot.png b/Screenshot.png index 6a82c95e047631804df1ddb7dab39790d4262839..71919d970b656082ca22d78093ed210330cedf2e 100644 GIT binary patch literal 52982 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 literal 50620 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 DxN}>; From a6038653e0f66aa56191c485e4e82bcb1f2c7ed8 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Sun, 13 Jul 2014 12:57:14 +0300 Subject: [PATCH 16/87] Version bump (0.2.0) --- RSDayFlow.podspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RSDayFlow.podspec b/RSDayFlow.podspec index 38426fb..d00b8f0 100644 --- a/RSDayFlow.podspec +++ b/RSDayFlow.podspec @@ -1,11 +1,11 @@ Pod::Spec.new do |s| s.name = 'RSDayFlow' - s.version = '0.1.2' + s.version = '0.2.0' s.summary = 'Scrollable iOS 7 Date Picker.' s.homepage = 'https://github.com/ruslanskorb/RSDayFlow' s.license = { :type => 'MIT', :file => 'LICENSE' } s.authors = { 'Evadne Wu' => 'ev@radi.ws', 'Ruslan Skorb' => 'ruslan.skorb@gmail.com' } - s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.1.2' } + s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.2.0' } s.platform = :ios, '7.0' s.source_files = 'RSDayFlow', 'RSDayFlow/**/*.{h,m}' s.frameworks = 'QuartzCore', 'UIKit' From b6b98ba7068698930de392771b46416e2c8aba2a Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Thu, 7 Aug 2014 22:35:00 +0300 Subject: [PATCH 17/87] [Update] Screenshot. --- Screenshot.png | Bin 52982 -> 66738 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Screenshot.png b/Screenshot.png index 71919d970b656082ca22d78093ed210330cedf2e..d2dce9817656c530b7be48291040b325462a7cb0 100644 GIT binary patch literal 66738 zcmXtgWmJ^U`?oZLl$7++jWn)wx6)G5onIEDySqVwrAxXSk!Ar|N?Lkh>F#`%-~T*s zc){V^_uSXaT=S_RO6`+84i-7qt5>gZ6cuDNUcExHe)S6Z8WSDy8y&$=%~!7guM}k@ zwLFauzG9dVY2O88Sxo!nld=Zq<>?}+*U@{pi;9lEUZD}iW}^!Ruwfxbo4n`u5#L{s z+>N|g@nOj?N$%=+KE4)o_Hg%TX2?)=PdUy8CNF0QIs2b)3#~q^d{GIepzp>E6-6dw zQf)me_kSF6Sm=~>Snc{+R9YNEQl%eV`A3C-n2c2=iGYrcZptM`kd`fM%!-gH<>620 zv+UY;OoDu|!hplvX={S3)n5W`TU8kdfQ% zab|T-_#v+AROqT_b&u~M#@v*W8ujZ;%c4*+HN)azoiPYhFH+-okN0pNHAIuE_uFP} zc`^gMk83aXmL8u7HT(??$ZmhzarXLPL6cJ4-;juiC~{;(N!`eZD?lQen3y=3Uor>jGSEfe1mnue237zcwacKA2SOe+@v%v91Q=HK`2WKjNlB4Zgm{t58ay;5={IbXI9SrhbkL> zv0LAWmY4d4e+B1G88mz^k@zN>m(sA~dNNA+T-C%O zzbkijW8hWq z=t#!iIGq}M3FF7=N0s}wb}8@sov)%z*|QrH`+a`K*PA{|^3KA}_jU>Ejt?`yveP~*op$9+S#T2$EPk2X2yrZ>Pwvn*aJcB@6*=f8pgFfv2JA1 z^cIY8JhOB>atPy1j{&lOYG~mK`3aNS<>TpDbhLJQ^awHW))qTQQaWeY5SB;h?RJ)I z(7(~kI#q>~^U&9X8aquTVZcFO%SPaxldIc>t;`^k&6nudQ(=X9QXspk^5Z^kqY(BY zX^{PEwQ-GE>OPv&4jTF6V+k=$7)c~!wFh*@>qBd9uK1hI^>zEH`-Yquo?irV-<*C* zDE8+P>rqHuTLJB&fD=zmp?inxoBQBj1dT#(FNNd|J^zYm-`miPc+VO7m5`8ER9a#1 zY&y$Am7waG9du5Yz$YE@503_)a%dYI(q{2S=|{ekP;q{|S@AgzixpB(NIpMV@6$}y zOfHqr7@H%wl?zUsK}J&0O=?IlB9^QO!?hH!e|CTVw5zXQrK|_hS6-kvwW;dc!w<^* z={?(er5mI`G9&7gw`8AiXs^=6Vd1=aE#H1*vEhH-eobK$;0-@I3@VYoIa<=WZe2WV zQbrHzBtZ4%@aX;aJKp=<4V{c=p+v&p$k0rHcdC-VU_V(CgKJ05d6#smDpH z^W`Mqd*j9a0hs7aZbY#JIGGQPf@|8xi%>QkE-ehLBq4GSgCeLECz zT@|08P`q3}_AD3g@JJ~YBiq4&k1Kr}l0!^XCFq;VTB!AP=euXk!ftyK6ZD*Bb*epbaI+1yVyZ#E) zu%hdOe?4+ptEc^LTmiNkk{`>QE9xmP+MUF92XSO z?b<0AQJXzKJ({g{`4!aGP9RnBZZuNLh%_=XF}YjCE{J@CB+`1#wBa@_H?Kf$SEZk_ zsjZ`Y0CaR`ipY%Qd3K~1sR`!OC91OfvsJQiXf`8RVUVY?(m@TM=hvQNV&b&M-+KDv zBai4NJ`FjpW*tc_>aAdsI&W-f$N_Ra-*v7? z<(24dDyP0+=GvQ}Tz{(W^9SZi@1f-MphxkA z#!Yu-%CE=;eumfIz73qo+Eg=a{2Qm3w53t1hS{|kH9C_)&vjN8w$OZ5R}zZ5@QTDK zwS11e`*;0am(;J~+wKi78LWm*DxeFjSvHm>-7YocNmkT$E}&fVBRrC8;1&+bbzPY~ z8H7^vTxQJrzRBfRj`wx2yLeay{LwT(V5TE}&sD$@rUTk*Ro31coAz(81M7;BpD~Wx+MN^|H9L@@bsVJ0(O78tCeU08KX!;QiLJ*svFlV~ zHwS#nPCn1}Sjk9CPHzWyAE*SfS}<}0wyzGCVkn$D)y1|Z@(3)gX%bg0t*nM^XcOz& z*OZKVe=E5b#F*38?lSBDC}asl;c~zFNe}W$r@rP53A|Sw4&XzMmC&Vq72a$@l_0|9 zkgfzOt%wd~(3`es(vNgGZ0Vd$QAX=wamIz@$tO_Lp2fZ8G-ys71hk^+Ulz#5FqE+e z>pV{h&d#^alYPJX1zRbX_fQM0U{B^1y_z>~F>siji%iv=v5)*%h)eY`a`gRgLw?&S z8UN5PvGw&zW$et1jKXe~RR(VytpwyVIO|+^gIR(xb&W7@-&vmFj99FHA`ALY@>LDQ zMrKN;mZ(g_$cml4Sk1kHI39h9id2q<+!M`+2Gi#~BP#==fTD>Xwn$n^3VpM~0$spd zGCzmy-2x?nWBb#=k+m}}I+r9f9Dyr?jA^3yS6S79262naXpO5jcghbnEH?9zr@*c6WcFZ zi!909biB#2!rp!8?}H+06?6@KrSzv&GcAA|ww`_pj|-pvOwlo;)W!PxCwKXx=kvo?le&0($uOF{Pq9X!o0_q5HUe$f91ns5btcH5nj1$(S`ofWwsuSkC`R8gFb zP92VIE-Ecug#6-C>aaV)(|R2`h|-H`(uyY+NProD+PI>5WWAaFg+;5jv9fbV#)W_P zPjb;A5@&=h4u=tW`iL{RADgk=!>3MdvuL6(0^@dKHO)I@s?d@GLT0PvE)f$%hc!cV z*fZi+`naGmx?)qLU7%MR8j;GB;RuDcY1-`HR15aq4;l*T%w<5naW(WWb3Ye@yYFB2 zQlGrUJ}(8Px;Zdu<%oTBggr8|fRPryy*<@ynzJ)s_lv<&`%gEg^Jm7k#D5YAS$rs|WUL{~T5=%{{Hn}cy0g}aMQ6^)5_G-AQTYm*SCNWMufXz}kL@k{mOP_>&JDJFF< z2Awm8H1_J-wq;=6bz~OUzXPTWJc#h@6D|hL7hWsnZK?U*n}Y5>r7VK9k^i$-0wsqT zQCL(_`YC5{!ZM9?R}u(JP?4o2KHsV3YnEfQZV?k_13c`M8T2NZSdbHeX6A*8Xf|v@ zA(G{^*6;FCk;mQHhXKzx4h+=>Gnrrl6)AP0kg`A+d%69a32L*ibkEBT%vn;kOG;H_ zcYMJzQ`7jAHXdQqP3Z#aG6F!Jl?cT9-UaOe);>*ncgpC1yd+K4iOA9jl(uX2*&${5 z#f9z#AFa~%|9h=BQL0WJojpSq)6t{9?6-Agv2mTp?=!mdWp@(CY%ouv_r~LR#gE8q zTHh&V9HP&~Ok<^&By$XFT5k~`$3N~z?CDquPJ)TIO~RjPn;GAWuPUiS)VV(-PzlR* zP2Lu0md0mV*k2(*0);Cag~$pIPp!X&YqO7Lls~vL#CQRz@C9yRE|L%>2J!#aY9%)4 z-r(0D?e5y9rM}hjHf!w?oImIJ&m0v&djYBV|6P-7^2Nvg|s2F*KB6 zW%)D(ORdX|YRq$-#o1!CgeRf<(M_CJ@BlS+&82+JdOy46VbAnP^a8BjSY10QkU9SC z&E@3eoOv6PNMWb)C&-9;B_2_;Jqjcbc71dCMVqQP-oF`t04}f{z)Z+P{*pqlj+Y3x ze@5@T8I?44JT)Jyf?OOx*Std#)e?D z%fVF2E};xSl#dPcEodU#5`!4Hlnl3Y%D7lM{6%jpd4%&V-^bo%S@~MLJeU<(-&||d zT2^*|nCRLO{dGv*^mGc4D|0EnEFVqjg*p^K>45j~^c%1gVTDIB5`hu3 zD*Yxb)}+zsm`{cuoc^^IcR?HVVPL-to6*ppkY#>u`J1sTHy@twcpeTd4X07pb6YEXD|833L(^*qtpl*>6>tlcbS;ysvDq46}5Km8c~+VX(={^PNc3LT1OZ zthqW^;QSkA%o9*5c-OT6&S1+NBZ$SVXXcnTnPhxMPc^ zS*A`bF+Dy%YU5e>hPXvBI~Qx(>lJ*_cgn9nY;J7!8#w=x&2f~cnr$d9I1A6E;^NiiT(x}6VPmd;B z@{e7C`4kNhWQYz@YAioJHhtK*Gf|75j(`~&|aZBW5xm@Qqw!-ugi!mJfuOYN!@Jf^+a94)6JSmekf z*LoFn6NXJXTKX1s`v(UOBhIU-d-x=gtePbXW^#q|yV-mtpN@BGop(ud)6Xkc186=c z4`8Y|Juombz8*=FT#tx=2o!}~xFU8JsGXHR89l-VSH zamv1cML3buEdH6bz27>f@l1o&Wer2;g2K6r6VCm=N!jsqnvYf3B0U|R5i7=KRA+Q z+-w{d8I;3qg+HZ=@&|t#Ycs|{jv;;jHUZB^Wt$`L5~*+9M8%^{IEUmB_lc1%+Epe- z%unX~uL?$1c9hKl#gyWG=Kqby^YovD*^@&34@Dm+!Qo<4lG8Wwhm(*^Rj66h(+Bgt z#^3jh@b_Ie1?F0fUhL6i!QfMGOphYJ`zuY{xO9!pLajU<1jDNW>VC<%zl?rmgm>Kf zn0v*rZGq3g#1#EA9UkR{HreZ*imc~&*iX!?C!@09Zz~W2F6$R=u ztx~~@P3&1pb&cPtG;rghZOVnWCcezu;m%%e`!C}MHu+A+&1o8u7L^Go_6{I_bJ6#x zW7=|<6y6SuTm%}B6We%h3YUEq=5d(+Z!nnv^CPmiBx^AduL6-RbZo46O_bwJGeOO- ztIR*o9QHVi4#ZwVu7tlI&PG9RCMqgVXa9Pnr&#)?*MDqxKV)O}c5!L*4P(F~P)=de zQ)oWk30Z~*`;XneB1g^fw`yaExu3GjWVH{Lb{(y7kTJ?R67ndU!a z3cHKw$zj>;xAXk?U-hjjHHQHHjY)IiRYgS%$is=5f@7(A`z!wUj`A~3_4FhvK5#0% z@7i-9|EpW;@fe;VuAcruyvA+5agmgN5?7j&v&~ap9|af(-jb4zdLdTix3<+ld8q3Ry|kQ?sce zMc#2faz}F@wGYScD64V$PV)IqX>M1@8BYMF*GF@LP)TVoUFHZc7fiNY)i(Z5 zYFu#~7KIH0j#K^Nq0}nSZ;1H~G{O&r%h@VM)#_}`1r}EtC#KL^pav%dt`wNahJ}F~ zBUxZxD_wrc=#!48wdQLg$V{!Lq=g zcFb-QN?2l1pd4z99MorxbAlHj48~V`f-dr;d{<}Og{tfRUTU)cZsVb0U+1=<(Z(H# zF2%gNS?#gndyeuIME!6geIND1z$6K+eHq~k$m_TwRr!}H{GJL8y@_UETN!EN@3k#I z(IrC|OI!pK21KD=hDLg}tnBOw!AIcaWWd$&>U*)f9eTJyj;in3;C{{OktDQb)!zpM zvQy$B;Nx_VSNq}a%45>~imeHhN?EF|*P()N$aJRI3#UO=&)e;t+rAtxP>B%rf)uTe zN!Kdl7f^)>6EEcju45p1*!CUOnHm$J0>7taC+?ye`JT#VFv~R=E}atL zfv7+Hx7GyPe5hiRpQ$kxN2mkNYz_4Z^{h>AVTBl=du!B5SM9iAT>}E z7w2xA#Oq+5M~T+^N4aZDdKVO6f5L^?Sy0(ohyi@I?+&~#%NwQ`0d<{2h08z=)*~Cg zjgwu|D6-=$@R;D-82}NL7f?=vD&hubGqyfsiI#bH{q(p1EBW`y_iUIsHOn_51U$U8 zV~7XpvR~`2V-QNvV2?oP(ZByxB&E29TEtl;gR=w*VRz&_Ve}~b@ZNKE#Pk3z2>zSN zb}Zsa*>WIEf?zlJTyss9X=0or43U_biZ8;S!hN&vz4W0d7@ex|57*^Y)Lt-x4CTVw z+E5bIY0E9bDR9q;12E#LbB*AI{EE`AeS$LB;)^fQsi#q-`F;{>`<2(r#5)wu8*Q6n zAi@dn!0?qME_Kp@^Eu3O>%WtU9#F_o2$$K%qO)!|_gxrj%c&8i`5&BrhvWfbvJAm; zGN4l*u)aQ8PJLBYTnWH4w$=+t^jAoyhV54I{MYSV5*ax8_&2E@C1t5(^qKH7lx3Qgvm)l+wOO z5=7}cnDRa6PR;M9MOu4ZhuJ7<*h4@FdKIlfYscPy7dw-w?>>I_JqaicDjL#~ty#n`?| z`+U7B3l#JgjH*ttfy~G`83c~7OF5XKI_+>qNrJ>Tq9R;v*IYa6060$}wXe;8xQ-KA z%lH8J<2{~Qe4NhNwvtNZ`{FQ3BYcO%1~ujHP0SPw!@<(b+i`6Ddz@jVDT&$L;RVl~ zEvK93KWz9&6C4w-We-0oC4kGoCTLsY$+rS(&aJICp+9)c!#5?g@ZHmgsBR#I((#k3 zN%0g|LKqOQ)h-kwLcU@@Nj*fYD@EyIp|Vhtb7?w_Q>B&&a8i$;m8e^CAZEC4$j z70LVUI3F(-;*vc)Oyi|8S$k2lFOMHN3E&|^3R7R4f0TbN_fSd4|8jlh@s(owx;@=B zOm>7kk&lkff#}~Cx{^=X2nA-zH$m8Wr*`OU$4W^(#p&-)^?DKQ^KDLI;P}`ISu+dz0NIU(OXpt@{VOmzsfj?sg|owz?fj3q9Fs7Sk>i9F-!agLaZv$ID3cAuEe~_OW8>^yp z14<>y$cje6xJqGHj|T8b9ieE1Jf(liXg_1^6i8t^rYz}fQOy!0jws80!zP-hjP^C< zZHh(tz|<5kf#Q9dx;_%jf1%A4<1mF4tKtp<{6VjwsVQq|iPmcsmJvy)&7!ZdTaJQ( zr*^mGR+l?C5q&ifmkdtk*l$}OLj%}6p@J4W0H%gbri_e+~hBg-;!5qBJ z{wgH87SxmA(?VdBS~n9D$Ts^2f8(1ON)vkzZ?5!Ko*i{XW`tbGqG{p5sBh! zh@*{Q`Lnq6pDbbdix1}I-!{teSQ_v;$7DXD~zxhce9Yw&-kT+64$6jR;itr#M+wZ-P){>SeaG1f7UT zzxvkcwp&DffP>HbN76U6TmU5x$I8!cA z)ks5V9B?mwJDATFSeTwaJ0*0t=n}9V637KiX+Z~lv>(2$YFU{Ar`on*029a`EodE+ z@;KnM(%}jqr-k~a#!!u9!qJ~y0DI^Gd%N4apK$;?S<%=+tKkZ))6YOOl-PP#i;w zxU-`qgq(EWBcy`&@sy%;oXZ=@X1kE297&zyuE!~jmG8ekyX~*UH7`r-(~rqI9l6lK z-emlYkun{|icgyL&YE@n>AobW_~%8G8Z$^nQ&rbjI0|!XO;jo<_>*%@(#j zYAKRE^((;9K3!@4#{NsTIq^~B(#s_nLalT0>$%PN;kj_|^M9ma41~Nx|NNO0< zVTJ$HnFaJ&g<$~S>vtAKZu@lxUw|9DBdeC&N9L57;Ng6ef9U{h+?D!__UxXH*Z*7- zc4jI(njmfUZwaAna&H1+D^~>=(D;dklVD+$)0|mCioq+YFwD1d895*7!L*JNZvh^v zbaNt;je44O9^=$gzdxtREO&Zg2Th6nh-tH^>dnTzPn$H0UZCV0CQUzB?~5pM3-0Hw zeK-Xc;bG;ywcN5iGgV8>Wxhw*Z7z=Jr^P~+$nX~49aLnesK??s6Hz++p)mYAKJj-z z$JJpmQHq>~qWa|PWWKlk>d7K%`Thszgbd*){9!WY+hIN7u6=(uR34ICl{5+z^1K?O zR!%6Z3#B5!9>)t`6kNq5k)6GU_59z{~=$)EVVGQ+P`UOz+zyMa<*TeMlj^i%& z?eW}WR|P!Li^LttWGO%n#mQ8l(;LuWpYKj$#1@^o`;`%^qeGaC#4P)hlcG$f>q%bZ z=g1a#oh-F19skY%zy!ap(MZwT_R}mI3oD?>oQ(;TJ}GV<0- zrpwmCvadWYJ}TY3S5Q%LSi?^8R^TExDT6gWIW5-F6s>Ow`Mk5TQtRylE!|yes+Qv4 ziC?sq{P~r!wP%DotwRcYG6To#_g@*q6W*~FQzr8HIED^#;DxE*OoOMVHEfm{6)ld1 zciwTS(tjTHB2D76z~KZsue7UvT45V)OSQl;!haK1VKmAk;cCw*ya5TIGcH(^9#%GF^9H@=oo~ z2*0VwKvz~v2_-wMB#-!=m0un6wfYnw)=MVJov3xY z0MaCC!YPqs$omug>jH1D{_bkrsmBCQp3Iv}wx#nmnjRd*f!C{$#(?yk+FUZ$DWmmv z0(90_vo`Mt(XEj{;l)B;XBKt-kKW6KJ|{gG1A5lkREaaOxF+9%^CnZX7T~#lbVhz# zmcpjV#5m3viR}CayQZone2_PntfrT}JT$Xxk-V(H42~sw-qKc4HvHLdsi_hGJwPv8 zMsrX^STX>>8VEbQnfqid zGJl*Cc1R#wk6CHKA)~)r^=c?GDvJ31?=$jW#9*#_wIjd(N;d~FA@_fbaAi@#D_YPw z;6$0Luoij>Kzsev^bStLPyqds6cq%x6u>me>V4N1nAto0|vv z+?6+2bOS8)KX|Nk%K*|3P9?G;_;xCl*$$g#n=-75gg1scgqNRfU&D^)(U;8DaUVAg z>)u7ytw|C{J}yZ^hcDx=~&tFf=Nn*_$g__Z8~$Ts2oHZ~~yS|)M;NfrS#B?``;|0J8#!}sQc(DQD{BcjzB4dmTp0hYCy z>eCf-+}G#Uz|!QE*s!g!#^zGnQISpoxme$Vz>-V`Yn9e~X`14ZrGT43tVNHB==C)ZuV#g5ZMn zHnjq}lBpNAKB`)Mq-r2~>` zDgj_GBe%H9-4vCuBY655njm`ht_{z0CabT7;(=p>&;nsO^%0!NLa+MeufCCyf&|ed zpb6qnAKGvalj_mov)m8uE)lV>=qI`fPCi4gVCH<*P&a_2bI22?wJem)lI1<7;7LY* z=@0_whtsVY&jub?Ck+qrkBI{d@2;TP9aOjA3^2|wr+;J!lEVKV>O)Gyvg0{|%hgZ= z>38GktkVU^Z#XulU(ByQf(d50(#SizaivmzYi((K6hMC8@2yHmo9*=W0o>unaufH3 zz~|Gije&Gnr4hS$^tLcT3}golYMr88c#5a$D5~s9ca_eS^YurJ+JqnZi4Ii~`ri^N z&>p$u!2k+?XA64_?=7i7<%|W7UK~sEkH|rZeB3uTn+a5wb33GuN-T}p^u7jqP!4~%R+T`E%@LQ}mm1{}oXA5{N8|)K zf%{yT@xGu`x?4foUv0VwI@ET}+kKoxhM3^_{v)oydP$p6kldW_FSYBLDg5o2D ztlF&>+)$rcUpdKA@-~+NQRR10f$u?b8-+VIKE+p`#UKB==zazHpOsDGBCxiHBy_2{ z2jpbc0tQ@ zyr~B#jRV<6aG;GB3i zj{C&h_(`X|G{;Ln0^AbwM`adFaYOmPDGvew*4SIZr@-op)UZnOnfePueBbQ_9$e61 zxB^+bBSnfUel?lL3nz_xg%ptPs-lwG2>yMufh~U{xaD!h0OuJO-7f&*Q3$FyEMw^v zMlBnJkfKubxNT^@tnEU4%uui?Fa#{HHFGhnR{<*Iuzjn-2)p5RIgm#6Vdg?MGTN+w#yz#woD=tY`l329C{g!=T>g76@)}SQxB!!?Eu=S$J`ssc6^U`x*?B zulkzhM&3Fte&iMS1TE?(H`Wr4&>67-HVg!&_Tzkn}c(Xad}j3kgH%jQlUt z3>WFNlg{%bLxPieQ{VbTo}HZyeoMP?c+s3H3AnSyQj1vX_2FxuUBg?@E#h+h?}n3Z z6m(XN+Dt9y2F{-z+>Td%C7rsQ(uval!lnXBC7myOtRDUh)i4gwuxwqpJdAJFpW1>gwtSbJ$) zWBP=Ep5(GE@AGkM>j!lW4LU@!3@!zIzMK2~h87;fbwD2-6GMez+y-Jac0)YX1hp48 z2%(ry^K2ubphsg+QyTh#xG;naEJ96uec!N>SbYHv2CsbT0P+`gv6NaPl_L!QDnqQwe&I&4|x zuSe&^eByy8gjsHF!TUP7*w{coOvvrklCwu*!+;q9VhW1YXa0gEZ+`h?55fLuX1xrM z8tDtDD;{!NMxMmC0M(dPgNfMBa^L_{wnRKuI&Wo}qq!iXql7m-!FhH7_>xn{*t!x1 zd?yn%A2FmyUl`%b1hb*WGFa~f^v-1CH6RZH`;h9VZYp2|T;m};6gvM=bS6A2KV;8dmm5Ozn=bIt%NU({a;gi^{McL%0W1(USQ#fU537j1FKKp}yn82$ufSwi2Js6M(y8p^k5 zY~`v<7GoPe9pboxCJSUi6n|))@`GL#%_5ldA|oltQ7(M{Y1Y6ws`_h(_u(M^XxoT^ zv>x;brh@Ukey}sR7g-Uiiys=&WcMRdXxS}gzRRza-qJ>i*A_a%aiUM9htl=;XV)2G z6GtMVqsfEWbR{YobX*+=ytmGdi*4{6c4w7;4^6g+M*6*Vue^dmve9|f=q-;EC=mzk z9J8|9$ZIQYR@kF_NMA&CK=gv^>}q3fw?^)Au6ZSv_mT%~uSnGoG+MyjC+O zWP5zhMaJ)jbhUZ0KiT*_iBxk$^!{Y<$v-?E2QbeSeHcO-j#v$YO_JXApwI$=ddWwK zINZQ)X)f2W$6zcOFCjfO?ozX(EB-wOjW6Kn*R|1t5H;>UDU_f#SNO;+QV1k+woo4L ze^FK;R$ZvUbn^Mk7i0Py?>n;Gh^uX-FSd0)_7bzNfQWW^4E0~D;&FcJY(onRBMs^? zEw&p*g&`aSAtk*+1R~;9U~EHYm9CJ6BJ5BSg=Pd}V#A2qK<_2Q(ZO+2&=p6hE5w$T zmS?XqkmZ-^%p-Ot@#Iu%xtTXOESJ_t#oi3Ylx9b9PhV;W^p6mG$G=|2y z^|^jm8NMtbA5Is-aVTJ7fG-EGh~#9e+ruBeafRR+uF6*P8i-eK=Slo-+kp94#9-g?OP0Y5oysf=^^jLga()$z>&D?YI@h?{*5;lKI-EOeNLq zf#zLhR?-`VZRhau;qmc(>`=`uB~(fm}&&W^J4fM zsjg;maq(2IM$sEZ)62b?R)Cgho}2uuK~U5IJ7jxK|h0*pDfn#Y{oC z`LA(6gWojq^y$OVLE$3k^bUymrT$8838cqF&^XU?X;+KlEa8A7@V|eZU9~6NE_}Sa zhUl)#-{z7k>nfo9);j^UM*phl1XwzsK4pK@?pBgQ2{a#!B|xlf?QV4c^wl^4&9J?b4wl9_QLAB1=+x(5A}x@N+YWz93P&bZ6B?dD?o z^VZT3g4T#!_|P+blHNmktB**wGXg8ZqoTfOiI|+8#70HA0JoffKkAqyk>ja#qM1^! zdDuKBvYpJjB5wA)7LllP3KF8N`jZbKtEol=vZA}CY4DsxE===YwnqYm&?gZ@g!pW5 zi2VowM%i)D69o*Q`Fz+Rve4Q=7x6yz-d|`jU{e??s6-=(!JY&B?Bj3r#Q38Tz*SX@ zG)h+EGXc)xx7A_B4z7*QyL~**eRk_Xt;wl%GEtWld=<30jiT2#GO*7K(OdoifZyDB zdbtKkG{HnbFooNZN+_|nm4ibi!srfTuug25wI5j0Le1DjpXD-K_pH6BZrzBU$mpT{ z_|^jy{t${m{cy;merdso&!RxV5Gz!M=&&(}_&|JF4ICWRz(pyA?Wc{@;rM@CmkaEq-9HB-h*dP z=nbo!0XKbM2MtPJg;O{s;$iK~Lx3ThFA)P3C@nt^V&Z;i>RwN5B1uCsItBibqQb{> z-zTLleB26N3%+d_9%Y2%5L?Av zw_~xJO>}I50w^7TzAoK2xHN(2J;h%zN6GW~YW_R!qaX5%D=(q%_a@plnIJ{|1|g%g zp3ABj(Hb*uH6cklw;TbX^VkiOWtx0V=0itc{lZb%^Ip#@w%e@txK^!B4W)-#Y#tzI zGg8}mQjU!+FY0#!>r<_QV)SE64Mq!B{`c?3^IMQJF9#hz2mgjPliDcR{hBEf=Tz>e zuhXxm)vi&Jq@FSa9WxoUufv5XL_RDpJwIKG-*$&%U?5u1&q;t~p126hBn@O?IgMb+ zL~_z#mB#-j-xC2Twla~(E1h&VJtex8hU)%O+W(wm1Vgc}g=SGNNRI44)QNvy+Px^W&HBlww8txJS`;dCWz@+#<8c|RqjRg)qzu`z@ zeK?(UsB__rtWNu&&%*7W7i#gBfIA#a`_aJS#@&qWEzJPr-RmtS`QM3K5Acm#+%1?P z8YtX=tf0QJeh_h_>}iy+&Fk$-J@%g5yzn{~dXqQ6CG5`ff8@IOT4fH!E#avGPlgwp z`C#eCb@5o7b@s|8a8gc^W!#`B+3f-1jonca+z=oa7lO%G3DUu3l}Vl@>IYW=w%w96 zlWO{-w;M6<-L<4l^+HNtxD~%U>RvE-*pmrl)VUMUCm;Wys=eyo0+xgtw9w_cE;ESP z9gyaX=OXGQMS)}vSttY2FNkr#8I{vp?VvKyXJNOSlhyUId}|6;Q17`4LC0p1}O$!k2)4(?U z%PP46m>_ZvbeOUY0L)Rnqy`2X1ToDLd%S0H{W}Bs8!kblRT#Kk>4sn(?F#zP130Bv zN`(ANw4q13`yGgj8Pwb{#j0n%J5^kre%`Q|bI-*`e@<>;7b2WZXYGI%+;!56Z7Ydi zk8Tg`>G=1L4^f0rY-G7aS3T`Z$D%(H_*fip%hB|$10RRd=nYs^uveVs%^ zJtTi^`~$wc2n|^ubo6;ZVKCMU3U5^m48+Y}7-YKOw@z&Mn`Jqo1}eTcgOWy-Y?dU9 zj*Oa1LOBf@J5yn?3dO*}-pG1z9icpC_`t)uqoJr0gw(1 zoH3m4nppj9-VJ*J`zZYgXP@Y(>F%%Kyfxw|<8{W4#^|G95ffXPL}SA#d@A&j-Z}^k z4b3wRaYOt0xKo9=i!`F2eqtiEZsI6#l7|y5jEfi=6TFDQ)4qRrvDjwHd$s}G1gqqL zk7c!BF~Mtp2uV^gU>O(Wl^aPDpJPyaN{}oGWQ~DR5H}v95h+S6Ev+vYODj|lku zord=0wRXeh;*0f&ecUU--JTyT#OCE=A49^Kj24c#3`v}ml$}ID{|ZqM_!MtPZo@3d zsL3uZ1nj6orDuLc^Sc8=jz~Rpr3y$uP23Pt<#wK>hn_z3Z_c!xY)f)@(JN* z5!xL8JKH+-k#it z2Av?Ht+$oohAHd?5Hibo6UL5~$wK*<2K?Kb8-Ye6fnQrzv-ySyW2I#?T z+SbD<`Vsj{j+KCCKbKL?mJfoDXQS^25ckGd8)$+n)3y*ns0~`@htnaNf`I3zvot)s zKnMi#N`5bZPZs*_8UcMvJNgjk`bG-aw9;mJ|4y9Ec@iI=8*zIh6nRW9$(2}oKZQ^A zLqv-lLMzDtQ}o92u2K3X@j(dFmS}AyO2cN}RNda~*N`IAm9otp1;SeMA>3P!(ofmG z$$ZT{Pk>tl+cOkFz+I5I0#yo=YVw^Bzr6yZ=c~@EMf)kU^~XLm4H5by|&)uda{>{K?*=v%lDziGh$wvT)e{ z-9p72Fu$d<#{b*uve}P7IrK(;m)b}mWY&Digs#na;eG^6h85&B-y$~Y^7dHP0GTzI zHZgD?VZsyqe!R+Jn2n8ngEUGagvH@biMQHwNf;B4xX4w~+rPAhf^wK2L7hzgp$JQX zEE+7i0{}UqxX^v8?%0ZrKREFB%^5($ZK{R@Coxzdyh4_wju{9`C>0opYbp{TkQvdS2IcQ;U#> ztK+CHS`4$|X@*SR)y)jNWFhTwJ|#spbTX5A_JT@S6)JBLI@Ivur1yHHOqGVlpUc4~ zd#?aqJ@wlO7fOF4tXT;tol5A=p;{h7?4|>8XEq|K=ouF^D%oA9DjD;BJlDvH; z$mCN(U31g!%z^1m=*E4YtqlZk|CK+7+iA?)g7Z&?vs95f9Jk4BIvHI#rIa7enVT|Y=JF&G~r{IHVEyNX?uXyJ%v@)Xf^elbF1q~A@Fa*EE%$Q5lIV2lI` zZh1tn(+v4fycXKhUR?Yeyw%Y@#CtMU}Si@{MqrLN?Mr_H5kb_*+8MZOqhKYH_EuK)}inj@KYJe@L89X z88V{#y1Dv@w@rSO6!wt{uruFbrse3dma6T9s)D8Z`C@g(H~u{&Wav+T0lc0t)Ei9B z3MS2rv^}37;rEYeNflv%!WJ{!z8ntjPRm0;SZ&_=zQBT1#C#Nx?hr4y4eFK2$5WLi z=-Zd>3lx(W50A#lzo=CxY`!_f`ZPj!3_&9I_lj&t#}_}Fn-O0|wUKL=Z?cD8ke|}G zwiG6Q{0Abc$J0n?XW1%^uQ6UC5;W`%uck%zs9v@0URejmm>cps`7#zX*QJc*{`Q=x zC@J-?%IEiy5W&UlU}x0s^im$Tc=WG7zT0st`z*T4H}#64$4+*c!$IX~Kum#*Ks zClgd>!&>1pW1pq2LnC!hZq{K?2)5eWlVIk@3Gi6^Abjs3=FlCM=WOK9Z@Vve2U)%`S0>Q5q8tn7UQ`v_X~5~j9?ys zrc~DmD}L)S@`n&5&Z?zL9v4c-m@iJ)#VRERe{s@-A*q)*J|xoLA`Y`o5ncGJKjB?s ziUlFYH3%B60?mH5=kohbs7qwyz+aO^xIJFw%cIckgN%xq?GBG{b=CtQ7wS1J*O%H@ym8AZi?LQavr#ZrqY1f*+ z`#TGocl2`yT@8SXP)-di6J9~kcY_NIwX;BB8RBx)V!In?9-8DF_iN*>MKYW|iu%v$ zPRAY3ifDq2wsD!vMBAgEk#X2Miiyukm8r&>9%*Qgvzd~}!mg%m*hIN|Qg z^Tq!)2Lob@Pzy>=N#SNO_&W0c;=D}kAB)NS@bbP>DTXl~ao3J~trihV9&T=pAro=a z&xbS$dn!2d*ZgWm+3ohA7OGVMUlFyg*;LO;|0)I+IU-YJ$u`;idr)7<@>gm6T0+o8 zW0;Z*N~{Un<8*z`8mdh|+Y^BT4AtTTG`b@Kdt2Wm*leR89)SN`7xlp?s~s}r)hdI} zHO#Jm#}GGS(rt}l=5rVb}JH~AS3ReNx#dSQ(Wp947QGD=tLu6>yZy6^eT0riq} zdO<_QJ-fI+eQ-y%z$0{(M*{vfXwySz`7Tt!lt&hMmP9m1S)ncKwrYseJPa3A#&?0) z-IF`rBS&7!61tKK6cP1-b-~G^byx0-p`=X|ldv4lcJ^=AucZqN=R%0xm;+i&s+9a_ zAMmTIy`BnLsbtpIM`oy`cp zkFC!C7sDIlzI^s5c@%;}pu}oIa6^WIS=C-&FW4neeL{f7diUdnT?ABv_ETO_#2u2! zXB<=3sdV8haXKlY-OV#-x?cu_pU?$(s7T$e_5x2)AXgHZcE0t}%=ToE={e$Z!Iws7 zqfBvykha|m;L?I>7`QisNCba9FE6heS|wQhrlZ=T9S@0y;nX);*9e68kMS(=71eEnWk0NqW%&XZ-amc% z7IbRH+Ps}-M6L_AZ~)5tQb41+#Fnv&uh-7Iqe0UkR#sLOUstuKuHTxN0uQ%Rf@wiV z8_Jye{NlFa-{2nFyD?C$p`@yM6)pHm5@K~)4#poS{tP38Pybt6 z%gn;Un|;?^cy~8P+&L2vkpg(d(U>PUkk0kv{>l3XM^ChcMTD*r4>98B0N0h3b^+-= zA4mD&HAgEVhW8XIRcbT!qN#1^8p+XlGQn+XIyx+`RFg7$t|HOJazqw$SWTSx`^SFw zM2u_YMv3FE0GRCnXzDBCPU*c3;L!UOcBMRVVCGn$-eHXMgq*m7RY*icCsmy09#=Nl zy?$d1TgB5W!)^}}*TnxbmqLojKBXM|wECNgVoJtFVID2xu@q|D?3PQ)UQ^>YPxX-; z-NzX8F^*{kbR)8^SotkKOD(XG7DY~>a{T{pPrts#@Q!zL62k++PP`qVrA>O z6#gR~9REo@gA5|1O1a-4di1M)dTv7yqUy=+2XGc{A-+3#*V5YOk8g+S4#;3JPVD4;&($$DTMJor(hkotL$V&i#Nd4;P(zke$ z24wf_ked4i*7>5?b+npmygmv0)3di*+xh>_N`rQ7=q2=jKS>b9_9M;32sNFj8r9-* zua$e?N9X`fW6cQrNTwMuO=B0I{KzlQvs{O zAl~J|IFQ^XSL`Ds8;mUdl?6@el!8t-OUVzecL=}0CVpb>>;ZkP3}<9*o((C$c{-hX ztYhKwxPHPGhqKE<=kI6TXW=%aQB9GhwoXpvJ!?ZT@m<0HkxZNy zv?GFEq^H|$sJA3zWXn6Ho7N|rw-?}th|ANxs>R4Os|{*@vXdS(=*vFk(|js~>~X(h zvI#s6hPLjB)~2|qB3v#|JY3*fq977NTKU_{-u9W>mpQ7f5b%lpxZu+LPBTLoS!4Mw zU}djk?$aLsg&&N9fbOwZ zpQ5-PlF9B~^WX(&JA5RKfwA1;b(|2P4SWB8J|iCD4?G0^)qpp#{r+cfZ9l2XO@*pV zfbOCNnr@QpgS92;PpHieEGtlXYoItPy_XV!&8jgy36c-_%V@kwE}!o`Wnw8r$X=ha z9(u`p5AaiBm!Xo8&H!#-Zdhq5E-WkSexve<1Hc-Mt>Q3?SNw(j89IOm8N9Z-4{@|` z1WXXE0*i~lE)zOjKGwY@BYXC0srJ(F%sk+S5;XW!OmUPIYs}Y36~rqg?xBX>-68gl zzo2pS1{%eOaj*tsySm_h_`ra=LQ4H-f(w^Xo9w?+XBW@CSUpO)u(ho`Geu|QRd8$< z(71uY1{B&=Vl~iuM?SiF83>Rvv151br;VMmo2@@!N=mqOID@Wc*Dr)4&aiJ04nPft zzvlKR_0tfb2j#l>(1w{94UHli1wBW1HZsfie}1;3gd~1A7=NtAj@(P*>V;i#pt0unx?x?T#<3|}XY1a5~aHv(gMHY-zdx6sDo{;}%aIy6b zB-gQsxVXA04w!9zRn$B$EWWD4fno7N*?D0`s)$UuxVVN!dsQ`YQUlPjdyW29D!9!u zJK9U=JPF%AQ9A|MM04E7k00xpf%NH~HtThWo%}*Ztdd%)R+1oM&>f8TU1;$H9HzI| z^2se|OlB#sDC2%sd(9Hpq}zDCar}(2Rq_29G+19%R&8<9WaQ<`m%fjWaRIb;T0dJV>gr%J>BA8OpikNe!&zwivni|6$E;Xhd^XTZS1rN*A6z4c zF6Iw1djJk#0G9Mi?#(iDER@cMRS7aX_kIlilc$=EDOR9jO5kv=UArcMiT*E9Kwb&) z6)yHRE7<_(Ge-AXAlt2iBwD3Bxc0oI6S!HGVw?_BHyz=O~ZzkfO zGflrg-*zVsUG;6@>jZPLc)m0+VYTU-8za=Z2mk%T%AD=?+-G;s4ez0_CG7^nQFLc& zxqH%)zeL+)v!lH31DqP`_Z5v&US~fpLPG-$EAj<4-9asE`uqCS*AD-B%{N&oDIBIv zE;k{Equdli6qfGhNKsKyF9^a@ zHaEv!yVO?#Z&FN&0D?CC=l%ec6g4#H%S4(sIvJo=*GM2Yn>D4wz)9VZ2+QgxoyyzD z2(AM=+LsyC_cJlUJl}v#by2DQ$uPtuu_*!)J^n^J7!)efF+{iLhj23V)hgw8k3UkW zhxT7B68gaOwWRE?VUpCZ7{9d)qZpeM23=9_c&v>C@`GAyJiMBHz9-f2PiVtixflvsvF~jz)8-gj1Cd3}s?*Jh(s*EJ_~z*+_|OO7 zr?V46zOZ68ge$?;R@}D$y7z6@gxTZ4&pU(qc8VBn4K%ag$K?StT=P1OZyNyXNVM~p z=H{qwV1M{NS+OP{%ikPYV2}gI+4PGS5S5O``A8&^_@sQf-eNl5#h5a3?H{P=V@W9J zVgSc&>9puj8>c7dySMVO4WBTLZ3}s^n+s_@JLy4RL%db|GO_|5ZlHQ80cbc;c4fV) z7x7g#K6M0x*E+5ec ziF{&D_6b8?Wu`i@ZP-Y^drR_YkT%$QA%=oYN_;7}X!7;#*VC4PTDmw!$L;CgJ;lPe zmu+toFUN#(;425J3LCKoK^K=-7R^W=h7MNg{$juG1Fur<_p2%E~U)N=`5-i zLX>m>YMuSC`j>i%#5EA;bb28jrMKtCFo5+L?^ovI_YjcC z!h&Z5>OEL&A~0Pm(MElMJl|Tb3ZvTaE3lr+=5>t7-3oe~Aa{=gMuU!`f6Yv~Chfj& zi?ro(DB{n@1e@RnndmI9{O$h^f?G0H0sv>f_FEVL*aw+{DZeh5Pk%3(58Qe87=)Fe z3u{n1?O2k3KjK9?jRRb|wCHGOk-t!opsJIpKyQ!aw#Sm(Z9wK`ee7wwa`(Uf>KPXd zjW-8T6Ci~KUzFGUIzzzPQ`o#^^dtOZcR`?m=fA81AG59i)rO*9Hhqd@Xd1!5Z4&Z_ z6bJVGw;Yb?u3z_f2b>MJhzp}b_wZQ3bLgxb)KA&2tU)r$-{TZts-lmp_WCQ#ssIa`@LXc0YD}LZ63MQ;o5*Om;RBu-$whxqHg@=(9EWWk!)Rk&28x5yIlpHDU+Q~`XT3MnQaAnpdLWgIzG0@{MUCJ{oYy!8K& z&pl|i{C8_Jn_>mFfYvb-W^+OAH$YNnl`cQ@lrW`}I11L_7G{(zN{`_jf=jXecdxrj zT~~%$69)B7>|{_?>s#N@Dzx&6`J&(g>HjXcHH#Joj;BElzRgXKk_XIzM?bx6^*y2&C3GcHo8GSnz|2^c|1IwyWu*T$@~!yvmKk>#xmUaR>Qwr z-iQrOt2cwh_WJ;=Y5+LfIyRzB4#F$i`IBbd)Nwt?T4D`Hz-|Sh1D6ck%!4keHR8gz1Ov&$_7-~oB>PCBrsg55S{+|{? z9$YZBKlQcQJ)fEQ93DQ1?#t{zToHa0^$FTBy~E^g4Vc)IlRz@#q|fe5^Q_|FjB^}4dN;E|An-dM(mQ)*gT-ps5w5Dh0- zdXD}~4CQCK>%EYH{7@TDPSwU6c3FLX4Ubb!7bR)&DZT*K2aqtMmO$Sw*9X2O)fiZ-MUhpHPP z%5dK*iK{95r@tBL*ro4C@$#zT*Vp3~-Ua?J#vR)I0g(kun#&vzl*;7>eBl0nE zyOfLMNOq}o(Q7nxKS1$)a~o)AU%u2TccMhso!`&B7<3Cf7s{K^bJ17en6_te2i1gS zd&v1Q$R9|&aGPDy=W`FV@0CS%XJXWb>95m3qeVj8ms~HZpbH4*63xl)jTN8Rr2||@ znMvhGL3c6F4HlP%Z9Vmo{!AeQnMxulA#&3c7Wudk>H^if@R-8P>)nQ109BS0IZ5N5 z2nyZJWKk!|Cvh7a4k<4#pr6Niuh?;Ya$GFS$jXY}4?Oakap;Mnr3R9LNE}H}gek^BN1<|f5Af(bfwf;|dK`G?uS;|UjhANh*D6p0)X&0N) z>J2f>;T__cRmKt$vhS@g-=Iy#x`O;Ar+gJLm+UThVO(FySABvPm0N9p^rIc5@`m;_2w4;0b5_8n2mdHMIiLkpv z3yhWtK<}Rq@KUYh_^ovDj@12sA!mE7gM)Fr0{r~uVyH%^{slO#cif&o^aQmambCE% zY>zwh?M959TABN*`9WelAguQ$5L(GkhFf`9(vKiu7xf>#PrInC zrB#GTwsv>@K4@;IryGalN6iy+&`|oAZBId@fe`)B1v-e|Bn{n4cKBq_u7%M z|K&Szc;A;P*Gr zp&t4#E7A|@LHrm1963q`#YwP24F_a1uuDhG!E3QKEh|(k;9DvMQO{vCJL(@_p`h>J z0{iw&F_6(SaNyaAD|yHb#E>G(H!Ko@yOMea)WjrY2v74%*8XT0Gl}J zqeqW=^P~f@5fN)rPd>jGv(Vl?bpfRoH}bCY)aMcgsx-{D2+vU$^x!C)y7!sGNc^HI4dQ^?^Q|7L~g95}G%^Ar`)oI{Xx` zS=Sf(XUBc2$uVu@(ZqQ6Oyv|GxLQ*K;lEwYxYcq|~eW6E29tO$S!gUXXP^Pd0 zRj6Ci-b@a>d@-zjydS`*i7Oyp;1h_{)o1$f=C9&=B%w*Ystf_BY>bLZ9Ozk>BPrx? zqgazEhYrS+|ITuAh|WkcBdH@-c5Ejr+(_P!GZ0{__PSM*QTZW5*DntAHZE`>>Y4A}hgsmrh|29h|&+R-~R8YG98UJ|#GUZ(%+JU5e>1MCSAA2T?3W5`-d=t## z0oJSC=!Fh{f%fq|7tn(OI1G|N4M6>^HxH*qQ$^YOn%5Ep3dK;zNUnSg`XMJ-p^_(z zO6L(68;5jg*atJ{Af28`(O^z~{nMeB7Mt+31biCUuZdy-;5W~>bD28a6n%KpSad_p66DcO5o)fYUbV(Z-$1 zgNC@x-FCk&@OyP_NohDxY{RUvN$G_Z?T8IGq_a4f*l;VIg%oJAfSol}6zy#HO%s?652Wp;v?CJ!xkpHXr{&<&=Ak!ST)mY29QNXCEi6b%}QF%XbDaWPg z(Q8<4on}#kLX1`OY;R*}TdB|6o`cmVIU7@&F%oZhY~E6Z1=sv^VxT|G3H&G_Il@!7 zAL)?tn1Q#%-_57PIA;5k3+GLh7@U}}`?)*vG2>f3g$AvCnb3%55^wikzzF&J!}1cR zFX=-rkmg|DtxxURBSn$Xi%L`(^u90c=r0{e#8L#R#waS;NiWvMS#WWBM^6XGDNA`f zMz*|ZSI6=-$4>B=ea!sCspO?^-D{-F(;IAM*88|TYX*2Gukkaij6dhOea@pA#(vxO zrGX~amN8c8Gg*m(T`%?Ce5l%(;DEQ9@sCcgY~?wR?BJ~c+HdAklbnA{PHO)mpAC91 zd49PLE%ixQWoG4DmyhTy4ZbTepmDcD_?!v01K*yVLg4{_yollLr&(G-`!$p)8P*Jv zN#A-)9#yUU#ArSiOOX*={wrGbcrJr}C38ZnD7{9xM9@!$T9V;|EM9y zn%-)jl>_Ip$)A6aW5e`xhdA74zO&(BjAe~k?^DNoc6FAg?qq40er-7tir3r(YT*_& z&AdAwQ9EiQn&}lYQ44h%LpOuk>*BB^2UDZ?4c8Cg2) znHCqAIJDi}819BRF!4^T;3F%f22L8CwUm0R^8>jE(Vfk4!Y0M;M{%$k;f6cNyQxT5 zAb-U;JBXv+FThXn9nT_k;RC(YQ;t&M zJ(nIhS##E0nXUdiaB{S5c>Cq)`JP+5$}s*~dqgh?Qe3^B4NL)(%4N`GIX zCa&#f-Svy6flPOxpr<(^CGR*HovB0N-#HX&syY z_12>Ecqx-|jHBno)SrMdOkv>d{V^Sox*zy22FB8OB;gL!Q2l~2K>&AtF8Gd%+P_r8V``w(3pEYYkR1QuWXcfurhKXw#x{n_}E(4umXNUUn zx9jE;@pHOIJ>90!H1ela^W_c6bTsIY$ja$I>cn!ACuH%*$NBUtb5qqyFN_{DN?X2- zv--!z5nSY~fXlh`t=K!r>{8klZ}rINf4}PMtHv2^rx2yzuAaS-9DiXbbB$wsB`8hQ ze7`z)aRq&%4YOfMYgS>NM?Sc2?b{Z0zuD6g=wsClWKiyP&7y^@{OLeRx4>novPY-)V0){jib7PN(!08JU-|kPh0J5T&5WDez%srYNb6<;;oBE zu^RV}CP4bgoQ^caP!F62uRIQZZwK3dFVoy6_?Pyy#z1gR%MD{-J5{u-g_&~esf+U5 z=lv3R2k=4}x^wTux9%#6_alXb6u%0A>;}r;1CJJ06~D}{O;p-3QI84F-(aTSG)OKy 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

rz6Kj6UW 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 bbpAtWIf+VZXq4}V1AfZ#8gg|q77_mgZg;YI literal 52982 zcmeFZRa91A^zRJ_NT-x^cXtRVN|%6icXu};-Q6u9(x7ywAPo}I-QE2z)c`UcE)2C#Ia1hMduojl?fd6fj_C5f_XOY%PrqpJ^M#s29%;`1_i4xr_PWJ9<-bF`uT^UWCGi;({R zFA{FOIk;X=(h)rF!bBCiJ9NxOsGi+4A>W99PcbGv5|4c&!(}04 zdo$S}QqW6MsH*k;VphlN{DU~}{3l^Sf4{3eLhOCDJnZvux?9#5d8kn}2VV5yvi0%)>7SwDZpYR=cp#s{ z=1Zpfwb;@|slHeppZjw~S>E-g(;<9T{kLq8t%8Jvgnh}|g<0OSR<-xt%--$HDr^h3 zQB+5Zj}Mmv?8E6U3vQ1$Q>|3^Z0=`ULU+rkwR84}S<-??;O39!#ibX$LJu*$Rfbje z%Q)JudW9Lzq2@`_H4E;$@9o29Y+CORT5bFBdW<6R~w8I{oBYECz7gi4o@|zPX5P2T8-yXL5 zG?@bvBemVmPkPw5@!`K-iv!=hd@;xBmIPiT^>B#DW3TdhBaM2MKF9(;3mKow@^-)0 zXElPmAXz{3gNl|@0G2W?hv|qEbF<@&QPRB6<2}Aj)A7?Q6FN`loG_-@CzQMMq$;Q< z1bCkGQHv3|QFslAe`HW1NnpkDe{;$Mi|M}Z(t4|vAkAs6irw|?LE|BqO+m-45oP$J;_{aMRrbXrEEUb;SShC0?go_6 z`HK%1wR4%H3v&*`%{M#6y;6(_ciVD4FL~|P(jA6oa!g-k*ye_o@*(h2rep_5i=?Aka=}$Xe%$WF>)fpO8$w3se zRTF_ro@wEg)Gf24SqydB$m#!_Ru~-%=oSxCPjOgFb|Be4azRn@5)DCiUKD zdBl1)I*z076ffWTU(2ldLda1#!bVYvGxz!Wlg5m)i*741$+64&wrH5<1jH`x7$*0x zBKv+%6wmA_Yq{CU{s=q@{`i|<%2Q6mC>zY*yH(x_J#xFPRH7VkE=EBE18^r+-V zJ8;zqg83puPf{3Umwql z>zAfaKF(qIRi#QHRVJ&>(~?^g3)M`%k}r9@ZG9vk@QuAfWU3?i#5zKHDiG+!5z~e!iG4trqSQeB^5iFTFSbfaOLslCh9xVV zoV$Gtw;{8vv2+jorxvLPnGd+tR&@B~|@&(^@|{QJ-;UwrNIW_Ia`&BN#wO4}8o|je&dyLv$e` zu(-S$$$tRcu1GyFbt~`Ws~Te9Is_E&c2rtBTK$8pH!}SRqjIR@2E_>Mpg%V6RsGDh zs*8U~K(*7R^(P5_1Aa-~!*CD6posDZ(truH&Z|K@B)At>d@qI?YHaSjVSg+<(cE0@3%{D}`*{X-cbd=r}yQ5MEI~+z77~ z11^L%#lMKtaw`~{E}%O~iZruz;3~J}swQWS$A^-+dzSSZCAp|>U~63{5-tlwCkdZd z8{~5qn%6(*7wHofnc609qI~XF>yZ4HIRj3MUyLitd2{gM9;7=>s@<8dmUd=mL7QH@ zx}3v2?O}j*hlZSB5@b-&lU4j>Ecx-dq9BAs^V`qmtq(WRvDDqk0o(AAt}mf}m|uO% z>#EaS#^|O^x_WWER(sM<-+T7j*KMMc+>cpByhjWXas0g);fFCktW#wamPk~18b;n- zX$qMQc#J4(<;7)-2H--2;)7Y~kKs-uq{t9d?&~;1n zCfQR`t+G;`K5Jjxf|2w!-~T?PO=HJKsi%Y;vaUjc!YTqamwL6qZrV1Se^tx;d6@~x z;kvIA1|DYmKcRY#HAb6xi8O91z5tvM>i(K8hGrIA*ckC!#Xz8qcF3`q-jmHD>9a5yIJB5 zJ>iZ|!q!>T{2}4VxfDlPtKRs==H&z%N*|nj3yl-|(VPEN-uTR-tT)0%pcKrL=*6mPd-5baPt^Q+OngacvvxviIEMC^K)m5; zgZ{fP)19uwB%8zX9nvdW3Rjzev7-+g8X?2bQe%~j=poR`*Lnt@A{12xu2PSr!@ns0 zh*y;DW00$Rcfx$TztlPG65UuqLZ*rEFzktl3#oGDPW6+O!7m+6d~h}1(h2ws0gvl3 zSUe^*c{_?Y1-p}kEY!@ol=2RF&mKIJ=;Xx$C2Y%|lsNKnY`hwY{aCVDo+lEqc4C&T zMbPa|cp`X>1YJ_=2UwU&a250L9qE!4>QrLotn9YQ=QU!XUK^O{h1FV$(x)VuFAPyoWwwW}lB!*Kdf{^=# zU<+*|42AZkhcQnba)ZB*+^tg44uL~%-IS54H70*&l(L)#`j=XqLxcQ8RY3d4ujzG_3l?7S61abv@72uX#!)X`^mG(owr zkOgp5p;s*lw*{;^Sa)ALs(E#kGI!s1r5LA%Y`U9w(wPxRyC#a|gwc1AH1e=@Db>Be zfS%jMdGBNo1f9J;6o)mDJ9i#x4vS(Mz1br#pxk7LT@++$~&A-L^(k z{UF`Twm3{@YfQFc@2fOhiC?W@-*3R0K$U(Hf&jTEM~V4K{NRTvz70IpYdTL619%!H z#fjr@{Sb?61-WWsZHeT1T4Z>3mYCf5An%Og7_!KxAH zRKc^Mf=(u+JXZHbdXT^3B~SOXQ>{!?s^Zzk6djYc`ede(c^%8Ya9k1gMe)UOUEiKe zZzR@B$O6?=G_E1TSjxG|{7Wl$5e9jvQu1i^6`f_#UwnG3-pHNG1=*?|@|t8s1ba2F z1tu$O6Ar2UfD5NCYUyG@Ccxl0W^Q#c-2q9KrhvSz4RqiVSjXm=HaKB73zsduCtrcr z?qWfaedqo=44&oiC#;D;P$gXk^#sBWB6LkCIi(Jnu?ZBWa>MDi(Ji8JWL%@<@t2oe zExHsD4%i{AFXCeS;Ug*JGOtIxDFo_uX;ZS*mMiAqN{td=YV)RbeW8z87>VhH2f%;u1p1gQGbF$K*kS542fs2UodpFm+gMjMd6ezXtXu)Qvf}cR_$dWoqtw z`ocZ1nozb2;&7Yy|=F`DWrvV-o;Txc-#@#EZX?QFKYD}(e$MyLEyA3 z{6lT(C$q|2LwTyGvbg`zsq>p2;yr{e9$z)>NvdTYQS6Hr)K(p=swppc4YJu!$3K6F zz-!Na^1?HpXYnu<4e!g@fTI?(qh}%M9^}4?JgR{$8Dw|}p^dRJHkVf%7*%!QU7>s% zNvPF9i^(@_|1pc5JK}PkZjrnu&SHL3VDdS=qoyiWP^;z#Uvjc%^KX1heJbCv%5*Zw z-O{&t)$@bcd=kXwv^ccuqiHsTCq3%I#(ZiI#M&~U_|!M41c+o~(t)g0!Z2>)CL+Y? zZ?D1%X^MSuA*+et8`Wffl}0DiEiYg->0arrQ2Nf{m{{(N>;wo;Pp9B^E~m88dUymN zcoeyy>E7B|cC-^|$b`vDIuA*HWv<6iLU(n=a=gT6FCJ` zF7l(PY+YS@1bv-?t^5p|CLEg9Bw_a{SZ&gS`Wcb8TycosH|zwHiwsf*5tfhwE)nt| zm1Y(LjNgAx=R(t^MPJ0pw8kS_Raade51Yc;^_PfBv~V;NnQ{%=!)(L**sg6WWbR;v zXIu3SS}=rjzSbMEY@3TJ@tBv^7_oT->NhLdADNIESh5wUHZs2L!&a2rA z|B5i#)uq5dV%p2k5uu+;8v0)#bt%6NtvSEdeD3YSeVbw?1LZ<`l zav=E!$zACc9qW@~b?ANBSX%S@tLoe0k{*t6>FQBY{QEU(AvJ>tPRWJb`6=4ty%XpuZi=rF*F`%UO-$zT06RU6zf0h)vOyx)58eO?8Nj%_cz~AX0U}xf@F2@{m{~v=TLgj;k!;KY7#<;G!+1}Sr%7}EQexex>?N87(wI&2 z`6Qadq?$?Tw=qf8Sc8v-Bp;BCCD1*L;~#<6XqU&_ddEhw;Rq(&2dFu)NVw4h3lYmH zCYjeyQsi6u3XnF-azwyWkoctn9hY;N&29sZ#Zt?@k5WoGYhTV8tbIZMXCznHdKLN}U=#0&U!+R@}?7lDDHJBnC)zU>qsp7S_t27_%UeZ494$Qv1AU}%?}%F$h4h3y~YHu=@i ziy|5wD$O%18MVdra!QE1_GC3va} zS9K%Ze%ivW(Ho#Nqh@LX37N`&DeK{^uxM`plU=lTF&XAP(A=07G>}SI(Vvp|@Fu%e zNq7Cnb!HzoU@Ri=Ptt4aW%FUaBx2!}&nqy^q)pw}8YN99{giQ>tQca|V9{*(JtuNq z38AidjKX6NWXgtDeNh1|&D#B<&tu;HC!>mvms4()&!a$bH1xgs)cP8GKVA`qh5S^cN6vO3GIK^LD&NJ(o9tRTGL#NQsSp@=E z=(9ZGl7SR!K##3y+pZ7!0LnogO3>mp(1g* z97G(bC>m!M6*Fty7=i9U_o~n`6@4O!Wk^TB;YFdDK9U^#PsUnJNw2td^5G}VI7;wl z3%4Fv;4sf>_;P%Vb%|AQPTza45Q(9epP+$`<=ZMj?i0>I;>Um~?^`{`KUw-7YT&Bs zhAR=HCKj&Hay^D4C=!?TBQiH`q5if}WFor8_|)DI=agn8)t02fUX;Me51PL4`s3b~ zg+pP@0hrFvS3$ zpULdk{$;@Qf%wf3NlW_)UW&u_+0UoKMi?=t_K0d=-ZHmSUaIV>JoB19&yR;lQi3G% z)e9%E4ZJJrdDGZOl@`rV@Yz}<2nD%58Mg(9_#(+>DgtF9Ja_LBfKz@9WLdXt*e>WR zW(_xZ8M$)&ji>F5F>zt#N(qVUP8`EJNz-0JbG+MOcq7dwl7AKm<8t;n?YNyO`zW)j zZ1zU%Rq`*xTJ(2=L$r54f0jFz%%ehD7tzlw)9+T+u=*a$4o8~rLm4dt;vufvZuJjR z5cjGMgPhcS05h^AHhaM-P218ld&bE z2tSP&H=mOySt-f$gRVs>o&cej0{<7cah6G@8*WKZyAc761J)vaCPv2rnX9RyF54j} z3gPXKeQ~v~BbKsO_SLg~@!oma_$&Wcn>rZs`8Zj=5Ol`zUtJ{WzR1JS1KOvaXnT;3 zVkH=%QkXoH%%_cd98p+&2rMTAS|zX1*+QE zLlAF&exLE$w&|@etEm8^vvp`vDn^?$A>+k#LnYG-oS!s_^RoH^)?=j7^tpa7<2=q} zO`v#GnQ=e%UTe{GW2|gt#a1eGxjw_#qJ<`ayo}GR$~?!^6?6iDgI=)mfk~+8Sv-=VCb?|!M z4pakFXyR)}*agGjKcc=DD5XWK4JT1Kv67lVz-O?C5ivt*m*_i45FlR43RoAI`Lx2% z))t{Y#KAHaK$>AyEFu~Bqr{tO=+_)>!I*(xU3a%Fo$oXCiFrfp*zWfX7qHs??WTg^ zOL!yX!xX_#1j^5PVZ_73<5(13&Xl0kK&oU??^2?H30Lu`&p^p{MG;ZfjlGvF2#qV< zo4nO?N-qQL z$_vfBJ_YM*oBFYxFgbJ2il8J0YB#eV(WHGG?|nnM5Hh|A1sU4COpXv_(T}6*;=hy8 z=a{PovC^yJ))K2h=vc+l&LC9OYqfn$#EyxOQ!4>R6oLD*an>q96XLyT34WH)%rhm) zG6UH%rAY2l%~!FMr6Wim^X^k(>`t!9v8T_36=d9&4bFmP=V@-j(6c5iWm9-js;551 zK@m7{OFwf+&^zPZOvfZvi|rr$fC_&`0vsUf4nwgzs^1!t^_kQg-#i@*q4lc|l$ZIE z3$P9}vpBuD7k#12=1@&uet4RR4ORQ1(mqRm&wE(>OskDr*eB^yND$1~*zk-qunJDl zMD)3E;q@%15;BHj12`~@JvIYyw0YuvQM{Yi30?QEg!f3K>m1 z5IrnZf1pQ?G*+29D_>s{xDRv?CKHXyC|7wy^&!U|ZF4rJkET47`*UEuGUVB!8JCBC9(>KniqosU_0~Ojtfb~Zgf1K; z7O$Utxubbvy`jgdZ9Nen7FyJocI=B}g|=lhR_5crB@jqN-zyeSAO61In74|Fu1 z^si;V%+(UWWEmzzz7qJ@MIES`QYRj+{2Y@nBi7S5c)V?tqKzw&l2}bY1yov$pqNDZ z?GIIJsnEoE*Q@G+Bl2mI?n`m!d*Garx-f9 z)i7SIq$OD{FM%_qrJtotVM@~h`D<1K;Y`ffTJhQR3U0nh_X}oXq@A!gV*5GzC9<+N z4gm-(`Kf0NG*k46iO8 zLze+fFDf!RtQIrT6W-vfv>au$8n92}#-32l2;nigAQ{R$()d@IuFT99wkc5zCVgGa z!4jG^zF(Zm&~uECLX8cAjcL(Q+SY6G$SB7Lmd{a(xbnCMwsX5&xw^5w6>%JMY=^!x zoZTC)g!(~81%0u<@}4CBerX-u?^Ui_g}5w2R}*RU9<9Ctl(e)b8tH(i=MGa2+M{H4 zA=*~(sm81Po=HWhQj)eWNrO~&3Ho7_J=xQ5W^z;VJL)#DqtrCsL-rd+FjS8Yh_IW4 zA5|-GU1L+32Qwx~Rs~UdC{j?1iFmoz=$>$X>WlPies^9{pjt3inW*^OThEn~6t{S0 ztSU8DhTKnE1b9qNEi;i5S%}553Xc~guC;GptTs7R-edfr0}*@iD}!bVc|^#bR9At3 zB8!4%JkcQJ&*rq9-!P(uHQ={k=9T9bq@iRed^=e@#8<B=sld-}SOKH7G4o+1Jp( ze+%{{U&8kLt_uGx9YV2#N4(J5|7_(bAEL0rmCg?dV+4`UKSMu(LY^A(u1rm$8(8EiHC>-+N*BLYyMCg{TI5m@1dy_+%peiv-PoSCzOjsBDp!cdG9ASwy4WmNy8 zNm0m0`ciG#8-^$SRjs~712pJO9X8`%8Hz?s7?Me>$Mvs-C5#9pE5=V2qyH2vd*BKF zyA+6f|8EUbwoW}_X(Tbwg#ZflI0}#vkRCrlO(54CSX5r*@Lv}KJL8jR0forGvYGCX zSiAu04|6j!*Ug7sFp?d|By8%IVb8GqXsu5G z&m;roZ63yaevrJG(wB~_#BAt`!3jyjPyUQUd-A&0=8w9k}8mOs=R(9m9+=B zEr`GOW(j5UygC9CLU&%-Hqro;8J6mV(BV#6sDaP({-}b<=6h-;8Q+1hr)MeM?U70h z<@%0gy1RlPZNL*b3wv(>cda)9KZ%1qcU(0VkcMBAr~lW@k1(Vd{1E$|0Kco%C?6oa z+yw0m_syt_8{J+4H6q9CcGt2GKg!mE44HZ}P^0 z^x`~ZH{%Ka0`o_~fuldfscQ>Jw^_Eso^1jID#Qf&f}n zhCo>P)CM5FP@*jRe%kBLdc|?jEYVBfg56TCb$i-NaDt0t_1P+boaA zq?j`XEO=_6H?n-ZiB=Q`vw#6AvR?BJW*<04LG&{9G7Yy!Aqvr}evVlNZ_KbxLWp^J zAe;=htmNd}cgP|rop=HTQ_FBaPh z%lp}6CL7_U1+UixBNFyj_O@gjTZ?&k4TL*M8M|TRFnd}od5(aQ6f&)EIs({C*VaD_ zSw;}(&_O7KsdFx5LIjp(tdP*j=kLUs)qi%qJ@IcR;Ze;wt%0gbj%CH5kszsV7`KM( z$+-k7J1&4UC8Pzauq+(<;+xs*>(>(v&W1npw5Z^&0WNb>dqx`n!*f3Xg(ACj>vaZF zQu~VVN>xynY}b$_)_GBjrj8#@)wLxl(6i3qg5=pGtokk&uqc0F3sel+_s zA`IIOyd+BJA}|9yxhVwN=6HH2PrEDe3LRRitt~$+I2Mu~zvH^q$kk_^kxca+`UaHp z$bJJmvW+mfs(0E)-y%yB261L|nU^}l)_}s<+Yv~t%qi?)kqTI~4NwNS2aM?QPTs=r zZl_vAdJZ|`rexA}+~Fuh#STlAqDO~$%fabgctb^(hIaTcFPfP*Q8+cg3v*i9{2YGX z5Qd4p`?9i{_0__z5CYcAAI>BAmKBf(B_LB)3oz8~Cxtva_kD&!Q&bfml7jF2yr00E z&eA>sx~hnO{*>#pFH#zNn3d{vzchH%*KY@q^?$zo4RLUqokqv&x z^8fIqXC9zk9yJ&-VW22T|P9>yd$I^S=xKPY%x3RD(tY;K}1`A^|Wf z3w)9ykotWgpM7o80(B#>K|ef!-GItnLzuZex6rdHE>R`#15n~^2O_foD3m=F8l>3= zIsP&6Pmt}o5un!ZiU6enxaYpAAKbkR)dLD%&We95T-X`z+uN~`kj+dF6iC_c4kOvG zMFNpthbSKRDSo~L0Gvo}bg`j;UKMji8x#o2jOYY!3s-w0ZUJ2CIjt9TtQ1pXl_lu) zgoi&BG;}3;aDqUHbfD!jfBqC*XpyZ7Jsd{?kH&~~SoFsX4bz36f1K)~^9FGqc+dgB zdKtKB2Qug@us`Fo>C~ zyFlh1ly_bG5%U!B#Yg7@r9BYOSR7sNhX;sXKCzPJezbD}Wz6=gaIBlvC?V0FH|}fZ zfSLX(5H6cA*IbBi^=%Z4kQAZm1PCf>dtO@T3iOEE_7b|>-5>fqf{?MUtKtC^aAbvP)VglPzIIF1rYVUWI`w6b2Np!Rr#|NtK_m%pzc83B9|;@ zFx(Drn`%}Flubbm7LJqBK30NC&FR;N+snf&XV07~2SNEWR z8T>X`1-Oc}Uju}~8IkeZ z2ndVC*1&G#0&0KMVvhp5mQBY!oq@=!bi;hpL|178)~bJ=kWDH(MSEo6Hqd!RHC{ny zg*wAgp`)20{nHM3Ok{N7{4B*yMLOS{#OY!kX>U84NYEok0Zl;$NOA zuf*SAL=jJhP-o&|KocS_UtNM=5N_vZXFmvwGL>}3bl;KKFSYr7dT$5Y&YJhvJ^$eG zD}X-&5kB5KyR!NXx*1EP(x(`>?$dj|6spWzj&%W#7-FQ~q$=OUsS*3slktv0LJ_Y% z`o-&FrqJ+w66``~!@AspAG_i~+rS67L!kRoRxZgjgS!N9u-Xk+|MiC81xG6IbVUZu{uK;`h3K0GYB_>tPpz%PI z4O#T|N%ZJ?5tV7s?;0YpuDcwS^tX{k*chI}3Qyt1Qh%5i-V0c41{B#h?T@_a`bDxm zg&ki!f?u22{+7gwm7LozOrDw2uzB^>Z(Oauf2juBYh1zkRz=$lrt!^>AJDe-7hdyZ1aH-$n>_b;W{D-!Z*f4dt zF|1Gf1e-V*nQ$xK)TE!^dUK#_ylZ^renTZeXH!HD#Yj-2j39#KgPiY|IHaX+%~tsas*whcyE`Zm%t(3uzf?# zl8ms&c2A>k2xE(bNh{pljvA%9wPcf2Z~#-qxt7T-%sOh#2t!W~!^ds8>&f2(z#%VH zPUxOPL#e9K&>o)iHXr~Yhyja^7>p1WhKIyoUn86yK(4z%PV9N~`ZMJhX6rF9o|e4l z0Wjq17e>;uCS(iY?v(=1&nazQu#6?8Qx8FnoA0!ZKg(N)lM_ryXnD;!LwIx4i7K}d zfgFC5+LVga3(YEZ@>TDT%JYN7FA-t(E#6WN!?2<8e6>UI-Ch>jxkxZG;qxkpXU;0r+`KAm3 z=xYLp*2scdn^3j+hH5*zJeZqaGX*wM9bW}Lh#QS!+=OL7aF~Xympn>9A;(=lv^cl2 zp*Mb%9vRW0GE7-I@TLddb^xRNNIcUD?jg{Sx&|y4=6}qWUuJCD|Y##Mz zJyK6TOBfrDL($hwzEIQM(zv8|Noh>)r?+*Ht~ck0sqKW`ti~ zEEdUE1%f6gA5*r(i>v;33b`#$rEif$V4lT>+GMNw-zU}S4@?x8Dv$rJQuL=)THz;Z z`U|uksTE_exFZ^?29EBHs>aGDBdlX^?e`yA(xf!s$2`?c>b60uwti$w(x0IMe);%Op)=B!m-X(73u9MT0X^FG|GSPiKY(Nlr1 zAJ=`lLhslK(f>KB@eGDTU!G`$KCj|jPwYIes+{KfguP^!a4eYxT#2{N45!JB=?phKulTILjTNRY@b2WNGa z_-^TW_e@00|JX$;#G=>b{CoalGdjcw)!%87A>7O_32GC>wbtX8Io&6#l_7LMo%*S} zqjOxsE-YA2;umNUd#a0a@_7`-68hX717t*3^J78-LIimvk3P7cOt%N!pZ!yfYJ>oj z!+$DuqLu*N*jWV>$Vo*4Uq~?|O}~8^W__G*pKnCr4LTn6*ku<4RGU!YS8oAZ5;@=U zR3ZfZ0Q4aE%mO>=iy($EYJ3<3Wxi$o(i^Hu+$T(NgdC2;3VLpCQXki(t#^e$v=a&K z__;BstsE=Aig3H=WH9UL3`1TA+Tfiv%seC0a}zVFjui4ujM+5#H~nVCJYjz}7z$9V z$HQ8(?5I-yGfgCZ#^|Pz@C|C;D+&H7$Fd-WlLQGv&5(ieUa?R~#2**E1~Rzx zxX7B6zjMq8(z}|Q&fkBiN#Xx4{BLmnvz-4{$Nw#^gRVW}aLKI=5Ux&%Uu3%1o^HD!5_@YWdo*-3 zjk}Zxy6A;MCRiWOBxRtssJTAemo+`R!3rFZPxg`TJ*mdIaa8J0C|S$lj_|Nh+Psju zRI@rTul}^BBKYcH$Aqu&<+Rw4$V zefciI{Rh1f!@)c>DQ*(KOp&(U;mmQBNhPRv&_wRl4*u*^Uk(Mvv9Pm>Shgv&wnaU) zukIr3Z||j{_onUub30uHLhXZx6qv@^u*XlwFt+neEc?U zIrIYAHhNJB)LRyH{g%h&Duj<|wyUSB)t{tnBI)kdhsq=t8-87$GB<_~uksNFbE z6ph!SxEz;5+rMi=w=HX!?YW?X>J-{GAMzY$57AH`#?Go=O^9l^Yd(t9w!SFqO7;;V zn8#AJ8+ucr;*voT`C(IkOY_Rqak*s*QOENauWjrxrQA$w#R@@)V*rzj#av;r5K3$Q z>Gvqa#kAUrUl?8o-ki(J%3kON@xq6|g$DBnqAE){13=d81(#VCg zH=6-bPO`5mY$ssV=ld^`a85*pA%`@gW*4;I=vtaAm*cyHn8G+5urHRpGd6c^dA+I; zLCH(tAj2&vf48VPu3(uY+sX+h2#2~@5caa{zI;D+r*m>2_ile|XQw(%0jfCxR8BNJ zCY{giq3URCnrvs@GeorRq}VZtZKyhmUd-TTo!r~N4!)J;H=Ai1mzhimd)8Z=ihUKR z+3oXQXKw+YY5KS`fbanuG-0-grSO1>JbG|B8$IA?ipA8wya@tIqx{(G&v5JZzD`})enM` zV7=4oH2V>bQCoj;qESO~E|-d7DY#2O)l-hNaWm8oSh~tlwefpCoEj#v46w>fMWTJ+ zGCGQH`dseYRCx<+j*}7k(+HK`v7YZVem$0hkw|AfOOxYZ#s;=!9Esu1c`&jxaf{|s zvOT5XrO)D&5Y!tpEzkY5OTifH#3D)RF9kb$hVV>x^+T?@b9ktq9V%Gip4(*nK3*w{ zacvb0@UdQ)w&nMFK1@0C?1`4ljw{i}gwJLgh*em!uO@AyL^xGfu0~MavOAR#WUfafk7qV>ICpUr*Q3wPf^IURgYoLv31#R(TuGFMM`T2(ytqm0UhK>V%yKI)zI&xoD(NNB$D|@4(ZrD} zELsz!Y4YHR%!4jo$d167duNI45t zP-=4>qu4jHrS#`{l7G^{ezm&#LIV@W_LaRQbrjSK(Ngb91!V4<<=R^lLhqkE8`W{Y z-1hUBs08}@$*ZlM4;G?h z?6$3LwSpQ<3#{8NgoCbHB*v%o&RguJCz5igPIIFS;EP!OP&`FL4I*NMiQvNTa!;=> z5z9TNdG#Ij%FOsSh?SNoz3%DuV$*#)UNBf|HnCntMDYt<$A0M6s@dW#G}@`9mcY^R zS>U}|c@C5LZi7%M`SrYvW94i3Z>eCHG4DuZ{#y^Cd7WKSRQgsu@83aX7^WB?K9L|{ z6#XM^KarC#b=c|!U^<>Y!4U$krijKS|9kb90MHhT$TKT8b*cVdLHsQmXmlE82!9h?4#q(KLFdZ)|y&yMB6($fry zocgyw7{Q%t;YzyyEj>E$i1ee!ssA409k|mUX8EsbO9>v4l21GC?;-|7Gt?Ye1@^xs z@C7{L|IIHe+=`t5hS-$J5A-dc0Vv=J0`)mB*5RyOBU1VO1hW1BWhX#?JVCS3q$1dW z6RbF^Q|74b0H~?gasUp*34jrXKyx&})`mfqJ=uY(+qJy$paFoMaaZ6}30uI1Fw2gF z8Gw_`itSc=K3MCDiHSWv+|w7D-TaCi8X79VG4}({0NEl0$||={wO!D}D{!-wH^|uZ zJi!@!38+G}0MgX>>kz(m-7;t^t^Pq4_IbtQp0@QXIMgr;6?D>qer^>)}y9@G2=G_IBc zw)5$nK}j##mwJMacc)Ls3raE7e};G2S$?NWI_-VC?|*Y~R4}3F1)Gv$)kwAF?mi)~ zPw~XIf=1@D{U!t0Lr!o8A7C~3lq|u~l4{`OMSvl=5lOm!6Izc~6pbPpjAD4!lAow< z4o*Dm*S*(xpa0Yl++GlRYzt0i(*XVG6_7}P#d$g`2{b-FfOj-PdW^Q*-)2O=sq57L@RxP=VL}umR9d zC8-_rGFf8RCCKpNY&aiy-H$_9kePjDj~i_$S>FRKKBDL-JQ@eLfn(qN3`QNtWolPK z=^sD`^EH?-cBT4*F9@eC%QfMrD7>B>A;%vdUv&c9!P;-N{U9MX7hUILoc80 z#<4=(IaY;JsL^_hIPgb?XsetKauX{yNig&svHfIl0Ow6&bRy&%dX^(qZCjxGSoozOEES7Lg^e8t;bOa(vaWaMF|vWo6N$M#g{@m%fQxr3<4iNX~szwP3dmy5iLV{cidb zkgZx}?@C^x?npspYV}j@mL7wuJtT_hHxx|A%8-`YnuaPVn0qdO!nDOQ+zYkn=oR9+@kQ+6@Ys=wcA5a)*=Ia5A657Kgs)}DKu_fVX5w{i@7*fC%H$W^SrL9rvnytn5BB+M3 zV8YMYc!Ky9aa&6n)ue4=_g-nfYm3(iw@M^w1bnZyNg}j3R?wU3pZI9{16r2Hh>qyZ z%#eSk$ehm9?CcxpjR4GpkCUY~A}Pmb25wlB{y1tHnRl`6D0aKgfDX+KE^%=daIPWU zUEvH+8)`hxvA1j-rf~pdJ8i_Q;phNl)f=*2ZQs;|Lf8tVp(R^;u)8iGh#SH|mL3^!k$9~SpI$f4KV5A*1ZnCr>2O~@A8^A@f$^?T>4JdIw;g+_^ zE>UU9PuuX$$y-kNRg&~{E797hqKU3gQzpkX$H1tL1q)>|0Y==f$b$mXf8NZj5V47y zd~f?{nZSEs{gU;EFrTW+~ZZ4-YtdI?J3ZSu8Izs7zmeXR!k)G%PmO1B#{}m z*KxIebNX}KQ#M}9hM&i}qh1J%ohRIq6;WN>E}soKE1oXi4}F43*~SC{E@v1S&E=Us zG*TX}?Ou;88}KQhqTM;Ok-o!UJk)MoMbZjEd}3nc2xxd!>l^cKu_b?S3T-sRhWM%l z3uBTzva5?k-oJ5$m*?Wbw?d@uhYGMv3KZ~qS1ybp4#m() zH+tEVX43D{eSj*}U~$(j9dNLCf5zI}rPghtH(d?bCXTc>Z0S8*t4}ACdu)%u9tZ#> zLh!q?9qX^WjT6X)h~BzI4lKxrt`PHqOTdal`LTKSvmWu2WRZ4jUcm^&5lG|JKrzG0 zNAA)BD`8GdWh|AHkp-Yp(J6%oT+8<%U6!o<0XC&QH1*#~j8?SY9M@y<%C2gu+1OU7 zu_^j$y`12n9yWq;y((=)dLZoWDD9n&%>6lE>hP=QNns(M=RiqY?3a#4oXSljSSHWR z08%D&%LXl9*taGvZoDeSc|f}&`3tP`)_9s+TaM_2?FYe$j zotIMG>r*~cOylnq6#jgFspVrYEJ|BS=(1(Bx`P7KUrr}s#v)fD+%#XA!2<&bmuRT% zJ#E?IfvMWD%1zcT#2?VBD@nL3;AZ8QipmC2w)3rqi@;P1fX|HIvNw>rd@>PJXjeP{^bo!MvoN!M@bSf~{@ghAb*FCOO!+9J zb0V=|iu2QgYIs0)@3+QUq3Vx+&{j05Q)*|omEo%=J~HdUJi)96J}fi86DicLH_Y;i z7Gm5WdP#fQA1!?He2uL9l~JkifT2&ga)dKAsQ zK*C;T4F7Eja|3XPX4*r&crOuo{uRt}zd4l$zRggD%YrJ44l>NDGI$>P>DwQ8WHTBM zyZhsWrq}jYZg1@QmG)Y7Jb~axbS+v;=_qX@80uZ$P0KXVlaAa883eo`#Mqz&SGDP) zZ0BmOmsOEJsHHO$VbE5mWqyq)xtn{(|AI)Hn7ZDhZmD2vZuW+4&FDUWZ*jO|dOla$ z#z&|FeGTi1iIT{VsUtBzHe{OtS04{I&PGwsViXf`smFrgFTW!IspKAq-Go(7*QZ^c zdCsw*PB`yoR!z0DrT^xAq_{i(tgWM5g$lGB^pVQr>H-~6Fcs#C}mB1}Odn*69 z64?V*-&Fyn7k`(~(8xJpIYCeMkKW}AH~SLwenjH~@_#Gcw_t^!{6gq)AyOUy)&S_e z3u6C%CK{|JzWciVBe`IiA%c|$aa_ZreK{FWrT;fqgkmR1=YjFKh6x4W5zNXzX7bw% zVsL#f3g;w`E1GA36A$11j|>J}!NB$HW$X$+E@9}wssttEAC-vA&jqab|NnENr9@f}?hxG(vWw+A>GWs)bAqe&Dc5pA!{3zcrD3@YLJy)iv=3_)Cjx) z`TYjncORIBzH~MInx~?)7vhG{UxCyaR8JL5*Ru*-b-sMPV4m^Dip^c4ri3&+qa^Uk z*B5#W=MUX}R?IjX<)7hxg9uiKoxlmlKEKl!gR>yK4-%aCoSVsztO=Uf3r_Ir2QthE z1}L9S-b||K5^Gv8EVe_g@ExR?!mIYh{ac*M0QQj(<_ldLPU!R6g0sl~?%AhT3MOy= z`&%|^{$IAZ_Pvs&e1~=OJ}4;UE4ZdD8gQ|^eixPN$cORp=WZ-MUadGWpIuvP$RRCT zI2d#g$7=>&?sZ~`dSinuLL%MHCDhLjCp9IRSX&jIp`bT?pZl7s zJ@%&m$5!}iXjhZRPCG6QR_X~USC9SY3FtBZ=TJzyg978#|5}g9&l@b_EXnFLA4hVm zyxs{gUJ8vOzmj_V~a)KJmmSn3WjD2(Aue=PApgXRl+*#9_W=OuvZ5G()5 zW7&xid>H;`9eP^Gn+=+r9}lK}Rqgi$W}#D;<(doBAuk12^VbGzc!Bbr&qS_D3t^Pc zSplrUcGe8|33x$h3}{K2CH+i+Z%mk+oXYdv7eGllFUnU-ak6Vb8_SFzTIIZy7L~VA zq55pS)gyhvrLH9wuaQ^YVEzjAEAwpb0Hn7dfSV@ReO4G}2^0RI*r(C%ye*J1o!;}v zIhzjQoblE!vo%s0Z&I(B-9DRbfYomUD73!zjg3+%i2B*DqTq=t@*P*UVjoQEy{$A83sa!@1tNRE+$51d-{(S2xr*e1+?MTD^SLnx_6i_NekyKj!iy>9a|#j9lJd zc3?DQ0MA-AQHIKI64TYu$l$;dB|&7SRxn3;!E>ZlkB6b3$5~*(5$u=>`TUKZ>temd zZXU2m=tH6G%30O&5;^m2CHU%GW99}%iFt_03(N5W?*Uw=r_SX-MWFKjjvRWE#xJ|y zL4nXe#ding4i~PdGoUsh04^`qrK{6&@aD69&x+@TZ1yH?3T;EP zv*tVV?>kQJYE@TebufNaQ}6 zl5@-&eYX-Zy6tl1bJ%NK1bN*pGisB{jSOT+BMn13wN$LZW_AHN z5Tt-Vyfu>D1oTQEJ;mtQHqs9kQI5;7Sn?1QS3p%K>)QrIVFp&adGyjza{a+;z!%UB z)IlJYiS)p=t;IGHB8>jdwY?ksReQ|a3q_DgN5ed_m7@$7mq0r)$9B2zS74O{&QGtO zcC&YZU5n<&dvuXBR%|&}9Xv`aK!^pA6F`(z)q8CYWXfiLL6zJ$)%^i+ks4I z;w2*SDG+LZPlhbT(tvFpaM1H+5V8DD*+kdxWV9T%vA4_ja2n`X#l$4)F%v}M9Mp2Xt>xiQR!L@}-1;ULX7} zDOk(AV`%J3oou0+=|m`_4eOOlG`#>qxjUfRT5ItFH}Uh^d!ekOBE2H10E8zi+5TAS z%5Q&|*S5d`uLOCBNoB`g&NisWZU7}-M@jXhNn&FH=Cn=So;N7F;uf+Fc!IbUo@xC6 z>#F(q1C4mC0dFN)mBqbyCZXd(scqEIyGgoR^9CBqOys0l{GCw7pD(-$ZP&nJtqRnL z@d{a~4=w9}<_$PdHRU&!TYW3~B3Xd*#6}@SoFbc|( z&74G{f~xUq%B3z}Gk#HLm8$&8&W6Q)ih-AyYR=O+4O~bATuHj1et~*$Y{s|v)9UtV zUNaN!32)#++5D=Pz$7s<`BYeV;4{c?0dG7|?Qr)~u05zdcT%(u(HZJBGH45c3I)U& zD>*#cy3?TzRkm)~pYz$^bkT6rK|AVip9q$!d{~ZE$Gq!v}=z`Ur4Ts#%d%m`!oiPZ)-Sn0`F^nTm^@uYGcc8 z{wRk-XfoTpf|s#E3Q$yt=0F7Nin&08L#PT;Sg7J>4>KTgKsjK-Df<9#Q;3`_FC?E@ z9(&LXbR*ytUhWPZcul?~z&>86wKN!Tqe;PX zw{l%R{{ELFWN_Y!8;0{O^;A&3im%Ded`jEY5na2Xw9TW4&6OStR0(8MChnG?NlNpeI5If~rh84E$#$xnPpGO}@1vPFtqr^* z-1r`w-e-pz#0`{#X%ZOTZh9Vj+^sJZeV6S3&~bmeDN0)cO1fR9ZgL(+FJl9)kKHbT z4`Pyv-n)6={Gbd53Q(JVIQ<$xItn-V?sW45Igg{m<5 z!9sc!E;QmZ^bwF!YVI)CQhQO#B<-e+NJSWB0P#BBYW{hHSX!V!sK&DjCWlU^)hvqEl$?%+P-DVW- zy_{nGltGp41h2L$FevYmZi+Pla}rM3qtrwM`Q+)8WQ*3N0JmU)@r1gicD((-o}8Sv z6ELU)SI55^NZE;<`1T04%+@C+2k|uWr{7!!Ip6*e^SW}Twxvr?pNZjpk479E7G5I# zEnl$Ii&EdS{}nSMnzi|+`wsV9M2-#5eDde-HIQTgvyi7z+h~Y&6#{#8{FE_vWhgem zLh(Ud&YtVDV=bu8>mH{AD;A%%Y}bmK;l&9wrcmwmi;lXW&Gy|5jpZLnvY|JApTvq zEd`?(#A~q?B=jJLje%ZWtWSJ>dolzH?i#rC_Q=`Tk(@ojH8NfZ(}CIaU57^}%GfAh zO>0>!9gkjm9w%n`7#vHYq&qX~TDFc9ZE$5WOyFQna>cl0$sJSaqrK=&%&iqnEZ}{* z6ij_vsbYrah&_@#?*wfVJN^b%81(7iM^4PTbP@Pva>%4aw=)b&TW1Lx^{$}2JSu~$ zxC;z28X6lqo*4b0MU_j0?PPHPMlF;*z?K;iJ=9Z`Z@sL&o($V>B9S5t)mFZr*0?jj zV!>-I@xk^$c8T}-&clNT7aC1p|3~srs~Lh)af;lcK(ob%Yw^Xba!GO}l`L75KVPM` zXkV97&8mDGo~|+?;NnyXFi3oGtlf40pxf(IY-A6W9G#Q3j#%@{gS4?OfSkOUd`4E&0u_jejm4ccpdr7k8K%; zhx^xSGD9wE(s&VMyWKxZxen1V=feZW+_*QN6F(SmLWzyFKnZm1BA~BMT*(wTGhKSF zQIaCl5CQL(TzUR+cy!p2BP+NCTz6WTk&Y_=*pe-1^_h4d7k8wgY4Lv7LrsHo-KJlP zW04sTGo?qZG?_`Yc4SQ{dY?ApVl#g!eZm>MJTgQ(?to(N)iB=?Wq`}Gn>NM7TP|D4 zIUSktMrG^jX0MjoGy#*JSMHiu5opCgfw;?WaLE6RNhhV+&{ZY$y2-_1Ts$%Cz1!Q) z?STgb(!mEkU?g4M12Ic5Bhgxl6$36nK0;pa<)WjYgTU7uRYEN7ikai*QP>5Si`S74 zdS`OE>uN~?Z)1HQC-llh9QEpYx6Vi6s6^onKX>*Q;T#SnT-7+x*RP0%F~89sN~F1u zY>{TWO*0s}{ca6636Z4qFI$W`qu;+JV8fH6@mSpSofP9v1PP?jig(;Rk7hTh`?u~!a$miR)OP5zej63+NKd^Mlzy3Q-y}1nj~$q zo|E+IW);u$>~o(K59fQW=TX8lu1k6ms_D+j+GwSR6ctQ6n%+7K`f?54<`p7Nb3}rv4EhIs&Co9t=^O$!`xGCz* z!CAFGULFiI1L?+#tM>{DdO4xClV@+emieKe2NSzCY{^(SpSR>{0AmYx*ABg_UiI_$ z)!ElRqD((RX$?|=X^_1dMUvzB?GaAR(ksR;_4Or1xnVfQ}0Rv(IX@v z!pdoFhget`&KwHn_pxV-M&40$wj#E^`>iJ)lbyaDHw;03*kz#lbv4A1UT}_pBqX@a zKHR%bAJ$2)VK<j^)*Wj|o%MB<9s-qPLCP_^I83Y$r)FRaNX{@8+)f*=E%x#l~`Hi^onh5X$Pqu-A$fc8WELTSx^Zka@>Cfa$O~4JQT5*f&|!_);Va zLp_>?_{$dS+E$#8Wq+h{jkohs33*9Q`+X!Dv)=St%Gg*X@kvFoZ*vw~Vlq`Jf7)0Z z6jR646g&x4zYSLDgOwGt7_o!|3s&Izs0#)29Rho*=huyStZjpaB;l$op(4m^Ns)`I zMruLKYRm&mp1maopU8L8--y@VuQ8jQl93GbG)%?cj@l+hK? z(bZ3&?#|TA4vBA+yr%}N>RoG0?{B(YB2@1k%?5m8Ht~xN_WJqHl>OV2`|-#8k1#K9+iZiYqYBa5522d*Wp$h7ST z(Qp#FB){c>+Sjfx-(cdmus=~_eNN_4`uwQtO1}Pns}F6st*7%vXUxOQ#_S8Prg}@m zu-6v}Y_vLeGM6jr_%SLME6C@x@M;{L*ysFmDU`l3L+fnB>is zL&I^V6Q)9O<>{3d=9suNzw$z#sP1xR-h^E{5OI;Ve`}KON;fd=%w6@HlEF9i zM<-C!W^r*hwx)dLf;&)=Bi*tCUIBse`yc{A5y!9!H15TV1HE1-9$1CBb8B>=v(uOJ z;?NtzpI)wKQVbcZBn>I<0t%IZ7+YO9UsyK3Em-qW&V4JaSMe@Bdybegg=djVzs*WW1~@VaY%1QhOwz{W%W6}(%2$!>*$~P32GU15#I4-WkLfd|D<$7P9-Naym}spzeFiNvaX5lL*jX^*(V9t6%-_K1 zSO()bJfX#7?rHM(Rb>fGJZz5|2bZ1uDGV^<9VYiGg zLkzJD80lzFEu#4LMA#PgQ<58 zWOLb7gr)J+#@}`zD2eS%(uw<1*NJx#4U>fuYKANqx=k-D??8E67!+17o)v$R)+dKX zFMMb6%32|MV)aA5tj$0k-1dKtoqej|mefh_F+o#h^abq(Felw*Ax^UfV+qZ#U{EnS zXG;<2x{bV|8VjKH%IN&ypsUEK^e7n|_VuM-=XFuXBdxHtZEdNH5eJdSKjx z%B0BC62#w#-6G%=$YfTV4Y@6Ua3^j*vzLCqRx5MrpHKjm%ivNC?t(11c%3Z!BSFGK z*#hnJZY%;y56JP20G7K6nnjek<3Em{C3-AK-vN-l}Q zk$4yVx_MB2FOuk{C!V%7#m!gZ3_9Wh5>XqOzWHVWSzMNl@DF7Xcu2U@LQ zZ9$A}$>{xjqu9!Q>rEo9R%DvDo-9xd_ii^Be~PI_*1 z>7(X378=I9IQl_@*mzXC)Nyk#6%>?H_#KlQ?2@?5M}gS~ul-7Ue4{`lI`m>}ZCnM6 z&}B^R^2nTs&yb{Jx;GakBQ~DqaW-Sqhk5F$ZX`|_T@G^=S*H)zr+-d1O}#ShZZD6( zd`0Zj*X$h*3OG-B3zgwPXpHKTt<8x1Mk7o&8hk&*l=(&>U7CT!KV#t_eeYEoviQ=* zGbaLgm`2(&24i^F=Jk$lN0&w3jVOJ%$SN^U^4N`5<2C-egXh^#!<&yL!#-0ic_K3tC@E*)@Xu;7)Nf&3@$4NRWmL`9jueWv7*G7_wi`NxEX9xE(i}MpksGGuY zz_BW72s3w10*%KL9oF$RK~coKNGkV`SIFodC7K>LxCT|m&+I4JP*I=qf}v}-?}I$o zLPo`4-J_i#`~P{_>5)h!7+EVTED>izYH(SA*{!(6pQSRe{cckNn#AZR@UBs3olGL` z=O|zX5g}}ZaM*Fy^}d)snA@S#$+cZV!8#Pq*UvOEm4qJL$o`L8BQ0p85VZy%Qn#hWj3ET}n5yq_(xW1g`=>1l2iT!=4aKClJIBAG10(+8Ki~b^~jT5jExH_wK^( zD>fM3x*ZM_&?L51dr=O3`@(FAj=lu4bMtwI8@v_?p^Du|i21L7YQdo3h9$zpTa0xV zsijQ&j~4(=xt>_TYqzUE4IA&HB{{K0Ij8zxCzyb@HXu{*CkskFPy6=L)6t+iC+QRE zJ6n@1X-@F+O=wgd6@3fUC^jVic0zG~U&m%j#r{VdJylA;{{Qj1Kk6@p8xBTOSE^9W zznqG<85ZEh6nqJ}`sZZx834FZuh}jCNfJ~d0J>X&#V-1{ud`u+T|d*AMEs>p_!WR} z!hiFVFhW=zMW6rfs=y7#n+d7*+rOhi^II@RNMt2)EB(E?0&(!6eD^7l^zZnBj|_uy z`1V{U7zs|y@d78*=sitni0>G}b9|i&jFYT)Y9Oq<7%< z+yOF0BkM8fn0B)Nq3MP*{i;8to)%&|Z}QbTo{DYb48V0KwNni?{rWg)(W}Dz0HhSX z>XFy|Fz-z7n5XaN2IA*8<2?3k9JdAmVR;I;lMjB`xQ3som5SN!`unESvmCC z9$Rsg=sjNrgnBw#)R^)qFZE&T_#WJ{AzOx~m)kzXa@|w1 zWKPHlt1&p$l4OW(IGlh}php5pOg{*>jr&eVdhBvHEWF;I=V-}_^4c{7 zpc)n)T5`kPo~_SBq3)SKUi}gf4c&m|>$~A`4(ocRI$iG0M@-UeYm>=7XE|YPi4cO#$Wr}*f6m1L0bLOCBQW>?5(=4V#_3O2H`Nw zpwS&Q7$FHr3_ctNi!#-2Wl>?>ufsU;j}o}X{gz2QLO~<2A+E+*HzDJVW%WJ^^Fy|U zXM|O%S+S)J-N*1g42ZMsuyy1l82bq{Vbm`K!9u(XO*}U#st`@x9e4QUKu|%~2a`2ipAU@{LE{&gEg!DKu!(p85(Ois2bHCYW>h~e3ks$xw zTfJIt@6;Vj1^oXEQz5+c+xoJT+u2d?EBx55WqbbAb0z@tbnlN0d!)p#K}Np)K@)b zItw@tO3(#vS|587aqrHnn(opcu1Nj&Kvyka>qOK04D}{apMxQgT=|>K71&HXXVk(~ ze)W9uvJ(tA(!_%YKpzANpk#dS?84))gMKGqF%r$U3au|GjFbQ!BR|wsa+^Wjx(r zhzBaLdzEYRH#I{H-Bf6CpK}ecmMCPvbHPg9hBCP7M-(~qiw}Gg7C{)Vr@_C-Au~Y~ z#@16A_}R_3L@03M9`I+9VzPFt1J0ORKZ+_v=}=vzcE=(6J8pX16dWe5YFNWx$4%N zM79DVB|~#vh8b7ss_J#ZSo{osyf=wPiDJZOvr~=nZ&E{^5;tym%ZvZ^^T089RY7o^ z&YnQ9GeLBh_p+tuhoC+2PL5=(+1JWGQPj+UP(@%8A3M}w1ReR~d*XA4{uJYS>koc% z!J+}-=-yit!O!0DEY4DkXj}mFp8Ja*V{!elF{_7WuYJE(E#HCrR2@?1Q?7}w#N|Sw z3?yuXu4(^3=eF^?j+Ear_)lKFdFw~`F;HEV<-+D9{;TA9fJP|hc?mK2CKa`Hqib_7 zQpjl7;`A>+^^bQMK@Gh@eZLe>&bXea^&wBjpZwR%$mmZx-tdFbP-gr393yC(q#HRR zb6=x_xz&LseZS~ud#TqpNe3Ur``8ZLhCCAAntZ=iZ#@1I4=vvQ8HEBZ9u8XEL*r>A z<$Utl{hgtdZ3OouJ|$;Zp>~!dre@!!UroL6WI%z5)W1?kGm3bF|w~a z?q!_%kZH^Hy%2S>xlB5uD)341_f(fz5ZoTA;T=omwQycpMGV45_BK8Q zCCc}5ZFIN2qN;78JPvvdqe85AJ(^(FyL#Ms(Gc}!1VXQ9%b=`129pUtSt-|%HiN=Z zx_SnCK}({r$f6j$U)kZ50Tq(P{!l+n)MUOtow{NLX*a!K4;ih}SXt_ne>4x2gw)4g;@jbBzqW5VwX~WqM z+jU!7VR}CSl5qSW4u6!!!?M z!}6U}nhBzYsV7N^<)$!vYi~vH30k_32eDz{k``gq;d|$toM07Gy|=)7Q@;Lq&9#h1 zG`z!i;mOy>>Mgy5_wPWUBzJP&9h1L>2qOyH%$#w84unlrnjA!p#iU>qO(v&ppZ3nI zLS-xz%Mr(;Hsv-vFQZX~5shbb>ZMJ-#p>s0yOa9;zPQ$(eX zt!351gsWzJGL^LpTetF9=jx@3r0ATYUM>)7-=1DmfMl=?L0cRZeZ{w; zW7Y7$`Ot9uy(N<4*Ck6 zl7**_zwEMxEJYsLSJ^Gxu?c9HO^d)8y=129V7C>AV134USac0H{^pipioMBUG-x#; zo3ZtWY=Nl^{AMe)~B`vmTOT^RmEx{+8GR!db|g zFL}d4+;yjRW{W`&vcJw4?06P4KTG0+Nr8We)8#pc)Fq-vd-+T^Dx+~%zgE0sbN@IkUpRdUm1b zks$?EYGI~KHD`2&5hTI!?ZU;pzwN}1HYXY3??YY%5vWV^Xl@(7`TX1AQeFr-Y~Y#Y z&l(d)i+(-N9j!%_{gmo1S7*n>Wk-YGAHMV){d51R zQ{Q`&$|zzh*AcGld@Ok+OM>eCNQ1N>lP<^_Aifgrnd`4~R7?Ye~V?c|91EtLOKC;7R<}Uwj&Mu_}~%$C8hX1RZRVF z&SK6zna~8m1}{I77-$3|#4Y14DReq5c>~_2X~G4VSB^a;i+pMnOzN)J8QHq?F?YRE zgE1uX9pwf?oeR=V36c=X4lM;X%OLQ=J`_>#D^X(o!!0lso{wOdZy0-5{|vgG2YAVs zG^Djm#~lnW9^@ zszc9AjcHpVe3Lma*zeP6J6mqvLPS_Vu5nAF6VboRP zl2fndZ)U3@Yu>ed(llKmP0;OLUOg6t(VXLnx}f&P*N~Y2UDeDSC;P;}7P%2k*)%+> zJX}{$qEoKS$G)B&At?Z8JWBrmp>a^uJ2d)S5N|t^6=PEQ#qey$Hs2@Lz z_^DV}Ya@P#m-f~xQeC5?#j5=^#=9=vWT<8f=!t>q!BqaOxzV2IH;#teO zRLH}jrUU+Y_<_s29_SK?ub<~@PupRs zS2;i#)C429BdVTIoNsn7(4n%uZ@WKG5Z{FtUH*u@HAfv5-bDWwvR&%VH+U_HfZx00 z`i@yuLc=|t3;QfWOLxxtP&(+~yp|!Xq*a?(nk%2l?0eb!v=NtC8Z=o>_I@Hh;Z?rZ zzSrnu!TNQ~Ws2zXg(;lw_ymR|Ve0K=>?j+xJJm$jew;U|)2Z4{uO6?;DPAuj(`X`<^E&T^n`oZyRc>^6BI-S$1iJ#3WVQ$xC_Nw9ND&6dF##_G-e2m|;89THe7+ zaT>1q;cvP!?x1f9B=#P;j*~H!BRk@Zc(bsjfz;e9#%=hJwX*u3e9(<_%{_m{iF=q! z){+#sks_$9hn)s1kKK}CfLhOkkh2h`~b%zRWa5)>1ta_q2 zv*Ys5q;49Xgu5Tk&ci(E{B13<@Z`;9cYsE zix+c$r9k>y$SRgd?pyYj8UKVnWT0m2h5ZQQz=Epg_=g=)u|a`a zFjU6Pzj7~t>UISosz9(6A4siSp@zNwW0eDaPW%_Ef<{L31;Rb3Es=kA-U&lWe}G zl5E>?$K0xd%B~v&MM6;@Z-j40t6lP6d7e-YB4sB)Uj7dDqTf60tsNpZ>k0M=yyR}q z79?%UQWISO_0mJ{#HOuqABjBODum)ZPMN=mK){B8R;ZBoL=Q7bOHZ~i8TsM?E>RV0 zZ^KJViIPq6o%*q`3XIQ)ns# zaxk&Pyh9HJ$HE7{nn&qJ^hGR^&Y8+E&GL1I4-C=yjY}X61cTxQ`5p?&|Bkjm>9U#% z1V>l1yzc-0s8_>)yQXbUah~`g3;~dk+Cb)lGgWl91HhUhjrtuUkWS@&`OQnUSpEl_ zH*5Y!o3DCbsehNon#SN9-;(7hguvlDvEHNSn!*&rqR^dCjit@}L#Y}7A^Lzd3VM69 z8CHo1!GHrPP2mkgv*&6^F;jSc%d#Pw_fzx41y1YFFaE$4$xBIC_($GbBLQBk|+beB6!;fc3CQ??)(?1R}nLn>2dV25N$RnFOvMrG4(e zu4x}rBlb}fY6SKz+XA=x_e@(5v66(o?4xH?Gys7Iv$Fpq8T>y#3K{wQ{=a&>e?cMV z_@>9#3Ix}_&DHRzxTj>Av5y1zTe2{K3TZl>K3a2~LaezcOK2Xgxw-+wZ#pvaAFVJY z0P~`nlOLVNz@acHZzMz?n@|)O=7nJ_OCQ@16WAA*`0jC_6$U4|Kq~5a{5q6^egDso zV*O8iyljmUe`0p)-A?YW4i*89k@5+f78K%#QrQe%ZAMXEL*N!HG8FqOW{_l-Dp73G z4fI@xkhKmd?bZQ+<_9R7LqG(e6HBBl1d^rm(?4UMZb02!RN_?X4Sjcx{;5=END}>f zkh>=A3_d8wkzfIA4ZcHOBVoFyknG$=OWYIXz%UA#K#czK%9vv1b^T(=}#2=V8bvC$j~*Q#4n%BMZc~aHU}X)gMhMb;fvp~ zy?d6rC&}QvE&xlCt}*=$NanGHMWwyKF|A}o{P`UK8U~Rx?Th_oP{fOAQYgd~KM;Wl z6HuqE0n?`B^2lDNrn~c-@$VuXdU~S`EK_e1%gc{Ip&Q~bBDPBMq%eE*nL#PYmc0cJ z%2tv_KuKK`KukxKxOni+i1c9nBnS!9Gg*HJ;^H8H64BiV%ZJS)h8oK&DQ`NyiQCXy@SH z){NcFgEwVYR1Ae@q{QYPYWl_omCzZWS&hq2Y>^sj<8jH`#%GrY%n365BjJJ?+ea+M194+512xa#Wt7rwfBj)?RznY{Io#J^wdSR=V{VKMND z_9N3a$sEQgxz+s~eZv{9K+tEVsc=p{21qcLGuwb#LnCHNj@IDaIq=FSfgSpFD!boO zMGM07qViFx-08*O*N})kh!{)A3{oKlpdLU69j}X2{W&c=3Y8+4- zcnU5S)ZmR1_k%Q7t*v{9mUN62e+TjxbW=r|W%mG+fcF4`Qq2Mzm^gEhyZut{wKISP zDfZ_ZnLCaMVcdg_1eLikOAeq&8w^!0pU)8keF(v{zG4a!R0~W2IpZ6qACSJ5A3idr z2QWi1s9DBx9VO@$W@|jS8{q9Fg&qI`)m}ufpn&^qNX|eZ>&$$Hzd*maOhARJHtx0%z%^~X)O5v8yejw>F~3oev46;y z!%No(OzMO@&UaN1?m-Jh)Vt3mO+03Houk7SB_N(aBgn=3>J&BgaM>m54b0_&*_>Rm zJ*qEv^d1Q7GhQ^Yt@km<5M@*93_vq%9mgcpQ`PS~Nxd^U0GYB;oVP&3DCd|6$^Iq( zK&VHay4J*vvjpi&wlv!C3I5{jg?PGX@y{x_Hi2E9Hxgvt8V^pS5iMEvhKUim;Q@>} zmLTW}^~E-Ib4OCiGctTRo!RibNEUeKV0vVMk1yS4dr(da$eZD6lbiI`u51G_^)LVmRQMuivS=zDmf0VnZlypUm7h1O`*cly}Z0y>?b;+0i>7WVU*umh!Pqo#2o z@Z!v*YKjYh5DvDYAAw7sc#{W?tC2A!%SeP9oO(t>rE ziu36|s$@PJCsr~{ef^fxu#m(@q!>hl|3&a%;ccbo5Q$zI*`7xf^o%YVO|~UE+8NBN zjWW6sH{c_Zq38e+$HY%V*)E3j@cNDx-}vX{azNp&q8&d`(oVCkkudjfNX_*ZAHmOc zXy%&aspO1SWw1x48fbB8DOlBwmh64{?P%fb=ZEEPnWvWc%8kx7%!40eaR4~f&^B_{ z5$#_q*2RkctPfmyY*q5bvITzXdFcy09kpo`?2X_8xle9gg)K%z z!gAFVJ`7WGC5~^+QadBsXX?FX#Z0x}Cne-mILre1XIA{^tW|y3VPx-ZS*e?Uk;mo? za}dM8K}RaSLn!p86pjg(lk6t%TU`C-imR$hJ|{dN_L2rZ`(nKO_os_-I-Yufj+5T> z$a}v!pVqSn#QwEGQ&GzJ?zK2&xtHeMLU_!0oabXdDTWvZslr8L5exJxUqb*;cG2Az z%gM86l%!Wk(pT;U0!Nu0tSH-Z(O9J|{qzr6T`8np{$IBuDP=C(mdPUdJ}C>$u?LRA z@qL@#_cw91^0BX0FK8l7CT}Me^$ur(Xm09g)fS0q!ovfRg_6@#LRIgCE(C(%lb(ey zSneF>F8)vqFR-V=U5${zD05>?seK`lWPDz+b?@>jUyR18<$4KG^sPU{yAwa}fa)kY zh#*$-*^<2H3igON7t_!5H?ENa+j$`8Ha5+^AT)A$#~C^nZ64W~6*sdq{Bv{gAw8@? z>$cgXg?06E(9CLGen{%?_(~+k8-oz)%8uN6D{t8fnyeW^8^=gY!?;}u^~nT9^hg%q zJK&Aua0&k9u4HETx~XegL>B8m;$f}Rc+4PY5WCtW% zY~gbwR_Yll0$3;$THde8Vu#&lS`mD?xvR=Bi3Sn{Nq(293^1{Sxzyio^B1c*T>6c? z`s-(JdZHi=60JaU^rEHcK0JZpMQSec<#3eB@|#wqp>d)<`dw&dLxLUYVQ4IDn_T3T_N5=T7B7VS?=tO==OerR<4PFhtP zpPz=|eT)*^ob=x&KGRep=sVuT*Rl^P1p4G@ne328jtm7{{=`3hR)pcC*Ub+(pzU{= zeATq8ml;LZwhM)4_xcfFaRum~+M~VWpOG-#{yqG1+)#|t32dgTKRor0pE_ks4U&5a z56{;xi+?R1Ph$F%jz+O=G(88yl3mDDg4uq`SWY~&Ghr4xZ?vbyqXW@}5spC@LzAnYGU}AyZ*WvMrtjQymrlX1bx~NhLiT-J+v!RUG_?LW zI4~=37OJ}1wtjL&H(blt9&(E<#YFXV1?$|}Q>@$vd+kPZ^u%+r>Dk>V_u%p%P|#6X z)2@tPsP9m@W-kOqHK$}vITf7k&6)AR;eiH5WT_SE%y)=E= z$+1@~v;T7Ue<(ePn~40V!I-esT8KQRiJcD-fZfcNnzb=dvD@S_;lZECu3vjq!c}fC zbM&Q!3To*!bbPFleYSREmkOh&QMp5BXg+O;m~GOicCeYqM=GqeR5=z>AxEDZY@c2I zKrSK*1Ad!zNGWTm5hpn!8ECKFoL5gG;f;it&KpW))QKO}N2;gae^$hl5zhYorNC_J zIO(xVdn-1~Wlmhr6MK@t(atx3;d2X_`mIeIDyInE54XB;@g_?49IZ%@eOIcWH|Jvc zIiEC~CZq@@NhqiwA{k&^zel85p@%=Aj_tx|5G)tfHA*i}%ET^1gcrLb&WLWBoajsR z52Su!_lwkTOKr8>n{>uFB6uL<;B61@&87%kyvCMK&M)%&1&!{AE_TtY}3@uu80tG5%+ z7BDB|+K#VNH_ee@Gh=IPr5rkMRuk0%j;(wh(K)IfalYoLe|2Uy7%mv!Sk7+ZXtI*) zED(nz0w`Lt#@~@+fr_iWW@iPS*pW1LtI2j?Ki{$h&Kv;)vhzZRKY>2(CUs!WxIk(8+$lLb^LMM`2g3wlhU?yt^Q7&)gNws3NwlPM-`(q_!B@LmBOF&e8Go}Eu!*^Zb65) znx6Y=Ux*TiwpCN7&fpH3yK%rek2o$^mrAWYPnWe=)7quk$rO8kKCJ*@fj(~M$u8?L zis*2mdiJUhpRCKhc}0+6D9Qqjvi_hM@XpZa0_*<1#Jq4@oKXNf9i-?#7WjD z&m=;>zeB#>55?V-Gii5**q7FOfLV=Z_L9)zbN)#9 z21%zq2*Uv4P5v3fVAN}sNgG2$V=)I4V&;JG)kKr}(ly@Z)n4${311|QN4GS{6Xvd;8P^|sc z!rsfEg*^qh!atyZXgq={8`o;>gWa6XAV)F z)~znuuDu%e)&X-JYJp(u#!K%@f^z+R(!T!a12mXE^yIT=k9T?j(PDYqN6)CRDv^E9 z{<$=dh0tY^%tL%@9YwGB1|*{{6?qgaA9$0s3b9Yt@STmYXX(v2eD%LoOU-0Sc8ieQ zoQ~gC`R?HqK<4PRTg@BAvyH4*HWiJJ7%3pABf-*q!JiH1CB>FCf)SKNkn&il5(HTj zOYy$>8eV4#YavPQA(r~eZW@Z=D~vw0;XzMt&}WiIY;)5N#B&oJ4Bzx?@V0sZ>Vn-* zExUlrjpksz@W5L&aEnVyMuiIidJVmO)8`Ogb2OlPUgq54zsT=g2RQF1Eze}#b1aaC z46rxR6gd{>{EJuv0Q(NvxLhtUMM+SU<5q0oH{$b43#b8JY_M!@f5AP;f=eaUqEjv+ zLk|IHIQF5w|DwzWF#%wHWC_)H&mqN30{}{Uy-BP+hoO;lpqR&1IdL1*`O|*`$fREJ z9-{ifuD}Q`rDK&HxG*(&0l<3WsR8-|qDDb+kBm5l@C&=b|I1&p^J?hL6rLQI#Xt(b z3%Y-z+;S-O!BukR|3Vnaa(rhekTuf4kASq}1>^72E9tr2x2NF%PfO;_H~+-^B&7lr zLw=GbP?}pD1-+H`%Aj%m;E^UIBQtAX^M^7XJ!(7tKd2&PFPS4rO_?-r9X$J|aNchT zJjej`I59o}qFIklP>2Sh9qG&nz7QA{`6hfk9Of2t}n znx(AQakjll^30hSiBaERM5IPts@1!|tMrQ$ z1?7LL2!Y<@n!}|13UVPmB?C;(n?@wmwGILSu1)kl?~($f0qL_MxOW={ZhvC{VYI5ESRitu}~nOg@UpGeX&qH1kG^B!t8P}NF`;!LQ#e_dQmdG0E&dZ zwQRckQ!d%^^DPiEGmsy)}wD* zCo36e06-(lm8%80jq8R0I(I)e>2TPGb7#qj?zWR(ee`z+N^4{_75D1r>9PY56YJ6X z?3YfVZD3Cj+3N-gk9^6x*HZu(Jex0i$a?A%yFD-l3GZkBZM%P^mGdOs)t&wQ9qg-9 zor_POJ2A=KuwE`M>t(wtvePVckjVjxaK!t zl`uPO;6@-Q6z`_%Fm=;$M?&MMEBhd$IrYpeh6<)q%&yxVm^_tHr`s*S+!^)6v#PJ| zahCTZTti02fcRKg^9rDRKxKvHSllzf6A&_3$aN)*9e79-`+~lc!Dp@3$Nk268Yq4_ zYvux@a{<{C`h!g{|BBMwWBM7oG*Ju|jK~5C! z}Tur)0A@*v<`TZ7(Dkj9sqNC z#=oO3Mol)I^(W7cTF%P)I3?exV+z&&0|yH#walt5#=p&NAjp!kRPWKhHRb$0$;wwL zD2xg%tIs)DMh=@}UmltS(7`csv+_tr;NzAE{x#i+4RC_(#EG+>(g$EJD=(lL_QtDB z+xeGuCm{143r*!xtimZ^Ym}DbJnbjT=$b!(jvdcc{dbK6TuaxiV6aD);@-nuPXj8% zNblTDM~|^X928Enl%&FlAu2AuB0qV#i`Q?zPtLhU;u1w)QtD92LGc=bDs zYsqtax|Y?@9^Mz}vVM@2imfr6i%(9K*+JCfYk zK!ZO>HI7-?o}^h@c1PNjrs_F~n6gl#1w{Fr-{cNCJ5(eKj->;5!NotFJ(BYE_a8c`A9}W6Jfr0!!4{XB-Lyr`(WvGG7d$>*G`8aq_M!AyvuXG2 z4Z12?W1jHc(ElHxK{-A2L79X?ZYSgGZ%BQ!!CNfgVuc-{?>-xt$J-EQ~Nj8DEUh9RdvxGkoC8Sg^x{R$KabR{3UGn+0IpP0r!%$sw_!l9k zVq~@6PQT5%d;Q`~Iz{3%`5d+Cj$|Vef0h1kB7b+<-XI40W$%!&JPBx{rCfVQ4oZW$ z`iQO5dyTwM@HC%RTTzqD+CA`tc%UT}HJKu$cL)Dakuby5)?WEqUMeovGnzu~7@JLW z9+qQYVD_AB`sk)Ee`27b2}98Qa)kc#{z|;IWU-Iek?6nNhU8VmMOBkFu8yhLa}s_0 zZvT>#WKqU&%<|Nh5W&G5tvw;Hmf(?ih<*Y_BB~J^<91M5reU2h#V$c6TFm-SK(>aN zM)*!7eGB5yUN@DlWX^{SG(RrbuL+acsL%pA2-3480f)NxGiE^(T$1oi@&SqaGt`LmA_gFt%m8 zeqU)aujMYuPiAZ>uFgmg)wHjM9IjhsUOTn!0_^8)_!i;S8)28Y*Gp1{qEnO8(9UZ9U-Xgnh7DT^s zxd(m;aJwPirV-OV&e1XI;97fAZ^0JtM-4x*iR!#D zFi4W+q{KCR`J_aTTdv{`7O`1=WloLXF`16tx;v2)FYl>Rjg#E|={aq z23J9HEI1C78e8wlDd3X8k&mYnaO1JQJ~r$D@;oWgXX6Jwq)LSt)6ONN*b!-^&6?Kt z5l&`!>9Q3G9E!$m_clayG~=!(*eT_6a!x1$p8cZ{{$tV7BUH!yfE#idNFl@PG-q=049d#0yN=Kh>a!n8ACgQM!gEX?Nq+|xUW=W8!4N%!{j=i^LUft z!+tY1e+yN7+S!O-{>DjKPDbupI0J`d0EkvCr@EKH+b`!?>V~3Qh8Fpj^mN9>u4+ya z+;9{p0oX7l;t4Dsf6tpz#AG znm_b3YLi(;!#zZ{pJ`k_j+73;S>92HBX!<^2w+RxL?9&*+U5;4ZpC?-P$F=@kdO8( zUhkL@f6)g=FJ z6RCsIzI@Pojoq7aH%aa(8-`m}-nSg%^+chV#-GfhyP*lmX1BQ&K4_DMalPwfy~4hc zt3a)^&8V4l)DhxRwt!6JhtsMx|@2_zICyc6R#5g=_^AkGA#fpWx{1?WP)bLn(Z?q# zgv4G3RSm>L*OH!RvX9x2^bp!8nGqXnXKEy3x5lDe`+{qV2xfuZn7;EHj-?4X(>mwP zjip5!uP68JzefX0)nE>#>u+q#$=h;A=nbF)VGlM7tevQK?y2AgmFosBR9MS&cwW9^r zO~d!9OD-UJ&dL%8XoliSKtV?e)OM<5Sxacl_}rk6pz{yfyfRL~B$)1T3e^pviDXIs z6rTq)tm4mBsd(Gvv7?$Dqh2yaXp2&;Bu>Rcj473~fn=A8h8B1kl_S z_UZ8DP0|oqIdAb3tp341M=U+V_xG_2~g3rqJW5emEBxv(h^Kdp;uiNSVQ#LRH&)BM~#>NM2Fh|cIyZ7e3H z|6&|+9q))&q%Vd7(pHh`M~TYJ5D+JSGN@1T!{IUj#Metbp3Xr>*?!|`+S}BfkBgUZ zvKb&5m1C%CEatk$OqATs=R89UvS16Gx3b&y=rraZU1rWLGY8`QJsHo{G_HG9t+kK7 zmB0AeQsTA$rr2lsZlYe`$*UGnQ4xo}6T35qR7=<;;x6}8NY}kv7VxWHcGNZW+qKDj zE4OnZ?(M`pPM~go+US(%_zS5sP^wN% z9{dV0jbGKR3=dR%ZxMA8Bc_1$@u;DKSSXLdm*jV&v10^(0c~xxH>M4(KYBGl`$JSR zk`Ol&-f};SJGLK#^@iKpsaw*JwgSD@gsMdNOYWPTj(tiW#~P)RO4vkc|F(DYhPO?b zAL2ba7T+=P$kb0-uVMI*RT_d}nFb#WWcQ<+>IpL9o;7H_6VuTRFEkK zvB63}iogWU3v3FR{kOPh#lzS8N?hy@rMnmB2?V`{-k1!W#EAPQ<5Gd1^5 zcFuE|<#ihhgpsjbj|jCqbF$otTn8D_?2zO`B@>h zt@(pyGvNFXICdG7*dNpNwZ&vkUR>5ZPasYs@P~Y67;M!(Vb65Pew@F(#}f!$GRJB> z33xb@CNZ-8_fuzyr3a-v8toj1rDTzVw6m&~VGol@B5!G8b*;_2%{nW~z>i-zG0{fQ zCY8h|R@$+KFTAB~9bQp5(cDjPHfv|0k-iuC)}Ae+h}C;$!+?4=7_y)iV({6He*tcc z`hK!7GmO*B1u`!glcW*Z-6&_5FT5g?!Y6V-$iu`4ulF5?i9ZdU>594pyaF_=ab2zqWk#U zX(#>p!ZdlPtNuyQNpk@u_9Gb_^eY9uaP-4?t?#q>MMYn+b4nBkS*MI3LM)en`{iOe zUCzE@d0<{Tlj`E|5;JSnY@wo5HbwE&)qIoM$e|w}EsA^VC@flx7@M>xTTADrO?$PLHqr6W-@ zpz^H?NVFeS@MTr6+oR2G#qi$uA-x4VVP;mw~7cqBfH+SCOY1mvh z4t>$^t(t-f8E___nF5pFz|{I$PuE8YZk@5RDbvXYe`I7*+-*`#7tj{Pws^^ouGg2@=gc<^O>vgUAcV3MDU25NVwhwlKns6%W^mN?VP^} z6+x_Wz}pDAph3jL%0TL4^ndaB+)$p20%a@49EfOmTgHuR=k6){)sAV6v2k5 zn{d&gV=|Uh(CYV9zXEf>Z;61ImCZ(new-G3T8D;cF=@~=l&tvWpsTrx2Rzk+EIxS> zM(-*PzNlga0p{*%Sp5(n=k~~rKonifB}pTu1)A`aBU~G>A23We+83#>p?J37`MblE zpkLh6!v%E;*~IT`9&NGRyQFW1Ilw2nCg%(f)MJ2~ixcym9OyB=OwBr4Gon1_0d*b( zu25kk!bCv$Amy(?^v!*w53qz~Zf&#mT0fZ!p6 z9se%_kH)*Deks5ir3K6bP+8?RmXA5o<*jfJR}22MoNSwHW(N2kkhKTg(HeH#NouG= zqaM`OMf3NLn)URP0ud~~D}^End5nO1N)O0j*c5iYtqrA?@x?QN-w}sltcbXLVYJi_ z`FelcsXfI~6I5suE+E^jO$TF1ILnOYvdj0t(y%$<1wEJM8zI1Rx=Zu`^U%4IBo>Uc zyV(4Kmls3XdP*$t%dAHg1o(eunN0s_%>hj3G{N1r%aJAzNV!DfZ%dbx!TdjY=6K@E%3v(X&1YAK!-EK^ZZG`606%ilN>ZOBi~|1yzQQ$L From 419a1f067882ebc0e36669461dd96ce83bf02feb Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Thu, 7 Aug 2014 22:36:22 +0300 Subject: [PATCH 18/87] [Update] README. --- README.md | 107 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 88 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index bb3498c..fb8cda6 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # RSDayFlow - - - - -
+

+ Sample +

+ +iOS 7 Calendar with Infinite Scrolling. Only need 4 lines of code to set up. > [RSDayFlow](https://github.com/ruslanskorb/RSDayFlow) is a slim fork of [DayFlow](https://github.com/evadne/DayFlow) with updates and extensions: @@ -13,29 +13,98 @@ * Design like iOS 7 * Some other updates -iOS 7 Date Picker + Infinite Scrolling. +## Installation -## Play +[CocoaPods](http://cocoapods.org) is the recommended method of installing RSDayFlow. Simply add the following line to your `Podfile`: -Look at the [Sample App](https://github.com/ruslanskorb/RSDayFlow-Sample). Have fun. Make it faster. Fork and send pull requests. Figure out hooks for customization. +#### Podfile + +```ruby +pod 'RSDayFlow' +``` -## Use +## Basic Usage -Plop `RSDFDatePickerView` in, and implement the one method in ``: +Import the class header. - - (void)datePickerView:(RSDFDatePickerView *)view didSelectDate:(NSDate *)date; +``` objective-c +#import "RSDFDatePickerView.h" +``` + +Just create your date picker view and set a delegate / a data source if needed. + +``` objective-c +- (void) viewDidLoad +{ + [super viewDidLoad]; -Or implement the one method in `RSDFDatePickerViewDataSource`: + RSDFDatePickerView *datePickerView = [[RSDFDatePickerView alloc] initWithFrame:self.view.bounds]; + datePickerView.delegate = self; + datePickerView.dataSource = self; + [self.view addSubview:datePickerView]; +} +``` + +## Delegate (optional) + +`RSDFDatePickerView` provides one delegate method `didSelectDate`. It gets called when a user click on a specific date. To use it, implement the delegate in your view controller. + +```objective-c +@interface ViewController () +``` + +Then implement the delegate function. + +```objective-c +// Prints out the selected date. +- (void)datePickerView:(RSDFDatePickerView *)view didSelectDate:(NSDate *)date +{ + NSLog(@"%@", [date description]); +} +``` + +## DataSource (optional) + +`RSDFDatePickerView` provides one data source method `datePickerViewMarkedDates`. It uses to mark dates by using markers of different colors like iOS 7 Calendar app. To use it, implement the data source in your view controller. + +```objective-c +@interface ViewController () +``` + +Then implement the data source function. + +```objective-c +// Returns dates to mark. +- (NSDictionary *)datePickerViewMarkedDates:(RSDFDatePickerView *)view +{ + NSDate *today = [NSDate date]; + NSNumber *isCompletedAllTasks = @(NO); + NSDictionary *dates = @{today: isCompletedAllTasks}; + return markedDates; +} +``` + +## Coming Soon + +- Make the code more documented +- Make every view maximum customizable + +- If you would like to request a new feature, feel free to raise as an issue. + +## Demo + +Look at the [Sample App](https://github.com/ruslanskorb/RSDayFlow-Sample). Have fun. Make it faster. Fork and send pull requests. Figure out hooks for customization. - - (NSDictionary *)datePickerViewMarkedDates:(RSDFDatePickerView *)view; -That pretty much sums up what it does. +## Contact -## Licensing +Ruslan Skorb -This project is in the public domain. You can embed it in works for hire or use it for evil. Attribution by linking to the [project page](https://github.com/ruslanskorb/RSDayFlow) and chocolate delivery is appreciated. +- http://github.com/ruslanskorb +- http://twitter.com/ruslanskorb +- http://lnkd.in/gsBbvb +- ruslan.skorb@gmail.com -## Credits +## License -* [Evadne Wu](http://radi.ws) -* [Ruslan Skorb](http://lnkd.in/gsBbvb) \ No newline at end of file +This project is is available under the MIT license. See the LICENSE file for more info. Attribution by linking to the [project page](https://github.com/ruslanskorb/RSDayFlow) is appreciated. From 6dae6e122084d857d9db3f751e197dafd6452ad6 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Mon, 11 Aug 2014 21:58:56 +0300 Subject: [PATCH 19/87] [Fix] Perform selector of the delegate / the data source. --- RSDayFlow/RSDFDatePickerView.h | 7 +++++-- RSDayFlow/RSDFDatePickerView.m | 27 +++++++++++++++------------ 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/RSDayFlow/RSDFDatePickerView.h b/RSDayFlow/RSDFDatePickerView.h index d32a1c5..d88df6c 100644 --- a/RSDayFlow/RSDFDatePickerView.h +++ b/RSDayFlow/RSDFDatePickerView.h @@ -12,15 +12,18 @@ @end -@protocol RSDFDatePickerViewDelegate +@protocol RSDFDatePickerViewDelegate + +@optional - (void)datePickerView:(RSDFDatePickerView *)view didSelectDate:(NSDate *)date; @end -@protocol RSDFDatePickerViewDataSource +@protocol RSDFDatePickerViewDataSource @optional + - (NSDictionary *)datePickerViewMarkedDates:(RSDFDatePickerView *)view; @end diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index 0645801..0ce4eba 100644 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -376,14 +376,16 @@ - (RSDFDatePickerDayCell *)collectionView:(UICollectionView *)collectionView cel weekday = [self.calendar components:NSWeekdayCalendarUnit fromDate:cellDate].weekday; cell.dayOff = (weekday == 1) || (weekday == 7); - NSDictionary *markedDates = [self.dataSource datePickerViewMarkedDates:self]; - NSNumber *markedDateState = [markedDates objectForKey:cellDate]; - if (markedDateState) { - cell.marked = YES; - cell.completed = [markedDateState boolValue]; - } else { - cell.marked = NO; - cell.completed = NO; + if ([self.dataSource respondsToSelector:@selector(datePickerViewMarkedDates:)]) { + NSDictionary *markedDates = [self.dataSource datePickerViewMarkedDates:self]; + NSNumber *markedDateState = [markedDates objectForKey:cellDate]; + if (markedDateState) { + cell.marked = YES; + cell.completed = [markedDateState boolValue]; + } else { + cell.marked = NO; + cell.completed = NO; + } } cell.today = ([cellDate compare:_today] == NSOrderedSame) ? YES : NO; @@ -410,10 +412,11 @@ - (BOOL) collectionView:(UICollectionView *)collectionView shouldSelectItemAtInd - (void) collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { - RSDFDatePickerDayCell *cell = ((RSDFDatePickerDayCell *)[collectionView cellForItemAtIndexPath:indexPath]); - NSDate *selectedDate = cell ? [self.calendar dateFromComponents:[self dateComponentsFromPickerDate:cell.date]] : nil; - [self.delegate datePickerView:self didSelectDate:selectedDate]; - [self.collectionView reloadData]; + if ([self.delegate respondsToSelector:@selector(datePickerView:didSelectDate:)]) { + RSDFDatePickerDayCell *cell = ((RSDFDatePickerDayCell *)[collectionView cellForItemAtIndexPath:indexPath]); + NSDate *selectedDate = cell ? [self.calendar dateFromComponents:[self dateComponentsFromPickerDate:cell.date]] : nil; + [self.delegate datePickerView:self didSelectDate:selectedDate]; + } } - (UICollectionReusableView *) collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath From 93056359ea9f04e05424987c4c0700e3b50a012a Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Mon, 11 Aug 2014 23:33:41 +0300 Subject: [PATCH 20/87] [Fix] Configuring the calendar. currentCalendar -> NSGregorianCalendar --- RSDayFlow/RSDFDatePickerView.m | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index 0ce4eba..7c3425d 100644 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -37,7 +37,8 @@ - (void)configureCalendar { _calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; - NSDate *now = [_calendar dateFromComponents:[_calendar components:NSYearCalendarUnit|NSMonthCalendarUnit fromDate:[NSDate date]]]; + NSDateComponents *nowYearMonthComponents = [_calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit) fromDate:[NSDate date]]; + NSDate *now = [_calendar dateFromComponents:nowYearMonthComponents]; _fromDate = [self pickerDateFromDate:[_calendar dateByAddingComponents:((^{ NSDateComponents *components = [NSDateComponents new]; @@ -51,10 +52,8 @@ - (void)configureCalendar return components; })()) toDate:now options:0]]; - - NSCalendar *calendar = [NSCalendar currentCalendar]; - NSDateComponents *components = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]]; - _today = [calendar dateFromComponents:components];; + NSDateComponents *todayYearMonthDayComponents = [_calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]]; + _today = [_calendar dateFromComponents:todayYearMonthDayComponents]; } - (id)initWithCoder:(NSCoder *)aDecoder From c2cfc7d88acfc402df2d8b8d609c18d55d81f557 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 12 Aug 2014 01:51:26 +0300 Subject: [PATCH 21/87] [Add] Scroll to today. --- RSDayFlow/RSDFDatePickerView.h | 1 + RSDayFlow/RSDFDatePickerView.m | 53 ++++++++++++++++++++++++++-------- 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/RSDayFlow/RSDFDatePickerView.h b/RSDayFlow/RSDFDatePickerView.h index d88df6c..c82eb94 100644 --- a/RSDayFlow/RSDFDatePickerView.h +++ b/RSDayFlow/RSDFDatePickerView.h @@ -8,6 +8,7 @@ @property (nonatomic, readwrite, weak) id delegate; @property (nonatomic, readwrite, weak) id dataSource; +- (void)scrollToToday:(BOOL)animated; - (void)reloadData; @end diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index 7c3425d..27c3c3b 100644 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -85,18 +85,7 @@ - (void)layoutSubviews self.collectionView.frame = [self collectionViewFrame]; if (!self.collectionView.superview) { - if (self.collectionView.numberOfSections > 0) { - RSDFDatePickerDate todayPickerDate = [self pickerDateFromDate:_today]; - NSInteger section = self.collectionView.numberOfSections / 2; - NSDate *firstDayInMonth = [self dateForFirstDayInSection:section]; - NSUInteger weekday = [self.calendar components:NSWeekdayCalendarUnit fromDate:firstDayInMonth].weekday; - - // weekday start from 1 and include first day of month - NSInteger item = weekday + todayPickerDate.day - 2; - - NSIndexPath *cellIndexPath = [NSIndexPath indexPathForItem:item inSection:section]; - [self.collectionView scrollToItemAtIndexPath:cellIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:NO]; - } + [self scrollToToday:NO]; [self addSubview:self.collectionView]; } } @@ -307,6 +296,46 @@ - (void)shiftDatesByComponents:(NSDateComponents *)components }]; } +- (void)scrollToToday:(BOOL)animated +{ + UICollectionView *cv = self.collectionView; + UICollectionViewFlowLayout *cvLayout = (UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout; + + NSArray *visibleCells = [self.collectionView visibleCells]; + if (![visibleCells count]) + return; + + NSDateComponents *nowYearMonthComponents = [_calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit) fromDate:[NSDate date]]; + NSDate *now = [_calendar dateFromComponents:nowYearMonthComponents]; + + _fromDate = [self pickerDateFromDate:[_calendar dateByAddingComponents:((^{ + NSDateComponents *components = [NSDateComponents new]; + components.month = -6; + return components; + })()) toDate:now options:0]]; + + _toDate = [self pickerDateFromDate:[_calendar dateByAddingComponents:((^{ + NSDateComponents *components = [NSDateComponents new]; + components.month = 6; + return components; + })()) toDate:now options:0]]; + + [cv reloadData]; + [cvLayout invalidateLayout]; + [cvLayout prepareLayout]; + + RSDFDatePickerDate todayPickerDate = [self pickerDateFromDate:_today]; + NSInteger section = self.collectionView.numberOfSections / 2; + NSDate *firstDayInMonth = [self dateForFirstDayInSection:section]; + NSUInteger weekday = [self.calendar components:NSWeekdayCalendarUnit fromDate:firstDayInMonth].weekday; + + // weekday start from 1 and include first day of month + NSInteger item = weekday + todayPickerDate.day - 2; + + NSIndexPath *cellIndexPath = [NSIndexPath indexPathForItem:item inSection:section]; + [self.collectionView scrollToItemAtIndexPath:cellIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:animated]; +} + - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { return [self.calendar components:NSMonthCalendarUnit fromDate:[self dateFromPickerDate:self.fromDate] toDate:[self dateFromPickerDate:self.toDate] options:0].month; From 701e6d94ec132c356caf8e74e0a03fed186deebe Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 12 Aug 2014 13:22:02 +0300 Subject: [PATCH 22/87] [Add] Documentation on the header files. --- RSDayFlow/RSDFDatePickerCollectionView.h | 17 ++++++ RSDayFlow/RSDFDatePickerDayCell.h | 51 +++++++++++++++-- RSDayFlow/RSDFDatePickerDaysOfWeekView.h | 3 + RSDayFlow/RSDFDatePickerMonthHeader.h | 25 ++++++++- RSDayFlow/RSDFDatePickerView.h | 70 ++++++++++++++++++++++++ RSDayFlow/RSDayFlow.h | 8 ++- 6 files changed, 164 insertions(+), 10 deletions(-) diff --git a/RSDayFlow/RSDFDatePickerCollectionView.h b/RSDayFlow/RSDFDatePickerCollectionView.h index 9045311..e56c717 100644 --- a/RSDayFlow/RSDFDatePickerCollectionView.h +++ b/RSDayFlow/RSDFDatePickerCollectionView.h @@ -2,14 +2,31 @@ @class RSDFDatePickerCollectionView; +/** + The `RSDFDatePickerCollectionViewDelegate` protocol defines the message sent to a collection view delegate when the collection view will layout subviews. + */ @protocol RSDFDatePickerCollectionViewDelegate +///--------------------------------- +/// @name Supporting Layout Subviews +///--------------------------------- + +/** + Tells the delegate that the collection view will layout subviews. + + @param pickerCollectionView The collection view which will layout subviews. + */ - (void) pickerCollectionViewWillLayoutSubviews:(RSDFDatePickerCollectionView *)pickerCollectionView; @end @interface RSDFDatePickerCollectionView : UICollectionView +/** + The receiver's delegate. + + @discussion A `RSDFDatePickerCollectionView` delegate uses to support layout subviews in the date picker view. + */ @property (nonatomic, assign) id delegate; @end diff --git a/RSDayFlow/RSDFDatePickerDayCell.h b/RSDayFlow/RSDFDatePickerDayCell.h index 74b1721..7810d56 100644 --- a/RSDayFlow/RSDFDatePickerDayCell.h +++ b/RSDayFlow/RSDFDatePickerDayCell.h @@ -1,15 +1,54 @@ #import #import "RSDayFlow.h" +/** + `RSDFDatePickerDayCell` is a cell which used to display a day in the date picker view. + */ @interface RSDFDatePickerDayCell : UICollectionViewCell -@property (nonatomic, readwrite, assign) RSDFDatePickerDate date; -@property (nonatomic, readonly, strong) UILabel *dateLabel; +///------------------------- +/// @name Accessing Subviews +///------------------------- -@property (nonatomic, getter = isEnabled) BOOL enabled; -@property (nonatomic, getter = isDayOff) BOOL dayOff; -@property (nonatomic, getter = isMarked) BOOL marked; +/** + The label showing the cell's date. + */ +@property (nonatomic, readonly, strong) UILabel *dateLabel; + +///----------------------------------- +/// @name Accessing the Day Attributes +///----------------------------------- + +/** + A date which corresponds to the current cell. + */ +@property (nonatomic, readwrite, assign) RSDFDatePickerDate date; + +/** + A Boolean value that determines whether the cell's day is enabled. + + @discussion Cells with inactive days do not display the content. +*/ +@property (nonatomic, getter = isEnabled) BOOL enabled; + +/** + A Boolean value that determines whether the cell's day is day off. + */ +@property (nonatomic, getter = isDayOff) BOOL dayOff; + +/** + A Boolean value that determines whether the cell have a mark. + */ +@property (nonatomic, getter = isMarked) BOOL marked; + +/** + A Boolean value that determines whether all tasks for the cell's day are completed. + */ @property (nonatomic, getter = isCompleted) BOOL completed; -@property (nonatomic, getter = isToday) BOOL today; + +/** + A Boolean value that determines whether the cell represents the current day. + */ +@property (nonatomic, getter = isToday) BOOL today; @end diff --git a/RSDayFlow/RSDFDatePickerDaysOfWeekView.h b/RSDayFlow/RSDFDatePickerDaysOfWeekView.h index 8d17150..b2f43f6 100644 --- a/RSDayFlow/RSDFDatePickerDaysOfWeekView.h +++ b/RSDayFlow/RSDFDatePickerDaysOfWeekView.h @@ -1,5 +1,8 @@ #import +/** + `RSDFDatePickerDaysOfWeekView` is a view with labels for each day of the week. + */ @interface RSDFDatePickerDaysOfWeekView : UIView @end diff --git a/RSDayFlow/RSDFDatePickerMonthHeader.h b/RSDayFlow/RSDFDatePickerMonthHeader.h index 2f6ec29..d67c3cc 100644 --- a/RSDayFlow/RSDFDatePickerMonthHeader.h +++ b/RSDayFlow/RSDFDatePickerMonthHeader.h @@ -1,11 +1,32 @@ #import #import "RSDayFlow.h" +/** + `RSDFDatePickerMonthHeader` is a reusable view which used to display a month and year in the date picker view. + */ @interface RSDFDatePickerMonthHeader : UICollectionReusableView -@property (nonatomic, readwrite, assign) RSDFDatePickerDate date; -@property (nonatomic, readonly, strong) UILabel *dateLabel; +///------------------------- +/// @name Accessing Subviews +///------------------------- +/** + The label showing the view's date. + */ +@property (nonatomic, readonly, strong) UILabel *dateLabel; + +///------------------------------------- +/// @name Accessing the Month Attributes +///------------------------------------- + +/** + A date which corresponds to the current view. + */ +@property (nonatomic, readwrite, assign) RSDFDatePickerDate date; + +/** + A Boolean value that determines whether the view represents the current month. + */ @property (nonatomic, getter = isCurrentMonth) BOOL currentMonth; @end diff --git a/RSDayFlow/RSDFDatePickerView.h b/RSDayFlow/RSDFDatePickerView.h index c82eb94..4d31942 100644 --- a/RSDayFlow/RSDFDatePickerView.h +++ b/RSDayFlow/RSDFDatePickerView.h @@ -3,28 +3,98 @@ @protocol RSDFDatePickerViewDelegate; @protocol RSDFDatePickerViewDataSource; +/** + `RSDFDatePickerView` is a calendar view with infinity scrolling. +*/ @interface RSDFDatePickerView : UIView +///----------------------------- +/// @name Accessing the Delegate +///----------------------------- + +/** + The receiver's delegate. + + @discussion A `RSDFDatePickerView` delegate responds to message sent by tapping on date in the date picker view. + */ @property (nonatomic, readwrite, weak) id delegate; + +///-------------------------------- +/// @name Accessing the Data Source +///-------------------------------- + +/** + The receiver's data source. + + @discussion A `RSDFDatePickerView` data source provides dates to mark in the date picker view. + */ + @property (nonatomic, readwrite, weak) id dataSource; +///----------------------------------- +/// @name Scrolling to the Current Day +///----------------------------------- + +/** + Scrolls the date picker view to the current day. + + @param animated YES if you want to animate the change in position, NO if it should be immediate. + */ + - (void)scrollToToday:(BOOL)animated; + +///------------------------- +/// @name Reloading the Data +///------------------------- + +/** + Reloads all of the data for the date picker view. + + @discussion Discard the dataSource and delegate data and requery as necessary. + */ - (void)reloadData; @end +/** + The `RSDFDatePickerViewDelegate` protocol defines the message sent to a date picker view delegate when date is tapped. + */ @protocol RSDFDatePickerViewDelegate +///----------------------------------- +/// @name Responding to Date Selection +///----------------------------------- + @optional +/** + Tells the delegate that the user did select a date. + + @param view The view whose date was selected. + @param date The selected date. + */ - (void)datePickerView:(RSDFDatePickerView *)view didSelectDate:(NSDate *)date; @end +/** + The `RSDFDatePickerViewDataSource` protocol is adopted by an object that provides dates to mark in the date picker view. + */ @protocol RSDFDatePickerViewDataSource +///------------------------------ +/// @name Providing Dates to Mark +///------------------------------ + @optional +/** + Provides dates to mark for the data source. + + @param view The view to whom dates are provided. + + @return The dictionary that contains dates (as keys) and completeness of tasks on these days (as objects). + */ - (NSDictionary *)datePickerViewMarkedDates:(RSDFDatePickerView *)view; @end diff --git a/RSDayFlow/RSDayFlow.h b/RSDayFlow/RSDayFlow.h index ac3a728..431f683 100644 --- a/RSDayFlow/RSDayFlow.h +++ b/RSDayFlow/RSDayFlow.h @@ -1,7 +1,11 @@ +/** + `RSDayFlow` is an iOS 7 Calendar with Infinite Scrolling. + */ + +#import "RSDFDatePickerView.h" + typedef struct { NSUInteger year; NSUInteger month; NSUInteger day; } RSDFDatePickerDate; - -#import "RSDFDatePickerView.h" From 405ef40e4d2a5519e2b54b570d44fa5e7f2145e8 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Wed, 13 Aug 2014 15:00:49 +0300 Subject: [PATCH 23/87] [Add] More localizations. --- RSDayFlow/RSDFDatePickerDaysOfWeekView.h | 8 ++ RSDayFlow/RSDFDatePickerDaysOfWeekView.m | 126 +++++++++++------------ RSDayFlow/RSDFDatePickerView.m | 11 +- 3 files changed, 75 insertions(+), 70 deletions(-) diff --git a/RSDayFlow/RSDFDatePickerDaysOfWeekView.h b/RSDayFlow/RSDFDatePickerDaysOfWeekView.h index b2f43f6..0d218e1 100644 --- a/RSDayFlow/RSDFDatePickerDaysOfWeekView.h +++ b/RSDayFlow/RSDFDatePickerDaysOfWeekView.h @@ -5,4 +5,12 @@ */ @interface RSDFDatePickerDaysOfWeekView : UIView +/** + Designated initializer. Initializes and returns a newly allocated view object with the specified frame rectangle and the specified calendar. + + @param frame The frame rectangle for the view, measured in points. + @param calendar The calendar for days of the week. + */ +- (instancetype)initWithFrame:(CGRect)frame calendar:(NSCalendar *)calendar; + @end diff --git a/RSDayFlow/RSDFDatePickerDaysOfWeekView.m b/RSDayFlow/RSDFDatePickerDaysOfWeekView.m index a7d9b37..68b57a0 100644 --- a/RSDayFlow/RSDFDatePickerDaysOfWeekView.m +++ b/RSDayFlow/RSDFDatePickerDaysOfWeekView.m @@ -1,7 +1,26 @@ #import "RSDFDatePickerDaysOfWeekView.h" +#import "NSCalendar+RSDFAdditions.h" + +@interface RSDFDatePickerDaysOfWeekView () + +@property (strong, nonatomic) NSCalendar *calendar; + +@end @implementation RSDFDatePickerDaysOfWeekView +#pragma mark - Lifecycle + +- (instancetype)initWithFrame:(CGRect)frame calendar:(NSCalendar *)calendar +{ + self = [super initWithFrame:frame]; + if (self) { + _calendar = calendar; + [self commonInitializer]; + } + return self; +} + - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; @@ -20,83 +39,60 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder return self; } +#pragma mark - Custom Accessors + +- (NSCalendar *)calendar +{ + if (!_calendar) { + _calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; + } + return _calendar; +} + +#pragma mark - Private + - (void)commonInitializer { self.backgroundColor = [UIColor colorWithRed:248.0/255 green:248.0/255 blue:248.0/255 alpha:1.0]; - UIFont *font = [UIFont fontWithName:@"HelveticaNeue-Light" size:10.0]; - UIColor *dayColor = [UIColor blackColor]; - UIColor *dayOffColor = [UIColor colorWithRed:150.0/255 green:150.0/255 blue:150.0/255 alpha:1.0]; - CGFloat yCenter = CGRectGetHeight(self.bounds) / 2; + UIColor *weekdayLabelBackgroundColor = [UIColor clearColor]; + UIFont *weekdayLabelFont = [UIFont fontWithName:@"HelveticaNeue-Light" size:10.0]; + UIColor *weekdayLabelDayTextColor = [UIColor blackColor]; + UIColor *weekdayLabelDayOffTextColor = [UIColor colorWithRed:150.0/255 green:150.0/255 blue:150.0/255 alpha:1.0]; // Hard key these things. - // 44 * 7 + 2 * 6 = 320; from collectionViewLayout of RSDFDatePickerView + // 44 * 7 + 2 * 6 = 320; from collectionViewLayout of RSDFDatePickerView CGFloat dayItemWidth = 44.0f; CGFloat minimumInteritemSpacing = 2.0f; - UILabel *sunday = [[UILabel alloc] init]; - sunday.font = font; - sunday.text = @"S"; - sunday.textColor = dayOffColor; - [sunday sizeToFit]; - CGFloat xCenter = dayItemWidth / 2; - sunday.center = CGPointMake(xCenter, yCenter); - [self addSubview:sunday]; - - UILabel *monday = [[UILabel alloc] init]; - monday.font = font; - monday.text = @"M"; - monday.textColor = dayColor; - [monday sizeToFit]; - xCenter += (dayItemWidth + minimumInteritemSpacing); - monday.center = CGPointMake(xCenter, yCenter); - [self addSubview:monday]; - - UILabel *tuesday = [[UILabel alloc] init]; - tuesday.font = font; - tuesday.text = @"T"; - tuesday.textColor = dayColor; - [tuesday sizeToFit]; - xCenter += (dayItemWidth + minimumInteritemSpacing); - tuesday.center = CGPointMake(xCenter, yCenter); - [self addSubview:tuesday]; - - UILabel *wednesday = [[UILabel alloc] init]; - wednesday.font = font; - wednesday.text = @"W"; - wednesday.textColor = dayColor; - [wednesday sizeToFit]; - xCenter += (dayItemWidth + minimumInteritemSpacing); - wednesday.center = CGPointMake(xCenter, yCenter); - [self addSubview:wednesday]; - - UILabel *thursday = [[UILabel alloc] init]; - thursday.font = font; - thursday.text = @"T"; - thursday.textColor = dayColor; - [thursday sizeToFit]; - xCenter += (dayItemWidth + minimumInteritemSpacing); - thursday.center = CGPointMake(xCenter, yCenter); - [self addSubview:thursday]; + CGFloat yCenter = CGRectGetHeight(self.bounds) / 2; + __block CGFloat xCenter = dayItemWidth / 2; - UILabel *friday = [[UILabel alloc] init]; - friday.font = font; - friday.text = @"F"; - friday.textColor = dayColor; - [friday sizeToFit]; - xCenter += (dayItemWidth + minimumInteritemSpacing); - friday.center = CGPointMake(xCenter, yCenter); - [self addSubview:friday]; + NSDateFormatter *dateFormatter = [self.calendar df_dateFormatterNamed:@"calendarDaysOfWeekView" withConstructor:^{ + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + dateFormatter.calendar = self.calendar; + dateFormatter.locale = [NSLocale currentLocale]; + return dateFormatter; + }]; - UILabel *saturday = [[UILabel alloc] init]; - saturday.font = font; - saturday.text = @"S"; - saturday.textColor = dayOffColor; - [saturday sizeToFit]; - xCenter += (dayItemWidth + minimumInteritemSpacing); - saturday.center = CGPointMake(xCenter, yCenter); - [self addSubview:saturday]; + NSArray *weekdaySymbols = [dateFormatter veryShortStandaloneWeekdaySymbols]; + [weekdaySymbols enumerateObjectsUsingBlock:^(NSString *weekdaySymbol, NSUInteger idx, BOOL *stop) { + UILabel *weekdayLabel = [[UILabel alloc] init]; + weekdayLabel.backgroundColor = weekdayLabelBackgroundColor; + weekdayLabel.font = weekdayLabelFont; + if ( (idx != 0) && (idx != 6) ) { + weekdayLabel.textColor = weekdayLabelDayTextColor; + } else { + weekdayLabel.textColor = weekdayLabelDayOffTextColor; + } + weekdayLabel.text = weekdaySymbol; + [weekdayLabel sizeToFit]; + weekdayLabel.center = CGPointMake(xCenter, yCenter); + [self addSubview:weekdayLabel]; + + xCenter += (dayItemWidth + minimumInteritemSpacing); + }]; } @end diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index 27c3c3b..c92804f 100644 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -116,7 +116,7 @@ - (CGRect)daysOfWeekViewFrame - (UIView *)daysOfWeekView { if (!_daysOfWeekView) { - _daysOfWeekView = [[RSDFDatePickerDaysOfWeekView alloc] initWithFrame:[self daysOfWeekViewFrame]]; + _daysOfWeekView = [[RSDFDatePickerDaysOfWeekView alloc] initWithFrame:[self daysOfWeekViewFrame] calendar:self.calendar]; } return _daysOfWeekView; @@ -454,10 +454,9 @@ - (UICollectionReusableView *) collectionView:(UICollectionView *)collectionView RSDFDatePickerMonthHeader *monthHeader = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:DFDatePickerViewMonthHeaderIdentifier forIndexPath:indexPath]; NSDateFormatter *dateFormatter = [self.calendar df_dateFormatterNamed:@"calendarMonthHeader" withConstructor:^{ - NSDateFormatter *dateFormatter = [NSDateFormatter new]; + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; dateFormatter.calendar = self.calendar; - dateFormatter.dateFormat = @"MMM yyyy"; - dateFormatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US"]; + dateFormatter.locale = [NSLocale currentLocale]; return dateFormatter; }]; @@ -465,7 +464,9 @@ - (UICollectionReusableView *) collectionView:(UICollectionView *)collectionView RSDFDatePickerDate date = [self pickerDateFromDate:formattedDate]; monthHeader.date = date; - monthHeader.dateLabel.text = [[dateFormatter stringFromDate:formattedDate] uppercaseString]; + + NSString *monthString = [dateFormatter shortStandaloneMonthSymbols][date.month - 1]; + monthHeader.dateLabel.text = [[NSString stringWithFormat:@"%@ %lu", monthString, (unsigned long)date.year] uppercaseString]; RSDFDatePickerDate today = [self pickerDateFromDate:_today]; if ( (today.month == date.month) && (today.year == date.year) ) { From 2752313fb28efa3011fd115defe3441b7c2e9568 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Thu, 14 Aug 2014 20:06:03 +0300 Subject: [PATCH 24/87] [Add] Support for different order of days of the week for different locales. --- RSDayFlow/RSDFDatePickerDaysOfWeekView.m | 17 ++++++++++++++--- RSDayFlow/RSDFDatePickerView.m | 5 +++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/RSDayFlow/RSDFDatePickerDaysOfWeekView.m b/RSDayFlow/RSDFDatePickerDaysOfWeekView.m index 68b57a0..0795f51 100644 --- a/RSDayFlow/RSDFDatePickerDaysOfWeekView.m +++ b/RSDayFlow/RSDFDatePickerDaysOfWeekView.m @@ -72,16 +72,27 @@ - (void)commonInitializer NSDateFormatter *dateFormatter = [self.calendar df_dateFormatterNamed:@"calendarDaysOfWeekView" withConstructor:^{ NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; dateFormatter.calendar = self.calendar; - dateFormatter.locale = [NSLocale currentLocale]; + dateFormatter.locale = [self.calendar locale]; return dateFormatter; }]; NSArray *weekdaySymbols = [dateFormatter veryShortStandaloneWeekdaySymbols]; - [weekdaySymbols enumerateObjectsUsingBlock:^(NSString *weekdaySymbol, NSUInteger idx, BOOL *stop) { + NSArray *reorderedWeekdaySymbols = nil; + + // weekday start from 1 + NSUInteger firstWeekdayIndex = [self.calendar firstWeekday] - 1; + if (firstWeekdayIndex > 0) { + reorderedWeekdaySymbols = [[weekdaySymbols subarrayWithRange:NSMakeRange(firstWeekdayIndex, [weekdaySymbols count] - firstWeekdayIndex)] + arrayByAddingObjectsFromArray:[weekdaySymbols subarrayWithRange:NSMakeRange(0, firstWeekdayIndex)]]; + } else { + reorderedWeekdaySymbols = weekdaySymbols; + } + + [reorderedWeekdaySymbols enumerateObjectsUsingBlock:^(NSString *weekdaySymbol, NSUInteger idx, BOOL *stop) { UILabel *weekdayLabel = [[UILabel alloc] init]; weekdayLabel.backgroundColor = weekdayLabelBackgroundColor; weekdayLabel.font = weekdayLabelFont; - if ( (idx != 0) && (idx != 6) ) { + if ([weekdaySymbols indexOfObjectIdenticalTo:weekdaySymbol] != 0 && [weekdaySymbols indexOfObjectIdenticalTo:weekdaySymbol] != 6) { weekdayLabel.textColor = weekdayLabelDayTextColor; } else { weekdayLabel.textColor = weekdayLabelDayOffTextColor; diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index c92804f..6f5e878 100644 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -36,6 +36,7 @@ @implementation RSDFDatePickerView - (void)configureCalendar { _calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; + _calendar.locale = [NSLocale currentLocale]; NSDateComponents *nowYearMonthComponents = [_calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit) fromDate:[NSDate date]]; NSDate *now = [_calendar dateFromComponents:nowYearMonthComponents]; @@ -391,7 +392,7 @@ - (RSDFDatePickerDayCell *)collectionView:(UICollectionView *)collectionView cel NSDate *cellDate = [self.calendar dateByAddingComponents:((^{ NSDateComponents *dateComponents = [NSDateComponents new]; - dateComponents.day = indexPath.item - (weekday - 1); + dateComponents.day = indexPath.item - (weekday - self.calendar.firstWeekday); return dateComponents; })()) toDate:firstDayInMonth options:0]; RSDFDatePickerDate cellPickerDate = [self pickerDateFromDate:cellDate]; @@ -456,7 +457,7 @@ - (UICollectionReusableView *) collectionView:(UICollectionView *)collectionView NSDateFormatter *dateFormatter = [self.calendar df_dateFormatterNamed:@"calendarMonthHeader" withConstructor:^{ NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; dateFormatter.calendar = self.calendar; - dateFormatter.locale = [NSLocale currentLocale]; + dateFormatter.locale = [self.calendar locale]; return dateFormatter; }]; From 32484497f9e05cacee2355e5f6bf4ad5bab913ff Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 19 Aug 2014 12:39:47 +0300 Subject: [PATCH 25/87] [Update] Reformatting LICENSE. --- LICENSE | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/LICENSE b/LICENSE index 484e78d..5cad24d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,20 @@ Copyright (c) 2013 Evadne Wu, http://radi.ws/ Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. From 225a53d06e6790c012a1847e027eee50bb2e7430 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 19 Aug 2014 12:55:47 +0300 Subject: [PATCH 26/87] [Add] Example. The copy from `https://github.com/ruslanskorb/RSDayFlow-Sample` with minor changes. --- .../project.pbxproj | 525 ++++++++++++++++++ .../AppIcon.appiconset/Contents.json | 23 + .../LaunchImage.launchimage/Contents.json | 23 + Example/RSDayFlowExample/RSDFAppDelegate.h | 32 ++ Example/RSDayFlowExample/RSDFAppDelegate.m | 72 +++ .../RSDFDatePickerViewController.h | 34 ++ .../RSDFDatePickerViewController.m | 105 ++++ .../RSDayFlowExample-Info.plist | 38 ++ .../RSDayFlowExample-Prefix.pch | 16 + .../en.lproj/InfoPlist.strings | 2 + Example/RSDayFlowExample/main.m | 35 ++ .../RSDayFlowExampleTests-Info.plist | 22 + .../RSDayFlowExampleTests.m | 51 ++ .../en.lproj/InfoPlist.strings | 2 + 14 files changed, 980 insertions(+) create mode 100644 Example/RSDayFlowExample.xcodeproj/project.pbxproj create mode 100644 Example/RSDayFlowExample/Images.xcassets/AppIcon.appiconset/Contents.json create mode 100644 Example/RSDayFlowExample/Images.xcassets/LaunchImage.launchimage/Contents.json create mode 100644 Example/RSDayFlowExample/RSDFAppDelegate.h create mode 100644 Example/RSDayFlowExample/RSDFAppDelegate.m create mode 100755 Example/RSDayFlowExample/RSDFDatePickerViewController.h create mode 100755 Example/RSDayFlowExample/RSDFDatePickerViewController.m create mode 100644 Example/RSDayFlowExample/RSDayFlowExample-Info.plist create mode 100644 Example/RSDayFlowExample/RSDayFlowExample-Prefix.pch create mode 100644 Example/RSDayFlowExample/en.lproj/InfoPlist.strings create mode 100644 Example/RSDayFlowExample/main.m create mode 100644 Example/RSDayFlowExampleTests/RSDayFlowExampleTests-Info.plist create mode 100644 Example/RSDayFlowExampleTests/RSDayFlowExampleTests.m create mode 100644 Example/RSDayFlowExampleTests/en.lproj/InfoPlist.strings diff --git a/Example/RSDayFlowExample.xcodeproj/project.pbxproj b/Example/RSDayFlowExample.xcodeproj/project.pbxproj new file mode 100644 index 0000000..5ff1cfd --- /dev/null +++ b/Example/RSDayFlowExample.xcodeproj/project.pbxproj @@ -0,0 +1,525 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + B8F807C119A34B990047C24B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B8F807C019A34B990047C24B /* Foundation.framework */; }; + B8F807C319A34B9A0047C24B /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B8F807C219A34B9A0047C24B /* CoreGraphics.framework */; }; + B8F807C519A34B9A0047C24B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B8F807C419A34B9A0047C24B /* UIKit.framework */; }; + B8F807CB19A34B9A0047C24B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = B8F807C919A34B9A0047C24B /* InfoPlist.strings */; }; + B8F807CD19A34B9A0047C24B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = B8F807CC19A34B9A0047C24B /* main.m */; }; + B8F807D119A34B9A0047C24B /* RSDFAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = B8F807D019A34B9A0047C24B /* RSDFAppDelegate.m */; }; + B8F807D319A34B9A0047C24B /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B8F807D219A34B9A0047C24B /* Images.xcassets */; }; + B8F807DA19A34B9A0047C24B /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B8F807D919A34B9A0047C24B /* XCTest.framework */; }; + B8F807DB19A34B9A0047C24B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B8F807C019A34B990047C24B /* Foundation.framework */; }; + B8F807DC19A34B9A0047C24B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B8F807C419A34B9A0047C24B /* UIKit.framework */; }; + B8F807E419A34B9A0047C24B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = B8F807E219A34B9A0047C24B /* InfoPlist.strings */; }; + B8F807E619A34B9A0047C24B /* RSDayFlowExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B8F807E519A34B9A0047C24B /* RSDayFlowExampleTests.m */; }; + B8F8080819A34CDC0047C24B /* RSDFDatePickerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B8F8080719A34CDC0047C24B /* RSDFDatePickerViewController.m */; }; + B8F8081819A3502D0047C24B /* NSCalendar+RSDFAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = B8F8080B19A3502D0047C24B /* NSCalendar+RSDFAdditions.m */; }; + B8F8081919A3502D0047C24B /* RSDFDatePickerCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = B8F8080F19A3502D0047C24B /* RSDFDatePickerCollectionView.m */; }; + B8F8081A19A3502D0047C24B /* RSDFDatePickerDayCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B8F8081119A3502D0047C24B /* RSDFDatePickerDayCell.m */; }; + B8F8081B19A3502D0047C24B /* RSDFDatePickerDaysOfWeekView.m in Sources */ = {isa = PBXBuildFile; fileRef = B8F8081319A3502D0047C24B /* RSDFDatePickerDaysOfWeekView.m */; }; + B8F8081C19A3502D0047C24B /* RSDFDatePickerMonthHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = B8F8081519A3502D0047C24B /* RSDFDatePickerMonthHeader.m */; }; + B8F8081D19A3502D0047C24B /* RSDFDatePickerView.m in Sources */ = {isa = PBXBuildFile; fileRef = B8F8081719A3502D0047C24B /* RSDFDatePickerView.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + B8F807DD19A34B9A0047C24B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = B8F807B519A34B990047C24B /* Project object */; + proxyType = 1; + remoteGlobalIDString = B8F807BC19A34B990047C24B; + remoteInfo = RSDayFlowExample; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + B8F807BD19A34B990047C24B /* RSDayFlowExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RSDayFlowExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + B8F807C019A34B990047C24B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + B8F807C219A34B9A0047C24B /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + B8F807C419A34B9A0047C24B /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + B8F807C819A34B9A0047C24B /* RSDayFlowExample-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RSDayFlowExample-Info.plist"; sourceTree = ""; }; + B8F807CA19A34B9A0047C24B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + B8F807CC19A34B9A0047C24B /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + B8F807CE19A34B9A0047C24B /* RSDayFlowExample-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RSDayFlowExample-Prefix.pch"; sourceTree = ""; }; + B8F807CF19A34B9A0047C24B /* RSDFAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RSDFAppDelegate.h; sourceTree = ""; }; + B8F807D019A34B9A0047C24B /* RSDFAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RSDFAppDelegate.m; sourceTree = ""; }; + B8F807D219A34B9A0047C24B /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + B8F807D819A34B9A0047C24B /* RSDayFlowExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RSDayFlowExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + B8F807D919A34B9A0047C24B /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; + B8F807E119A34B9A0047C24B /* RSDayFlowExampleTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RSDayFlowExampleTests-Info.plist"; sourceTree = ""; }; + B8F807E319A34B9A0047C24B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + B8F807E519A34B9A0047C24B /* RSDayFlowExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RSDayFlowExampleTests.m; sourceTree = ""; }; + B8F8080619A34CDC0047C24B /* RSDFDatePickerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSDFDatePickerViewController.h; sourceTree = ""; }; + B8F8080719A34CDC0047C24B /* RSDFDatePickerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSDFDatePickerViewController.m; sourceTree = ""; }; + B8F8080A19A3502D0047C24B /* NSCalendar+RSDFAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSCalendar+RSDFAdditions.h"; sourceTree = ""; }; + B8F8080B19A3502D0047C24B /* NSCalendar+RSDFAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSCalendar+RSDFAdditions.m"; sourceTree = ""; }; + B8F8080D19A3502D0047C24B /* RSDayFlow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSDayFlow.h; sourceTree = ""; }; + B8F8080E19A3502D0047C24B /* RSDFDatePickerCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSDFDatePickerCollectionView.h; sourceTree = ""; }; + B8F8080F19A3502D0047C24B /* RSDFDatePickerCollectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSDFDatePickerCollectionView.m; sourceTree = ""; }; + B8F8081019A3502D0047C24B /* RSDFDatePickerDayCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSDFDatePickerDayCell.h; sourceTree = ""; }; + B8F8081119A3502D0047C24B /* RSDFDatePickerDayCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSDFDatePickerDayCell.m; sourceTree = ""; }; + B8F8081219A3502D0047C24B /* RSDFDatePickerDaysOfWeekView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSDFDatePickerDaysOfWeekView.h; sourceTree = ""; }; + B8F8081319A3502D0047C24B /* RSDFDatePickerDaysOfWeekView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSDFDatePickerDaysOfWeekView.m; sourceTree = ""; }; + B8F8081419A3502D0047C24B /* RSDFDatePickerMonthHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSDFDatePickerMonthHeader.h; sourceTree = ""; }; + B8F8081519A3502D0047C24B /* RSDFDatePickerMonthHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSDFDatePickerMonthHeader.m; sourceTree = ""; }; + B8F8081619A3502D0047C24B /* RSDFDatePickerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSDFDatePickerView.h; sourceTree = ""; }; + B8F8081719A3502D0047C24B /* RSDFDatePickerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSDFDatePickerView.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + B8F807BA19A34B990047C24B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + B8F807C319A34B9A0047C24B /* CoreGraphics.framework in Frameworks */, + B8F807C519A34B9A0047C24B /* UIKit.framework in Frameworks */, + B8F807C119A34B990047C24B /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B8F807D519A34B9A0047C24B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + B8F807DA19A34B9A0047C24B /* XCTest.framework in Frameworks */, + B8F807DC19A34B9A0047C24B /* UIKit.framework in Frameworks */, + B8F807DB19A34B9A0047C24B /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + B8F807B419A34B990047C24B = { + isa = PBXGroup; + children = ( + B8F807C619A34B9A0047C24B /* Classes */, + B8F8080419A34C3C0047C24B /* Vendor */, + B8F807DF19A34B9A0047C24B /* RSDayFlowExampleTests */, + B8F807BF19A34B990047C24B /* Frameworks */, + B8F807BE19A34B990047C24B /* Products */, + ); + sourceTree = ""; + }; + B8F807BE19A34B990047C24B /* Products */ = { + isa = PBXGroup; + children = ( + B8F807BD19A34B990047C24B /* RSDayFlowExample.app */, + B8F807D819A34B9A0047C24B /* RSDayFlowExampleTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + B8F807BF19A34B990047C24B /* Frameworks */ = { + isa = PBXGroup; + children = ( + B8F807C019A34B990047C24B /* Foundation.framework */, + B8F807C219A34B9A0047C24B /* CoreGraphics.framework */, + B8F807C419A34B9A0047C24B /* UIKit.framework */, + B8F807D919A34B9A0047C24B /* XCTest.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + B8F807C619A34B9A0047C24B /* Classes */ = { + isa = PBXGroup; + children = ( + B8F807CF19A34B9A0047C24B /* RSDFAppDelegate.h */, + B8F807D019A34B9A0047C24B /* RSDFAppDelegate.m */, + B8F8080519A34CC00047C24B /* Controllers */, + B8F807D219A34B9A0047C24B /* Images.xcassets */, + B8F807C719A34B9A0047C24B /* Supporting Files */, + ); + name = Classes; + path = RSDayFlowExample; + sourceTree = ""; + }; + B8F807C719A34B9A0047C24B /* Supporting Files */ = { + isa = PBXGroup; + children = ( + B8F807C819A34B9A0047C24B /* RSDayFlowExample-Info.plist */, + B8F807C919A34B9A0047C24B /* InfoPlist.strings */, + B8F807CC19A34B9A0047C24B /* main.m */, + B8F807CE19A34B9A0047C24B /* RSDayFlowExample-Prefix.pch */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + B8F807DF19A34B9A0047C24B /* RSDayFlowExampleTests */ = { + isa = PBXGroup; + children = ( + B8F807E519A34B9A0047C24B /* RSDayFlowExampleTests.m */, + B8F807E019A34B9A0047C24B /* Supporting Files */, + ); + path = RSDayFlowExampleTests; + sourceTree = ""; + }; + B8F807E019A34B9A0047C24B /* Supporting Files */ = { + isa = PBXGroup; + children = ( + B8F807E119A34B9A0047C24B /* RSDayFlowExampleTests-Info.plist */, + B8F807E219A34B9A0047C24B /* InfoPlist.strings */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + B8F8080419A34C3C0047C24B /* Vendor */ = { + isa = PBXGroup; + children = ( + B8F8080919A3502D0047C24B /* RSDayFlow */, + ); + name = Vendor; + sourceTree = ""; + }; + B8F8080519A34CC00047C24B /* Controllers */ = { + isa = PBXGroup; + children = ( + B8F8080619A34CDC0047C24B /* RSDFDatePickerViewController.h */, + B8F8080719A34CDC0047C24B /* RSDFDatePickerViewController.m */, + ); + name = Controllers; + sourceTree = ""; + }; + B8F8080919A3502D0047C24B /* RSDayFlow */ = { + isa = PBXGroup; + children = ( + B8F8080D19A3502D0047C24B /* RSDayFlow.h */, + B8F8081619A3502D0047C24B /* RSDFDatePickerView.h */, + B8F8081719A3502D0047C24B /* RSDFDatePickerView.m */, + B8F8081219A3502D0047C24B /* RSDFDatePickerDaysOfWeekView.h */, + B8F8081319A3502D0047C24B /* RSDFDatePickerDaysOfWeekView.m */, + B8F8080E19A3502D0047C24B /* RSDFDatePickerCollectionView.h */, + B8F8080F19A3502D0047C24B /* RSDFDatePickerCollectionView.m */, + B8F8081419A3502D0047C24B /* RSDFDatePickerMonthHeader.h */, + B8F8081519A3502D0047C24B /* RSDFDatePickerMonthHeader.m */, + B8F8081019A3502D0047C24B /* RSDFDatePickerDayCell.h */, + B8F8081119A3502D0047C24B /* RSDFDatePickerDayCell.m */, + B8F8080A19A3502D0047C24B /* NSCalendar+RSDFAdditions.h */, + B8F8080B19A3502D0047C24B /* NSCalendar+RSDFAdditions.m */, + ); + name = RSDayFlow; + path = ../RSDayFlow; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + B8F807BC19A34B990047C24B /* RSDayFlowExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = B8F807E919A34B9A0047C24B /* Build configuration list for PBXNativeTarget "RSDayFlowExample" */; + buildPhases = ( + B8F807B919A34B990047C24B /* Sources */, + B8F807BA19A34B990047C24B /* Frameworks */, + B8F807BB19A34B990047C24B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = RSDayFlowExample; + productName = RSDayFlowExample; + productReference = B8F807BD19A34B990047C24B /* RSDayFlowExample.app */; + productType = "com.apple.product-type.application"; + }; + B8F807D719A34B9A0047C24B /* RSDayFlowExampleTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = B8F807EC19A34B9A0047C24B /* Build configuration list for PBXNativeTarget "RSDayFlowExampleTests" */; + buildPhases = ( + B8F807D419A34B9A0047C24B /* Sources */, + B8F807D519A34B9A0047C24B /* Frameworks */, + B8F807D619A34B9A0047C24B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + B8F807DE19A34B9A0047C24B /* PBXTargetDependency */, + ); + name = RSDayFlowExampleTests; + productName = RSDayFlowExampleTests; + productReference = B8F807D819A34B9A0047C24B /* RSDayFlowExampleTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + B8F807B519A34B990047C24B /* Project object */ = { + isa = PBXProject; + attributes = { + CLASSPREFIX = RSDF; + LastUpgradeCheck = 0510; + ORGANIZATIONNAME = "Ruslan Skorb"; + TargetAttributes = { + B8F807D719A34B9A0047C24B = { + TestTargetID = B8F807BC19A34B990047C24B; + }; + }; + }; + buildConfigurationList = B8F807B819A34B990047C24B /* Build configuration list for PBXProject "RSDayFlowExample" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = B8F807B419A34B990047C24B; + productRefGroup = B8F807BE19A34B990047C24B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + B8F807BC19A34B990047C24B /* RSDayFlowExample */, + B8F807D719A34B9A0047C24B /* RSDayFlowExampleTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + B8F807BB19A34B990047C24B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B8F807CB19A34B9A0047C24B /* InfoPlist.strings in Resources */, + B8F807D319A34B9A0047C24B /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B8F807D619A34B9A0047C24B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B8F807E419A34B9A0047C24B /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + B8F807B919A34B990047C24B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B8F8081C19A3502D0047C24B /* RSDFDatePickerMonthHeader.m in Sources */, + B8F807CD19A34B9A0047C24B /* main.m in Sources */, + B8F8081D19A3502D0047C24B /* RSDFDatePickerView.m in Sources */, + B8F8081A19A3502D0047C24B /* RSDFDatePickerDayCell.m in Sources */, + B8F8081819A3502D0047C24B /* NSCalendar+RSDFAdditions.m in Sources */, + B8F8081B19A3502D0047C24B /* RSDFDatePickerDaysOfWeekView.m in Sources */, + B8F8080819A34CDC0047C24B /* RSDFDatePickerViewController.m in Sources */, + B8F807D119A34B9A0047C24B /* RSDFAppDelegate.m in Sources */, + B8F8081919A3502D0047C24B /* RSDFDatePickerCollectionView.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B8F807D419A34B9A0047C24B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B8F807E619A34B9A0047C24B /* RSDayFlowExampleTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + B8F807DE19A34B9A0047C24B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B8F807BC19A34B990047C24B /* RSDayFlowExample */; + targetProxy = B8F807DD19A34B9A0047C24B /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + B8F807C919A34B9A0047C24B /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + B8F807CA19A34B9A0047C24B /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + B8F807E219A34B9A0047C24B /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + B8F807E319A34B9A0047C24B /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + B8F807E719A34B9A0047C24B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + B8F807E819A34B9A0047C24B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + B8F807EA19A34B9A0047C24B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "RSDayFlowExample/RSDayFlowExample-Prefix.pch"; + INFOPLIST_FILE = "RSDayFlowExample/RSDayFlowExample-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + B8F807EB19A34B9A0047C24B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "RSDayFlowExample/RSDayFlowExample-Prefix.pch"; + INFOPLIST_FILE = "RSDayFlowExample/RSDayFlowExample-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; + B8F807ED19A34B9A0047C24B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/RSDayFlowExample.app/RSDayFlowExample"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + "$(DEVELOPER_FRAMEWORKS_DIR)", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "RSDayFlowExample/RSDayFlowExample-Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = "RSDayFlowExampleTests/RSDayFlowExampleTests-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUNDLE_LOADER)"; + WRAPPER_EXTENSION = xctest; + }; + name = Debug; + }; + B8F807EE19A34B9A0047C24B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/RSDayFlowExample.app/RSDayFlowExample"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + "$(DEVELOPER_FRAMEWORKS_DIR)", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "RSDayFlowExample/RSDayFlowExample-Prefix.pch"; + INFOPLIST_FILE = "RSDayFlowExampleTests/RSDayFlowExampleTests-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUNDLE_LOADER)"; + WRAPPER_EXTENSION = xctest; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + B8F807B819A34B990047C24B /* Build configuration list for PBXProject "RSDayFlowExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B8F807E719A34B9A0047C24B /* Debug */, + B8F807E819A34B9A0047C24B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B8F807E919A34B9A0047C24B /* Build configuration list for PBXNativeTarget "RSDayFlowExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B8F807EA19A34B9A0047C24B /* Debug */, + B8F807EB19A34B9A0047C24B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B8F807EC19A34B9A0047C24B /* Build configuration list for PBXNativeTarget "RSDayFlowExampleTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B8F807ED19A34B9A0047C24B /* Debug */, + B8F807EE19A34B9A0047C24B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = B8F807B519A34B990047C24B /* Project object */; +} diff --git a/Example/RSDayFlowExample/Images.xcassets/AppIcon.appiconset/Contents.json b/Example/RSDayFlowExample/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..a396706 --- /dev/null +++ b/Example/RSDayFlowExample/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Example/RSDayFlowExample/Images.xcassets/LaunchImage.launchimage/Contents.json b/Example/RSDayFlowExample/Images.xcassets/LaunchImage.launchimage/Contents.json new file mode 100644 index 0000000..c79ebd3 --- /dev/null +++ b/Example/RSDayFlowExample/Images.xcassets/LaunchImage.launchimage/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "orientation" : "portrait", + "idiom" : "iphone", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "iphone", + "subtype" : "retina4", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Example/RSDayFlowExample/RSDFAppDelegate.h b/Example/RSDayFlowExample/RSDFAppDelegate.h new file mode 100644 index 0000000..9a63b7e --- /dev/null +++ b/Example/RSDayFlowExample/RSDFAppDelegate.h @@ -0,0 +1,32 @@ +// +// RSDFAppDelegate.h +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import + +@interface RSDFAppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + +@end diff --git a/Example/RSDayFlowExample/RSDFAppDelegate.m b/Example/RSDayFlowExample/RSDFAppDelegate.m new file mode 100644 index 0000000..0aeddc6 --- /dev/null +++ b/Example/RSDayFlowExample/RSDFAppDelegate.m @@ -0,0 +1,72 @@ +// +// RSDFAppDelegate.m +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "RSDFAppDelegate.h" +#import "RSDFDatePickerViewController.h" + +@implementation RSDFAppDelegate + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + self.window.backgroundColor = [UIColor whiteColor]; + + RSDFDatePickerViewController *datePickerVC = [[RSDFDatePickerViewController alloc] init]; + UINavigationController *rootNC = [[UINavigationController alloc] initWithRootViewController:datePickerVC]; + self.window.rootViewController = rootNC; + + [self.window makeKeyAndVisible]; + + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application +{ + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application +{ + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application +{ + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application +{ + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application +{ + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/Example/RSDayFlowExample/RSDFDatePickerViewController.h b/Example/RSDayFlowExample/RSDFDatePickerViewController.h new file mode 100755 index 0000000..93cf473 --- /dev/null +++ b/Example/RSDayFlowExample/RSDFDatePickerViewController.h @@ -0,0 +1,34 @@ +// +// RSDFDatePickerViewController.h +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import + +@class RSDFDatePickerView; + +@interface RSDFDatePickerViewController : UIViewController + +@property (strong, readonly, nonatomic) RSDFDatePickerView *datePickerView; + +@end diff --git a/Example/RSDayFlowExample/RSDFDatePickerViewController.m b/Example/RSDayFlowExample/RSDFDatePickerViewController.m new file mode 100755 index 0000000..5b2d1ad --- /dev/null +++ b/Example/RSDayFlowExample/RSDFDatePickerViewController.m @@ -0,0 +1,105 @@ +// +// RSDFDatePickerViewController.m +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "RSDFDatePickerViewController.h" +#import "RSDFDatePickerView.h" + +@interface RSDFDatePickerViewController() + +@end + +@implementation RSDFDatePickerViewController + +@synthesize datePickerView = _datePickerView; + +#pragma mark - Lifecycle + +- (void) viewDidLoad +{ + [super viewDidLoad]; + + self.edgesForExtendedLayout = UIRectEdgeNone; + + self.navigationItem.title = @"RSDayFlow"; + + self.navigationController.navigationBar.translucent = NO; + self.navigationController.navigationBar.opaque = YES; + self.navigationController.navigationBar.barTintColor = [UIColor colorWithRed:248/255.0f green:248/255.0f blue:248/255.0f alpha:1.0f]; + + self.navigationController.navigationBar.titleTextAttributes = @{NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue-Medium" size:17.0f]}; + + [self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault]; + self.navigationController.navigationBar.shadowImage = [[UIImage alloc] init]; + + self.view.backgroundColor = [UIColor colorWithWhite:0.8 alpha:0.3]; + [self.view addSubview:self.datePickerView]; +} + +#pragma mark - Custom Accessors + +- (RSDFDatePickerView *)datePickerView +{ + if (!_datePickerView) { + _datePickerView = [[RSDFDatePickerView alloc] initWithFrame:self.view.bounds]; + _datePickerView.delegate = self; + _datePickerView.dataSource = self; + _datePickerView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + } + return _datePickerView; +} + +#pragma mark - RSDFDatePickerViewDelegate + +- (void)datePickerView:(RSDFDatePickerView *)view didSelectDate:(NSDate *)date +{ + [[[UIAlertView alloc] initWithTitle:@"Picked Date" message:[date description] delegate:nil cancelButtonTitle:@":D" otherButtonTitles:nil] show]; +} + +#pragma mark - RSDFDatePickerViewDataSource + +- (NSDictionary *)datePickerViewMarkedDates:(RSDFDatePickerView *)view +{ + NSCalendar *calendar = [NSCalendar currentCalendar]; + NSDateComponents *todayComponents = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]]; + NSDate *today = [calendar dateFromComponents:todayComponents]; + + NSArray *numberOfDaysFromToday = @[@(-8), @(-2), @(-1), @(0), @(2), @(4), @(8), @(13), @(22)]; + + NSDateComponents *dateComponents = [[NSDateComponents alloc] init]; + NSMutableDictionary *markedDates = [[NSMutableDictionary alloc] initWithCapacity:[numberOfDaysFromToday count]]; + [numberOfDaysFromToday enumerateObjectsUsingBlock:^(NSNumber *numberOfDays, NSUInteger idx, BOOL *stop) { + dateComponents.day = [numberOfDays integerValue]; + NSDate *date = [calendar dateByAddingComponents:dateComponents toDate:today options:0]; + if ([date compare:today] == NSOrderedAscending) { + markedDates[date] = @YES; + } else { + markedDates[date] = @NO; + } + }]; + + return [markedDates copy]; +} + +@end diff --git a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist new file mode 100644 index 0000000..867d386 --- /dev/null +++ b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist @@ -0,0 +1,38 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + com.ruslanskorb.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + 0.2.0 + CFBundleSignature + ???? + CFBundleVersion + 0.2.0 + LSRequiresIPhoneOS + + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Example/RSDayFlowExample/RSDayFlowExample-Prefix.pch b/Example/RSDayFlowExample/RSDayFlowExample-Prefix.pch new file mode 100644 index 0000000..743435c --- /dev/null +++ b/Example/RSDayFlowExample/RSDayFlowExample-Prefix.pch @@ -0,0 +1,16 @@ +// +// Prefix header +// +// The contents of this file are implicitly included at the beginning of every source file. +// + +#import + +#ifndef __IPHONE_3_0 +#warning "This project uses features only available in iOS SDK 3.0 and later." +#endif + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/Example/RSDayFlowExample/en.lproj/InfoPlist.strings b/Example/RSDayFlowExample/en.lproj/InfoPlist.strings new file mode 100644 index 0000000..477b28f --- /dev/null +++ b/Example/RSDayFlowExample/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/Example/RSDayFlowExample/main.m b/Example/RSDayFlowExample/main.m new file mode 100644 index 0000000..ccb9e91 --- /dev/null +++ b/Example/RSDayFlowExample/main.m @@ -0,0 +1,35 @@ +// +// main.m +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import + +#import "RSDFAppDelegate.h" + +int main(int argc, char * argv[]) +{ + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([RSDFAppDelegate class])); + } +} diff --git a/Example/RSDayFlowExampleTests/RSDayFlowExampleTests-Info.plist b/Example/RSDayFlowExampleTests/RSDayFlowExampleTests-Info.plist new file mode 100644 index 0000000..b0ff0e6 --- /dev/null +++ b/Example/RSDayFlowExampleTests/RSDayFlowExampleTests-Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + com.ruslanskorb.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/Example/RSDayFlowExampleTests/RSDayFlowExampleTests.m b/Example/RSDayFlowExampleTests/RSDayFlowExampleTests.m new file mode 100644 index 0000000..2d26631 --- /dev/null +++ b/Example/RSDayFlowExampleTests/RSDayFlowExampleTests.m @@ -0,0 +1,51 @@ +// +// RSDayFlowExampleTests.m +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import + +@interface RSDayFlowExampleTests : XCTestCase + +@end + +@implementation RSDayFlowExampleTests + +- (void)setUp +{ + [super setUp]; + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown +{ + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testExample +{ + XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); +} + +@end diff --git a/Example/RSDayFlowExampleTests/en.lproj/InfoPlist.strings b/Example/RSDayFlowExampleTests/en.lproj/InfoPlist.strings new file mode 100644 index 0000000..477b28f --- /dev/null +++ b/Example/RSDayFlowExampleTests/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + From 9d6a1a6bbc5402ea86ec2f9deda6546f64003bb1 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 19 Aug 2014 12:56:04 +0300 Subject: [PATCH 27/87] [Update] Remove unnecessary files. RSDayFlow.xcodeproj RSDayFlow-Prefix.pch --- RSDayFlow.xcodeproj/project.pbxproj | 288 ---------------------------- RSDayFlow/RSDayFlow-Prefix.pch | 5 - 2 files changed, 293 deletions(-) delete mode 100644 RSDayFlow.xcodeproj/project.pbxproj delete mode 100644 RSDayFlow/RSDayFlow-Prefix.pch diff --git a/RSDayFlow.xcodeproj/project.pbxproj b/RSDayFlow.xcodeproj/project.pbxproj deleted file mode 100644 index d0587b0..0000000 --- a/RSDayFlow.xcodeproj/project.pbxproj +++ /dev/null @@ -1,288 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - B8726564187C12BB000C1895 /* NSCalendar+RSDFAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = B8726558187C12BB000C1895 /* NSCalendar+RSDFAdditions.m */; }; - B8726565187C12BB000C1895 /* RSDFDatePickerCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = B872655B187C12BB000C1895 /* RSDFDatePickerCollectionView.m */; }; - B8726566187C12BB000C1895 /* RSDFDatePickerDayCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B872655D187C12BB000C1895 /* RSDFDatePickerDayCell.m */; }; - B8726567187C12BB000C1895 /* RSDFDatePickerMonthHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = B872655F187C12BB000C1895 /* RSDFDatePickerMonthHeader.m */; }; - B8726568187C12BB000C1895 /* RSDFDatePickerView.m in Sources */ = {isa = PBXBuildFile; fileRef = B8726561187C12BB000C1895 /* RSDFDatePickerView.m */; }; - B88EB3C5187BB6F100D8E2B8 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B88EB3C4187BB6F100D8E2B8 /* QuartzCore.framework */; }; - B8E5801F19728B6000D766B3 /* RSDFDatePickerDaysOfWeekView.m in Sources */ = {isa = PBXBuildFile; fileRef = B8E5801E19728B6000D766B3 /* RSDFDatePickerDaysOfWeekView.m */; }; - FF2A69CE172D2C07005A1A21 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FF2A69CD172D2C07005A1A21 /* Foundation.framework */; }; - FFB686B3172E8A970027ADF2 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FFB686B2172E8A970027ADF2 /* UIKit.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - FF2A69C8172D2C07005A1A21 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "include/${PRODUCT_NAME}"; - dstSubfolderSpec = 16; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - B8726557187C12BB000C1895 /* NSCalendar+RSDFAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSCalendar+RSDFAdditions.h"; path = "RSDayFlow/NSCalendar+RSDFAdditions.h"; sourceTree = ""; }; - B8726558187C12BB000C1895 /* NSCalendar+RSDFAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSCalendar+RSDFAdditions.m"; path = "RSDayFlow/NSCalendar+RSDFAdditions.m"; sourceTree = ""; }; - B8726559187C12BB000C1895 /* RSDayFlow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RSDayFlow.h; path = RSDayFlow/RSDayFlow.h; sourceTree = ""; }; - B872655A187C12BB000C1895 /* RSDFDatePickerCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RSDFDatePickerCollectionView.h; path = RSDayFlow/RSDFDatePickerCollectionView.h; sourceTree = ""; }; - B872655B187C12BB000C1895 /* RSDFDatePickerCollectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RSDFDatePickerCollectionView.m; path = RSDayFlow/RSDFDatePickerCollectionView.m; sourceTree = ""; }; - B872655C187C12BB000C1895 /* RSDFDatePickerDayCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RSDFDatePickerDayCell.h; path = RSDayFlow/RSDFDatePickerDayCell.h; sourceTree = ""; }; - B872655D187C12BB000C1895 /* RSDFDatePickerDayCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RSDFDatePickerDayCell.m; path = RSDayFlow/RSDFDatePickerDayCell.m; sourceTree = ""; }; - B872655E187C12BB000C1895 /* RSDFDatePickerMonthHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RSDFDatePickerMonthHeader.h; path = RSDayFlow/RSDFDatePickerMonthHeader.h; sourceTree = ""; }; - B872655F187C12BB000C1895 /* RSDFDatePickerMonthHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RSDFDatePickerMonthHeader.m; path = RSDayFlow/RSDFDatePickerMonthHeader.m; sourceTree = ""; }; - B8726560187C12BB000C1895 /* RSDFDatePickerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RSDFDatePickerView.h; path = RSDayFlow/RSDFDatePickerView.h; sourceTree = ""; }; - B8726561187C12BB000C1895 /* RSDFDatePickerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RSDFDatePickerView.m; path = RSDayFlow/RSDFDatePickerView.m; sourceTree = ""; }; - B872656A187C12CD000C1895 /* RSDayFlow-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "RSDayFlow-Prefix.pch"; path = "RSDayFlow/RSDayFlow-Prefix.pch"; sourceTree = SOURCE_ROOT; }; - B88EB3C4187BB6F100D8E2B8 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; - B8E5801D19728B6000D766B3 /* RSDFDatePickerDaysOfWeekView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RSDFDatePickerDaysOfWeekView.h; path = RSDayFlow/RSDFDatePickerDaysOfWeekView.h; sourceTree = ""; }; - B8E5801E19728B6000D766B3 /* RSDFDatePickerDaysOfWeekView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RSDFDatePickerDaysOfWeekView.m; path = RSDayFlow/RSDFDatePickerDaysOfWeekView.m; sourceTree = ""; }; - FF2A69CA172D2C07005A1A21 /* libRSDayFlow.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRSDayFlow.a; sourceTree = BUILT_PRODUCTS_DIR; }; - FF2A69CD172D2C07005A1A21 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - FFB686B2172E8A970027ADF2 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - FF2A69C7172D2C07005A1A21 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - B88EB3C5187BB6F100D8E2B8 /* QuartzCore.framework in Frameworks */, - FF2A69CE172D2C07005A1A21 /* Foundation.framework in Frameworks */, - FFB686B3172E8A970027ADF2 /* UIKit.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - B872656B187C1332000C1895 /* RSDayFlow */ = { - isa = PBXGroup; - children = ( - B8726559187C12BB000C1895 /* RSDayFlow.h */, - B8726560187C12BB000C1895 /* RSDFDatePickerView.h */, - B8726561187C12BB000C1895 /* RSDFDatePickerView.m */, - B872655A187C12BB000C1895 /* RSDFDatePickerCollectionView.h */, - B872655B187C12BB000C1895 /* RSDFDatePickerCollectionView.m */, - B872655C187C12BB000C1895 /* RSDFDatePickerDayCell.h */, - B872655D187C12BB000C1895 /* RSDFDatePickerDayCell.m */, - B872655E187C12BB000C1895 /* RSDFDatePickerMonthHeader.h */, - B872655F187C12BB000C1895 /* RSDFDatePickerMonthHeader.m */, - B8E5801D19728B6000D766B3 /* RSDFDatePickerDaysOfWeekView.h */, - B8E5801E19728B6000D766B3 /* RSDFDatePickerDaysOfWeekView.m */, - B8726557187C12BB000C1895 /* NSCalendar+RSDFAdditions.h */, - B8726558187C12BB000C1895 /* NSCalendar+RSDFAdditions.m */, - ); - name = RSDayFlow; - sourceTree = ""; - }; - FF2A69C1172D2C06005A1A21 = { - isa = PBXGroup; - children = ( - B872656B187C1332000C1895 /* RSDayFlow */, - FF2A69D0172D2C07005A1A21 /* Supporting Files */, - FF2A69CC172D2C07005A1A21 /* Frameworks */, - FF2A69CB172D2C07005A1A21 /* Products */, - ); - sourceTree = ""; - }; - FF2A69CB172D2C07005A1A21 /* Products */ = { - isa = PBXGroup; - children = ( - FF2A69CA172D2C07005A1A21 /* libRSDayFlow.a */, - ); - name = Products; - sourceTree = ""; - }; - FF2A69CC172D2C07005A1A21 /* Frameworks */ = { - isa = PBXGroup; - children = ( - FF2A69CD172D2C07005A1A21 /* Foundation.framework */, - FFB686B2172E8A970027ADF2 /* UIKit.framework */, - B88EB3C4187BB6F100D8E2B8 /* QuartzCore.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - FF2A69D0172D2C07005A1A21 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - B872656A187C12CD000C1895 /* RSDayFlow-Prefix.pch */, - ); - name = "Supporting Files"; - path = DayFlow; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - FF2A69C9172D2C07005A1A21 /* RSDayFlow */ = { - isa = PBXNativeTarget; - buildConfigurationList = FF2A69D8172D2C07005A1A21 /* Build configuration list for PBXNativeTarget "RSDayFlow" */; - buildPhases = ( - FF2A69C6172D2C07005A1A21 /* Sources */, - FF2A69C7172D2C07005A1A21 /* Frameworks */, - FF2A69C8172D2C07005A1A21 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = RSDayFlow; - productName = DayFlow; - productReference = FF2A69CA172D2C07005A1A21 /* libRSDayFlow.a */; - productType = "com.apple.product-type.library.static"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - FF2A69C2172D2C06005A1A21 /* Project object */ = { - isa = PBXProject; - attributes = { - ORGANIZATIONNAME = Radius; - }; - buildConfigurationList = FF2A69C5172D2C06005A1A21 /* Build configuration list for PBXProject "RSDayFlow" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = FF2A69C1172D2C06005A1A21; - productRefGroup = FF2A69CB172D2C07005A1A21 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - FF2A69C9172D2C07005A1A21 /* RSDayFlow */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - FF2A69C6172D2C07005A1A21 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B8726568187C12BB000C1895 /* RSDFDatePickerView.m in Sources */, - B8726567187C12BB000C1895 /* RSDFDatePickerMonthHeader.m in Sources */, - B8726564187C12BB000C1895 /* NSCalendar+RSDFAdditions.m in Sources */, - B8726566187C12BB000C1895 /* RSDFDatePickerDayCell.m in Sources */, - B8726565187C12BB000C1895 /* RSDFDatePickerCollectionView.m in Sources */, - B8E5801F19728B6000D766B3 /* RSDFDatePickerDaysOfWeekView.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - FF2A69D6172D2C07005A1A21 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - }; - name = Debug; - }; - FF2A69D7172D2C07005A1A21 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - FF2A69D9172D2C07005A1A21 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - DSTROOT = /tmp/DayFlow.dst; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "DayFlow/RSDayFlow-Prefix.pch"; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = RSDayFlow; - SKIP_INSTALL = YES; - }; - name = Debug; - }; - FF2A69DA172D2C07005A1A21 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - DSTROOT = /tmp/DayFlow.dst; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "DayFlow/RSDayFlow-Prefix.pch"; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = RSDayFlow; - SKIP_INSTALL = YES; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - FF2A69C5172D2C06005A1A21 /* Build configuration list for PBXProject "RSDayFlow" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - FF2A69D6172D2C07005A1A21 /* Debug */, - FF2A69D7172D2C07005A1A21 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - FF2A69D8172D2C07005A1A21 /* Build configuration list for PBXNativeTarget "RSDayFlow" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - FF2A69D9172D2C07005A1A21 /* Debug */, - FF2A69DA172D2C07005A1A21 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = FF2A69C2172D2C06005A1A21 /* Project object */; -} diff --git a/RSDayFlow/RSDayFlow-Prefix.pch b/RSDayFlow/RSDayFlow-Prefix.pch deleted file mode 100644 index eecd91e..0000000 --- a/RSDayFlow/RSDayFlow-Prefix.pch +++ /dev/null @@ -1,5 +0,0 @@ -#ifdef __OBJC__ - #import - #import - #import -#endif From 6e4de13bfb27275addc9331565d90246a82fb1c9 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 19 Aug 2014 12:56:12 +0300 Subject: [PATCH 28/87] [Update] Podspec. source_files --- RSDayFlow.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RSDayFlow.podspec b/RSDayFlow.podspec index d00b8f0..ed5472b 100644 --- a/RSDayFlow.podspec +++ b/RSDayFlow.podspec @@ -7,7 +7,7 @@ Pod::Spec.new do |s| s.authors = { 'Evadne Wu' => 'ev@radi.ws', 'Ruslan Skorb' => 'ruslan.skorb@gmail.com' } s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.2.0' } s.platform = :ios, '7.0' - s.source_files = 'RSDayFlow', 'RSDayFlow/**/*.{h,m}' + s.source_files = 'RSDayFlow' s.frameworks = 'QuartzCore', 'UIKit' s.requires_arc = true end From 8af68927e0603c4d929122ae220d9f920b604dc1 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 19 Aug 2014 15:01:35 +0300 Subject: [PATCH 29/87] [Add] Example of scrolling the date picker view to the current day. --- .../RSDayFlowExample/RSDFDatePickerViewController.m | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Example/RSDayFlowExample/RSDFDatePickerViewController.m b/Example/RSDayFlowExample/RSDFDatePickerViewController.m index 5b2d1ad..3a73a2b 100755 --- a/Example/RSDayFlowExample/RSDFDatePickerViewController.m +++ b/Example/RSDayFlowExample/RSDFDatePickerViewController.m @@ -41,6 +41,7 @@ - (void) viewDidLoad [super viewDidLoad]; self.edgesForExtendedLayout = UIRectEdgeNone; + self.automaticallyAdjustsScrollViewInsets = NO; self.navigationItem.title = @"RSDayFlow"; @@ -53,6 +54,9 @@ - (void) viewDidLoad [self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault]; self.navigationController.navigationBar.shadowImage = [[UIImage alloc] init]; + UIBarButtonItem *today = [[UIBarButtonItem alloc] initWithTitle:@"Today" style:UIBarButtonItemStyleBordered target:self action:@selector(onTodayButtonTouch:)]; + self.navigationItem.rightBarButtonItem = today; + self.view.backgroundColor = [UIColor colorWithWhite:0.8 alpha:0.3]; [self.view addSubview:self.datePickerView]; } @@ -70,6 +74,13 @@ - (RSDFDatePickerView *)datePickerView return _datePickerView; } +#pragma mark - Action handling + +- (void)onTodayButtonTouch:(UIBarButtonItem *)sender +{ + [self.datePickerView scrollToToday:YES]; +} + #pragma mark - RSDFDatePickerViewDelegate - (void)datePickerView:(RSDFDatePickerView *)view didSelectDate:(NSDate *)date From 8c1b54fba10c7da0192ba01fa9c3df49e7acd950 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 19 Aug 2014 19:41:50 +0300 Subject: [PATCH 30/87] [Add] The ability to customize every view. --- RSDayFlow/RSDFDatePickerCollectionView.h | 15 + RSDayFlow/RSDFDatePickerCollectionView.m | 46 ++ .../RSDFDatePickerCollectionViewLayout.h | 40 ++ .../RSDFDatePickerCollectionViewLayout.m | 60 +++ RSDayFlow/RSDFDatePickerDayCell.h | 132 +++++- RSDayFlow/RSDFDatePickerDayCell.m | 399 +++++++++++------ RSDayFlow/RSDFDatePickerDaysOfWeekView.h | 56 ++- RSDayFlow/RSDFDatePickerDaysOfWeekView.m | 92 ++-- RSDayFlow/RSDFDatePickerMonthHeader.h | 44 +- RSDayFlow/RSDFDatePickerMonthHeader.m | 63 ++- RSDayFlow/RSDFDatePickerView.h | 41 +- RSDayFlow/RSDFDatePickerView.m | 405 ++++++++++-------- RSDayFlow/RSDayFlow.h | 9 +- 13 files changed, 1027 insertions(+), 375 deletions(-) create mode 100644 RSDayFlow/RSDFDatePickerCollectionViewLayout.h create mode 100644 RSDayFlow/RSDFDatePickerCollectionViewLayout.m diff --git a/RSDayFlow/RSDFDatePickerCollectionView.h b/RSDayFlow/RSDFDatePickerCollectionView.h index e56c717..8e515d3 100644 --- a/RSDayFlow/RSDFDatePickerCollectionView.h +++ b/RSDayFlow/RSDFDatePickerCollectionView.h @@ -20,6 +20,10 @@ @end + +/** + The `RSDFDatePickerCollectionView` is a collection view which used to display days and months in the date picker view. + */ @interface RSDFDatePickerCollectionView : UICollectionView /** @@ -29,4 +33,15 @@ */ @property (nonatomic, assign) id delegate; +///--------------------------------------- +/// @name Accessing Attributes of the View +///--------------------------------------- + +/** + The view’s background color. Default value is `[UIColor whiteColor]`. + + @discussion Can be overridden in subclasses for customization. + */ +- (UIColor *)selfBackgroundColor; + @end diff --git a/RSDayFlow/RSDFDatePickerCollectionView.m b/RSDayFlow/RSDFDatePickerCollectionView.m index 956c5ff..d852358 100644 --- a/RSDayFlow/RSDFDatePickerCollectionView.m +++ b/RSDayFlow/RSDFDatePickerCollectionView.m @@ -1,9 +1,48 @@ #import "RSDFDatePickerCollectionView.h" +#import "RSDFDatePickerCollectionViewLayout.h" @implementation RSDFDatePickerCollectionView @dynamic delegate; +#pragma mark - Lifecycle + +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + [self commonInitializer]; + } + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder +{ + self = [super initWithCoder:aDecoder]; + if (self) { + [self commonInitializer]; + } + return self; +} + +- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout +{ + self = [super initWithFrame:frame collectionViewLayout:layout]; + if (self) { + [self commonInitializer]; + } + return self; +} + +- (void)commonInitializer +{ + self.backgroundColor = [self selfBackgroundColor]; + self.showsVerticalScrollIndicator = NO; + self.showsHorizontalScrollIndicator = NO; + self.scrollsToTop = NO; + self.delaysContentTouches = NO; +} + - (void)layoutSubviews { if ([self.delegate respondsToSelector:@selector(pickerCollectionViewWillLayoutSubviews:)]) { @@ -12,4 +51,11 @@ - (void)layoutSubviews [super layoutSubviews]; } +#pragma mark - Atrributes of the View + +- (UIColor *)selfBackgroundColor +{ + return [UIColor whiteColor]; +} + @end diff --git a/RSDayFlow/RSDFDatePickerCollectionViewLayout.h b/RSDayFlow/RSDFDatePickerCollectionViewLayout.h new file mode 100644 index 0000000..3d57afb --- /dev/null +++ b/RSDayFlow/RSDFDatePickerCollectionViewLayout.h @@ -0,0 +1,40 @@ +#import + +/** + The `RSDFDatePickerCollectionViewLayout` is a layout of the collection view which used the date picker. + */ +@interface RSDFDatePickerCollectionViewLayout : UICollectionViewFlowLayout + +///----------------------------------------- +/// @name Accessing Attributes of the Layout +///----------------------------------------- + +/** + The default sizes to use for section headers. Default value is {320, 64}. + + @discussion Can be overridden in subclasses for customization. + */ +- (CGSize)selfHeaderReferenceSize; + +/** + The default size to use for cells. Default value is {44, 70}. + + @discussion Can be overridden in subclasses for customization. + */ +- (CGSize)selfItemSize; + +/** + The minimum spacing to use between lines of items in the grid. Default value is `2.0f`. + + @discussion Can be overridden in subclasses for customization. + */ +- (CGFloat)selfMinimumLineSpacing; + +/** + The minimum spacing to use between items in the same row. Default value is `2.0f`. + + @discussion Can be overridden in subclasses for customization. + */ +- (CGFloat)selfMinimumInteritemSpacing; + +@end diff --git a/RSDayFlow/RSDFDatePickerCollectionViewLayout.m b/RSDayFlow/RSDFDatePickerCollectionViewLayout.m new file mode 100644 index 0000000..eeb43f2 --- /dev/null +++ b/RSDayFlow/RSDFDatePickerCollectionViewLayout.m @@ -0,0 +1,60 @@ +#import "RSDFDatePickerCollectionViewLayout.h" + +@implementation RSDFDatePickerCollectionViewLayout + +#pragma mark - Lifecycle + +- (instancetype)init +{ + self = [super init]; + if (self) { + [self commonInitializer]; + } + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder +{ + self = [super initWithCoder:aDecoder]; + if (self) { + [self commonInitializer]; + } + return self; +} + +- (void)commonInitializer +{ + // Hard key these things. + // 44 * 7 + 2 * 6 = 320; this is how the Calendar.app works + // and this also avoids the “one pixel” confusion which might or might not work + // If you need to decorate, key decorative views in. + + self.headerReferenceSize = [self selfHeaderReferenceSize]; + self.itemSize = [self selfItemSize]; + self.minimumLineSpacing = [self selfMinimumLineSpacing]; + self.minimumInteritemSpacing = [self selfMinimumInteritemSpacing]; +} + +#pragma mark - Atrributes of the Layout + +- (CGSize)selfHeaderReferenceSize +{ + return (CGSize){ 320, 64 }; +} + +- (CGSize)selfItemSize +{ + return (CGSize){ 44, 70 }; +} + +- (CGFloat)selfMinimumLineSpacing +{ + return 2.0f; +} + +- (CGFloat)selfMinimumInteritemSpacing +{ + return 2.0f; +} + +@end diff --git a/RSDayFlow/RSDFDatePickerDayCell.h b/RSDayFlow/RSDFDatePickerDayCell.h index 7810d56..52fa5e4 100644 --- a/RSDayFlow/RSDFDatePickerDayCell.h +++ b/RSDayFlow/RSDFDatePickerDayCell.h @@ -2,7 +2,7 @@ #import "RSDayFlow.h" /** - `RSDFDatePickerDayCell` is a cell which used to display a day in the date picker view. + The `RSDFDatePickerDayCell` is a cell which used to display a day in the date picker view. */ @interface RSDFDatePickerDayCell : UICollectionViewCell @@ -15,9 +15,9 @@ */ @property (nonatomic, readonly, strong) UILabel *dateLabel; -///----------------------------------- -/// @name Accessing the Day Attributes -///----------------------------------- +///-------------------------------------- +/// @name Accessing Attributes of the Day +///-------------------------------------- /** A date which corresponds to the current cell. @@ -36,6 +36,11 @@ */ @property (nonatomic, getter = isDayOff) BOOL dayOff; +/** + A Boolean value that determines whether the cell represents the current day. + */ +@property (nonatomic, getter = isToday) BOOL today; + /** A Boolean value that determines whether the cell have a mark. */ @@ -46,9 +51,124 @@ */ @property (nonatomic, getter = isCompleted) BOOL completed; +///--------------------------------------- +/// @name Accessing Attributes of the View +///--------------------------------------- + /** - A Boolean value that determines whether the cell represents the current day. + The view’s background color. Default value is `[UIColor clearColor]`. + + @discussion Can be overridden in subclasses for customization. */ -@property (nonatomic, getter = isToday) BOOL today; +- (UIColor *)selfBackgroundColor; + +///--------------------------------------- +/// @name Accessing Attributes of Subviews +///--------------------------------------- + +/** + The font of the text which displayed by the label of the day. Default value is [UIFont fontWithName:@"HelveticaNeue" size:18.0f]. + + @discussion Can be overridden in subclasses for customization. + */ +- (UIFont *)dayLabelFont; + +/** + The text color for the label of the day. Default value is [UIColor blackColor]. + + @discussion Can be overridden in subclasses for customization. + */ +- (UIColor *)dayLabelTextColor; + +/** + The text color for the label of the day off. Default value is [UIColor colorWithRed:184/255.0f green:184/255.0f blue:184/255.0f alpha:1.0f]. + + @discussion Can be overridden in subclasses for customization. + */ +- (UIColor *)dayOffLabelTextColor; + +/** + The font for the label of the current day. Default value is [UIFont fontWithName:@"HelveticaNeue-Bold" size:19.0f]. + + @discussion Can be overridden in subclasses for customization. + */ +- (UIFont *)todayLabelFont; + +/** + The text color for the label of the current day. Default value is [UIColor whiteColor]. + + @discussion Can be overridden in subclasses for customization. + */ +- (UIColor *)todayLabelTextColor; + +/** + The color of the background image for the cell of the current day. Default value is [UIColor colorWithRed:0/255.0f green:121/255.0f blue:255/255.0f alpha:1.0f]. + + @discussion Can be overridden in subclasses for customization. Ignored if `customTodayImage` is not equal to `nil`. + */ +- (UIColor *)todayImageColor; + +/** + The custom background image for the cell of the current day. Default value is `nil`. + + @discussion Can be overridden in subclasses for customization. + */ +- (UIImage *)customTodayImage; + +/** + The color of the overlay image for the cell of the day. Default value is [UIColor colorWithRed:184/255.0f green:184/255.0f blue:184/255.0f alpha:1.0f]. + + @discussion Can be overridden in subclasses for customization. Ignored if `customOverlayImage` is not equal to `nil`. + */ +- (UIColor *)overlayImageColor; + +/** + The custom overlay image for the cell of the current day. Default value is `nil`. + + @discussion Can be overridden in subclasses for customization. + */ +- (UIImage *)customOverlayImage; + +/** + The color of the incomplete mark image for the cell of the day. Default value is [UIColor colorWithRed:184/255.0f green:184/255.0f blue:184/255.0f alpha:1.0f]. + + @discussion Can be overridden in subclasses for customization. Ignored if `customIncompleteMarkImage` is not equal to `nil`. + */ +- (UIColor *)incompleteMarkImageColor; + +/** + The custom incomplete mark image for the cell of the day. Default value is `nil`. + + @discussion Can be overridden in subclasses for customization. + */ +- (UIImage *)customIncompleteMarkImage; + +/** + The color of the complete mark image for the cell of the day. Default value is [UIColor colorWithRed:83/255.0f green:215/255.0f blue:105/255.0f alpha:1.0f]. + + @discussion Can be overridden in subclasses for customization. Ignored if `customCompleteMarkImage` is not equal to `nil`. + */ +- (UIColor *)completeMarkImageColor; + +/** + The custom complete mark image for the cell of the day. Default value is `nil`. + + @discussion Can be overridden in subclasses for customization. + */ +- (UIImage *)customCompleteMarkImage; + +/** + The color of the divider image for the cell of the day. Default value is [UIColor colorWithRed:200/255.0f green:200/255.0f blue:200/255.0f alpha:1.0f]. + + @discussion Can be overridden in subclasses for customization. Ignored if `customDividerImage` is not equal to `nil`. + */ +- (UIColor *)dividerImageColor; + +/** + The custom divider image for the cell of the day. Default value is `nil`. + + @discussion Can be overridden in subclasses for customization. + */ +- (UIImage *)customDividerImage; @end diff --git a/RSDayFlow/RSDFDatePickerDayCell.m b/RSDayFlow/RSDFDatePickerDayCell.m index 4abe5c9..497078a 100644 --- a/RSDayFlow/RSDFDatePickerDayCell.m +++ b/RSDayFlow/RSDFDatePickerDayCell.m @@ -5,22 +5,24 @@ @interface RSDFDatePickerDayCell () + (NSCache *)imageCache; + (id)fetchObjectForKey:(id)key withCreator:(id(^)(void))block; -@property (nonatomic, readonly, strong) UIImageView *dividerTopImageView; -@property (nonatomic, readonly, strong) UIImageView *markerImageView; -@property (nonatomic, readonly, strong) UIImageView *overlayImageView; @property (nonatomic, readonly, strong) UIImageView *todayImageView; +@property (nonatomic, readonly, strong) UIImageView *overlayImageView; +@property (nonatomic, readonly, strong) UIImageView *markImageView; +@property (nonatomic, readonly, strong) UIImageView *dividerImageView; @end @implementation RSDFDatePickerDayCell -@synthesize dateLabel = _dateLabel; -@synthesize dividerTopImageView = _dividerTopImageView; -@synthesize markerImageView = _markerImageView; -@synthesize overlayImageView = _overlayImageView; -@synthesize todayImageView = _todayImageView; +@synthesize dateLabel = _dateLabel; +@synthesize todayImageView = _todayImageView; +@synthesize overlayImageView = _overlayImageView; +@synthesize markImageView = _markImageView; +@synthesize dividerImageView = _dividerImageView; -- (id)initWithFrame:(CGRect)frame +#pragma mark - Lifecycle + +- (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { @@ -29,7 +31,7 @@ - (id)initWithFrame:(CGRect)frame return self; } -- (id)initWithCoder:(NSCoder *)aDecoder +- (instancetype)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { @@ -40,14 +42,23 @@ - (id)initWithCoder:(NSCoder *)aDecoder - (void)commonInitializer { - self.backgroundColor = [UIColor whiteColor]; - self.todayImageView.hidden = YES; - self.overlayImageView.hidden = YES; - self.markerImageView.hidden = YES; - self.dividerTopImageView.hidden = NO; - self.dateLabel.hidden = NO; + self.backgroundColor = [self selfBackgroundColor]; + + self.todayImageView.hidden = YES; + self.overlayImageView.hidden = YES; + self.markImageView.hidden = YES; + self.dividerImageView.hidden = NO; + self.dateLabel.hidden = NO; + + [self addSubview:self.todayImageView]; + [self addSubview:self.overlayImageView]; + [self addSubview:self.markImageView]; + [self addSubview:self.dividerImageView]; + [self addSubview:self.dateLabel]; } +#pragma mark - Custom Accessors + - (void)setDate:(RSDFDatePickerDate)date { _date = date; @@ -57,64 +68,36 @@ - (void)setEnabled:(BOOL)enabled { _enabled = enabled; if (!_enabled) { - self.todayImageView.hidden = YES; - self.markerImageView.hidden = YES; + self.todayImageView.hidden = YES; + self.markImageView.hidden = YES; } - self.dateLabel.hidden = !_enabled; - self.dividerTopImageView.hidden = !_enabled; + self.dateLabel.hidden = !_enabled; + self.dividerImageView.hidden = !_enabled; } - (void)setDayOff:(BOOL)dayOff { _dayOff = dayOff; if (!_dayOff) { - self.dateLabel.textColor = [UIColor blackColor]; + self.dateLabel.textColor = [self dayLabelTextColor]; } else { - self.dateLabel.textColor = [UIColor colorWithRed:184/255.0f green:184/255.0f blue:184/255.0f alpha:1.0f]; + self.dateLabel.textColor = [self dayOffLabelTextColor]; } } - (void)setMarked:(BOOL)marked { _marked = marked; - self.markerImageView.hidden = !_marked; + self.markImageView.hidden = !_marked; } - (void)setCompleted:(BOOL)completed { _completed = completed; - if (_completed) { - self.markerImageView.image = [[self class] fetchObjectForKey:@"img_marker_green" withCreator:^id{ - UIGraphicsBeginImageContextWithOptions(_markerImageView.frame.size, NO, self.window.screen.scale); - CGContextRef context = UIGraphicsGetCurrentContext(); - - CGRect rect = _markerImageView.frame; - rect.origin = CGPointZero; - - CGContextSetFillColorWithColor(context, [UIColor colorWithRed:83/255.0f green:215/255.0f blue:105/255.0f alpha:1.0f].CGColor); - CGContextFillEllipseInRect(context, rect); - - UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - - return image; - }]; + if (!_completed) { + self.markImageView.image = [self incompleteMarkImage]; } else { - self.markerImageView.image = [[self class] fetchObjectForKey:@"img_marker_gray" withCreator:^id{ - UIGraphicsBeginImageContextWithOptions(_markerImageView.frame.size, NO, self.window.screen.scale); - CGContextRef context = UIGraphicsGetCurrentContext(); - - CGRect rect = _markerImageView.frame; - rect.origin = CGPointZero; - - CGContextSetFillColorWithColor(context, [UIColor colorWithRed:184/255.0f green:184/255.0f blue:184/255.0f alpha:1.0f].CGColor); - CGContextFillEllipseInRect(context, rect); - - UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - - return image; - }]; + self.markImageView.image = [self completeMarkImage]; } } @@ -122,10 +105,15 @@ - (void)setToday:(BOOL)today { _today = today; if (!_today) { - self.dateLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:18.0f]; + self.dateLabel.font = [self dayLabelFont]; + if (!self.dayOff) { + self.dateLabel.textColor = [self dayLabelTextColor]; + } else { + self.dateLabel.textColor = [self dayOffLabelTextColor]; + } } else { - self.dateLabel.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:19.0f]; - self.dateLabel.textColor = [UIColor whiteColor]; + self.dateLabel.font = [self todayLabelFont]; + self.dateLabel.textColor = [self todayLabelTextColor]; } self.todayImageView.hidden = !_today; } @@ -133,7 +121,20 @@ - (void)setToday:(BOOL)today - (void)setHighlighted:(BOOL)highlighted { [super setHighlighted:highlighted]; - self.overlayImageView.hidden = !(self.highlighted); + self.overlayImageView.hidden = !self.highlighted; +} + +- (UILabel *)dateLabel +{ + if (!_dateLabel) { + CGRect frame = CGRectMake(self.bounds.origin.x, self.todayImageView.frame.origin.y, + self.bounds.size.width, self.todayImageView.frame.size.height); + _dateLabel = [[UILabel alloc] initWithFrame:frame]; + _dateLabel.backgroundColor = [UIColor clearColor]; + _dateLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; + _dateLabel.textAlignment = NSTextAlignmentCenter; + } + return _dateLabel; } - (UIImageView *)todayImageView @@ -141,108 +142,52 @@ - (UIImageView *)todayImageView if (!_todayImageView) { CGRect frame = CGRectMake(0.0f, 0.0f, 35.0f, 35.0f); _todayImageView = [[UIImageView alloc] initWithFrame:frame]; - _todayImageView.center = CGPointMake(self.frame.size.width/2, 23.0f); _todayImageView.backgroundColor = [UIColor clearColor]; - - _todayImageView.image = [[self class] fetchObjectForKey:@"img_today" withCreator:^id{ - UIGraphicsBeginImageContextWithOptions(_todayImageView.frame.size, NO, self.window.screen.scale); - CGContextRef context = UIGraphicsGetCurrentContext(); - - CGRect rect = _todayImageView.frame; - rect.origin = CGPointZero; - - CGContextSetFillColorWithColor(context, [UIColor colorWithRed:0/255.0f green:121/255.0f blue:255/255.0f alpha:1.0f].CGColor); - CGContextFillEllipseInRect(context, rect); - - UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - - return image; - }]; - - [self.contentView addSubview:_todayImageView]; + _todayImageView.center = CGPointMake(self.frame.size.width / 2, 23.0f); + _todayImageView.contentMode = UIViewContentModeCenter; + _todayImageView.image = [self todayImage]; } return _todayImageView; } -- (UIImageView *)dividerTopImageView -{ - if (!_dividerTopImageView) { - CGRect frame = CGRectMake(0.0f, 0.0f, 50.0f, 0.5f); - _dividerTopImageView = [[UIImageView alloc] initWithFrame:frame]; - - _dividerTopImageView.image = [[self class] fetchObjectForKey:@"img_divider_top" withCreator:^id{ - UIGraphicsBeginImageContextWithOptions(_dividerTopImageView.frame.size, NO, self.window.screen.scale); - CGContextRef context = UIGraphicsGetCurrentContext(); - CGContextSetFillColorWithColor(context, [UIColor colorWithRed:200/255.0f green:200/255.0f blue:200/255.0f alpha:1.0f].CGColor); - CGContextFillRect(context, _dividerTopImageView.frame); - UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - return image; - }]; - - [self.contentView addSubview:_dividerTopImageView]; - } - return _dividerTopImageView; -} - - (UIImageView *)overlayImageView { if (!_overlayImageView) { _overlayImageView = [[UIImageView alloc] initWithFrame:self.todayImageView.frame]; - - _overlayImageView.image = [[self class] fetchObjectForKey:@"img_overlay" withCreator:^id{ - UIGraphicsBeginImageContextWithOptions(_overlayImageView.frame.size, NO, self.window.screen.scale); - CGContextRef context = UIGraphicsGetCurrentContext(); - - CGRect rect = _overlayImageView.frame; - rect.origin = CGPointZero; - - CGContextSetFillColorWithColor(context, [UIColor colorWithRed:184/255.0f green:184/255.0f blue:184/255.0f alpha:1.0f].CGColor); - CGContextFillEllipseInRect(context, rect); - - UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - - return image; - }]; - - _overlayImageView.opaque = YES; + _overlayImageView.backgroundColor = [UIColor clearColor]; + _overlayImageView.opaque = NO; _overlayImageView.alpha = 0.5f; - [self.contentView addSubview:_overlayImageView]; + _overlayImageView.contentMode = UIViewContentModeCenter; + _overlayImageView.image = [self overlayImage]; } return _overlayImageView; } -- (UILabel *)dateLabel +- (UIImageView *)markImageView { - if (!_dateLabel) { - CGRect frame = CGRectMake(self.bounds.origin.x, - self.todayImageView.frame.origin.y, - self.bounds.size.width, - self.todayImageView.frame.size.height); - _dateLabel = [[UILabel alloc] initWithFrame:frame]; - _dateLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; - _dateLabel.textAlignment = NSTextAlignmentCenter; - _dateLabel.backgroundColor = [UIColor clearColor]; - [self.contentView addSubview:_dateLabel]; + if (!_markImageView) { + CGRect frame = CGRectMake(0.0f, 0.0f, 9.0f, 9.0f); + _markImageView = [[UIImageView alloc] initWithFrame:frame]; + _markImageView.backgroundColor = [UIColor clearColor]; + _markImageView.center = CGPointMake(self.frame.size.width / 2, 50.0f); + _markImageView.contentMode = UIViewContentModeCenter; } - return _dateLabel; + return _markImageView; } -- (UIImageView *)markerImageView +- (UIImageView *)dividerImageView { - if (!_markerImageView) { - CGRect frame = CGRectMake(0.0f, 0.0f, 9.0f, 9.0f); - _markerImageView = [[UIImageView alloc] initWithFrame:frame]; - CGFloat centerX = self.frame.size.width / 2; - CGFloat centerY = 50.0f; - _markerImageView.center = CGPointMake(centerX, centerY); - [self.contentView addSubview:_markerImageView]; - } - return _markerImageView; + if (!_dividerImageView) { + CGRect frame = CGRectMake(0.0f, 0.0f, 50.0f, 0.5f); + _dividerImageView = [[UIImageView alloc] initWithFrame:frame]; + _dividerImageView.contentMode = UIViewContentModeCenter; + _dividerImageView.image = [self dividerImage]; + } + return _dividerImageView; } +#pragma mark - Private + + (NSCache *)imageCache { static NSCache *cache; @@ -263,4 +208,180 @@ + (id)fetchObjectForKey:(id)key withCreator:(id(^)(void))block return answer; } +- (UIImage *)ellipseImageWithKey:(NSString *)key frame:(CGRect)frame color:(UIColor *)color +{ + UIImage *ellipseImage = [[self class] fetchObjectForKey:key withCreator:^id{ + UIGraphicsBeginImageContextWithOptions(frame.size, NO, self.window.screen.scale); + CGContextRef context = UIGraphicsGetCurrentContext(); + + CGRect rect = frame; + rect.origin = CGPointZero; + + CGContextSetFillColorWithColor(context, color.CGColor); + CGContextFillEllipseInRect(context, rect); + + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return image; + }]; + return ellipseImage; +} + +- (UIImage *)rectImageWithKey:(NSString *)key frame:(CGRect)frame color:(UIColor *)color +{ + UIImage *rectImage = [[self class] fetchObjectForKey:key withCreator:^id{ + UIGraphicsBeginImageContextWithOptions(frame.size, NO, self.window.screen.scale); + CGContextRef context = UIGraphicsGetCurrentContext(); + + CGContextSetFillColorWithColor(context, color.CGColor); + CGContextFillRect(context, frame); + + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return image; + }]; + return rectImage; +} + +#pragma mark - Atrributes of the View + +- (UIColor *)selfBackgroundColor +{ + return [UIColor clearColor]; +} + +#pragma mark - Attributes of Subviews + +- (UIFont *)dayLabelFont +{ + return [UIFont fontWithName:@"HelveticaNeue" size:18.0f]; +} + +- (UIColor *)dayLabelTextColor +{ + return [UIColor blackColor]; +} + +- (UIColor *)dayOffLabelTextColor +{ + return [UIColor colorWithRed:184/255.0f green:184/255.0f blue:184/255.0f alpha:1.0f]; +} + +- (UIFont *)todayLabelFont +{ + return [UIFont fontWithName:@"HelveticaNeue-Bold" size:19.0f]; +} + +- (UIColor *)todayLabelTextColor +{ + return [UIColor whiteColor];; +} + +- (UIColor *)todayImageColor +{ + return [UIColor colorWithRed:0/255.0f green:121/255.0f blue:255/255.0f alpha:1.0f]; +} + +- (UIImage *)customTodayImage +{ + return nil; +} + +- (UIImage *)todayImage +{ + UIImage *todayImage = [self customTodayImage]; + if (!todayImage) { + UIColor *todayImageColor = [self todayImageColor]; + NSString *todayImageKey = [NSString stringWithFormat:@"img_today_%@", [todayImageColor description]]; + todayImage = [self ellipseImageWithKey:todayImageKey frame:self.todayImageView.frame color:todayImageColor]; + } + return todayImage; +} + +- (UIColor *)overlayImageColor +{ + return [UIColor colorWithRed:184/255.0f green:184/255.0f blue:184/255.0f alpha:1.0f]; +} + +- (UIImage *)customOverlayImage +{ + return nil; +} + +- (UIImage *)overlayImage +{ + UIImage *overlayImage = [self customOverlayImage]; + if (!overlayImage) { + UIColor *overlayImageColor = [self overlayImageColor]; + NSString *overlayImageKey = [NSString stringWithFormat:@"img_overlay_%@", [overlayImageColor description]]; + overlayImage = [self ellipseImageWithKey:overlayImageKey frame:self.overlayImageView.frame color:overlayImageColor]; + } + return overlayImage; +} + +- (UIColor *)incompleteMarkImageColor +{ + return [UIColor colorWithRed:184/255.0f green:184/255.0f blue:184/255.0f alpha:1.0f]; +} + +- (UIImage *)customIncompleteMarkImage +{ + return nil; +} + +- (UIImage *)incompleteMarkImage +{ + UIImage *incompleteMarkImage = [self customIncompleteMarkImage]; + if (!incompleteMarkImage) { + UIColor *incompleteMarkImageColor = [self incompleteMarkImageColor]; + NSString *incompleteMarkImageKey = [NSString stringWithFormat:@"img_mark_%@", [incompleteMarkImageColor description]]; + incompleteMarkImage = [self ellipseImageWithKey:incompleteMarkImageKey frame:self.markImageView.frame color:incompleteMarkImageColor]; + } + return incompleteMarkImage; +} + +- (UIColor *)completeMarkImageColor +{ + return [UIColor colorWithRed:83/255.0f green:215/255.0f blue:105/255.0f alpha:1.0f]; +} + +- (UIImage *)customCompleteMarkImage +{ + return nil; +} + +- (UIImage *)completeMarkImage +{ + UIImage *completeMarkImage = [self customCompleteMarkImage]; + if (!completeMarkImage) { + UIColor *completeMarkImageColor = [self completeMarkImageColor]; + NSString *completeMarkImageKey = [NSString stringWithFormat:@"img_mark_%@", [completeMarkImageColor description]]; + completeMarkImage = [self ellipseImageWithKey:completeMarkImageKey frame:self.markImageView.frame color:completeMarkImageColor]; + } + return completeMarkImage; +} + +- (UIColor *)dividerImageColor +{ + return [UIColor colorWithRed:200/255.0f green:200/255.0f blue:200/255.0f alpha:1.0f]; +} + +- (UIImage *)customDividerImage +{ + return nil; +} + +- (UIImage *)dividerImage +{ + UIImage *dividerImage = [self customDividerImage]; + if (!dividerImage) { + UIColor *dividerImageColor = [self dividerImageColor]; + NSString *dividerImageKey = [NSString stringWithFormat:@"img_divider_%@", [dividerImageColor description]]; + dividerImage = [self rectImageWithKey:dividerImageKey frame:self.dividerImageView.frame color:dividerImageColor]; + } + return dividerImage; +} + @end diff --git a/RSDayFlow/RSDFDatePickerDaysOfWeekView.h b/RSDayFlow/RSDFDatePickerDaysOfWeekView.h index 0d218e1..7e77b7d 100644 --- a/RSDayFlow/RSDFDatePickerDaysOfWeekView.h +++ b/RSDayFlow/RSDFDatePickerDaysOfWeekView.h @@ -1,7 +1,7 @@ #import /** - `RSDFDatePickerDaysOfWeekView` is a view with labels for each day of the week. + The `RSDFDatePickerDaysOfWeekView` is a view with labels for each day of the week. */ @interface RSDFDatePickerDaysOfWeekView : UIView @@ -13,4 +13,58 @@ */ - (instancetype)initWithFrame:(CGRect)frame calendar:(NSCalendar *)calendar; +///--------------------------------------- +/// @name Accessing Attributes of the View +///--------------------------------------- + +/** + The view’s background color. Default value is `[UIColor colorWithRed:248.0/255 green:248.0/255 blue:248.0/255 alpha:1.0]`. + + @discussion Can be overridden in subclasses for customization. + */ +- (UIColor *)selfBackgroundColor; + +///----------------------------------------- +/// @name Accessing Attributes of the Layout +///----------------------------------------- + +/** + The size to use for labels of weekdays. Default value is {44, 22}. + + @discussion Can be overridden in subclasses for customization. + */ +- (CGSize)selfItemSize; + +/** + The spacing to use between labels. Default value is `2.0f`. + + @discussion Can be overridden in subclasses for customization. + */ +- (CGFloat)selfInteritemSpacing; + +///--------------------------------------- +/// @name Accessing Attributes of Subviews +///--------------------------------------- + +/** + The font for the label of the weekday. Default value is [UIFont fontWithName:@"HelveticaNeue-Light" size:10.0]. + + @discussion Can be overridden in subclasses for customization. + */ +- (UIFont *)dayOfWeekLabelFont; + +/** + The text color for the label of the weekday. Default value is [UIColor blackColor]. + + @discussion Can be overridden in subclasses for customization. + */ +- (UIColor *)dayOfWeekLabelTextColor; + +/** + The text color for the label of the day off of the week. Default value is [UIColor colorWithRed:150.0/255 green:150.0/255 blue:150.0/255 alpha:1.0].å + + @discussion Can be overridden in subclasses for customization. + */ +- (UIColor *)dayOffOfWeekLabelTextColor; + @end diff --git a/RSDayFlow/RSDFDatePickerDaysOfWeekView.m b/RSDayFlow/RSDFDatePickerDaysOfWeekView.m index 0795f51..415e089 100644 --- a/RSDayFlow/RSDFDatePickerDaysOfWeekView.m +++ b/RSDayFlow/RSDFDatePickerDaysOfWeekView.m @@ -11,16 +11,6 @@ @implementation RSDFDatePickerDaysOfWeekView #pragma mark - Lifecycle -- (instancetype)initWithFrame:(CGRect)frame calendar:(NSCalendar *)calendar -{ - self = [super initWithFrame:frame]; - if (self) { - _calendar = calendar; - [self commonInitializer]; - } - return self; -} - - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; @@ -39,12 +29,23 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder return self; } +- (instancetype)initWithFrame:(CGRect)frame calendar:(NSCalendar *)calendar +{ + self = [super initWithFrame:frame]; + if (self) { + _calendar = calendar; + [self commonInitializer]; + } + return self; +} + #pragma mark - Custom Accessors - (NSCalendar *)calendar { if (!_calendar) { _calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; + _calendar.locale = [NSLocale currentLocale]; } return _calendar; } @@ -53,21 +54,21 @@ - (NSCalendar *)calendar - (void)commonInitializer { - self.backgroundColor = [UIColor colorWithRed:248.0/255 green:248.0/255 blue:248.0/255 alpha:1.0]; + self.backgroundColor = [self selfBackgroundColor]; - UIColor *weekdayLabelBackgroundColor = [UIColor clearColor]; - UIFont *weekdayLabelFont = [UIFont fontWithName:@"HelveticaNeue-Light" size:10.0]; - UIColor *weekdayLabelDayTextColor = [UIColor blackColor]; - UIColor *weekdayLabelDayOffTextColor = [UIColor colorWithRed:150.0/255 green:150.0/255 blue:150.0/255 alpha:1.0]; + UIColor *dayOfWeekLabelBackgroundColor = [UIColor clearColor]; + UIFont *dayOfWeekLabelFont = [self dayOfWeekLabelFont]; + UIColor *dayOfWeekLabelTextColor = [self dayOfWeekLabelTextColor]; + UIColor *dayOffOfWeekLabelTextColor = [self dayOffOfWeekLabelTextColor]; // Hard key these things. - // 44 * 7 + 2 * 6 = 320; from collectionViewLayout of RSDFDatePickerView + // 44 * 7 + 2 * 6 = 320; in accordance with RSDFDatePickerCollectionViewLayout - CGFloat dayItemWidth = 44.0f; - CGFloat minimumInteritemSpacing = 2.0f; + CGSize itemSize = [self selfItemSize]; + CGFloat interitemSpacing = [self selfInteritemSpacing]; - CGFloat yCenter = CGRectGetHeight(self.bounds) / 2; - __block CGFloat xCenter = dayItemWidth / 2; + CGFloat y = 0; + __block CGFloat x = 0; NSDateFormatter *dateFormatter = [self.calendar df_dateFormatterNamed:@"calendarDaysOfWeekView" withConstructor:^{ NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; @@ -89,21 +90,56 @@ - (void)commonInitializer } [reorderedWeekdaySymbols enumerateObjectsUsingBlock:^(NSString *weekdaySymbol, NSUInteger idx, BOOL *stop) { - UILabel *weekdayLabel = [[UILabel alloc] init]; - weekdayLabel.backgroundColor = weekdayLabelBackgroundColor; - weekdayLabel.font = weekdayLabelFont; + UILabel *weekdayLabel = [[UILabel alloc] initWithFrame:CGRectMake(x, y, itemSize.width, itemSize.height)]; + weekdayLabel.textAlignment = NSTextAlignmentCenter; + weekdayLabel.backgroundColor = dayOfWeekLabelBackgroundColor; + weekdayLabel.font = dayOfWeekLabelFont; if ([weekdaySymbols indexOfObjectIdenticalTo:weekdaySymbol] != 0 && [weekdaySymbols indexOfObjectIdenticalTo:weekdaySymbol] != 6) { - weekdayLabel.textColor = weekdayLabelDayTextColor; + weekdayLabel.textColor = dayOfWeekLabelTextColor; } else { - weekdayLabel.textColor = weekdayLabelDayOffTextColor; + weekdayLabel.textColor = dayOffOfWeekLabelTextColor; } weekdayLabel.text = weekdaySymbol; - [weekdayLabel sizeToFit]; - weekdayLabel.center = CGPointMake(xCenter, yCenter); [self addSubview:weekdayLabel]; - xCenter += (dayItemWidth + minimumInteritemSpacing); + x += (itemSize.width + interitemSpacing); }]; } +#pragma mark - Attributes of the View + +- (UIColor *)selfBackgroundColor +{ + return [UIColor colorWithRed:248.0/255 green:248.0/255 blue:248.0/255 alpha:1.0]; +} + +#pragma mark - Attributes of the Layout + +- (CGSize)selfItemSize +{ + return (CGSize){ 44, 22 }; +} + +- (CGFloat)selfInteritemSpacing +{ + return 2.0f; +} + +#pragma mark - Attributes of Subviews + +- (UIFont *)dayOfWeekLabelFont +{ + return [UIFont fontWithName:@"HelveticaNeue-Light" size:10.0]; +} + +- (UIColor *)dayOfWeekLabelTextColor +{ + return [UIColor blackColor]; +} + +- (UIColor *)dayOffOfWeekLabelTextColor +{ + return [UIColor colorWithRed:150.0/255 green:150.0/255 blue:150.0/255 alpha:1.0]; +} + @end diff --git a/RSDayFlow/RSDFDatePickerMonthHeader.h b/RSDayFlow/RSDFDatePickerMonthHeader.h index d67c3cc..3b45090 100644 --- a/RSDayFlow/RSDFDatePickerMonthHeader.h +++ b/RSDayFlow/RSDFDatePickerMonthHeader.h @@ -2,7 +2,7 @@ #import "RSDayFlow.h" /** - `RSDFDatePickerMonthHeader` is a reusable view which used to display a month and year in the date picker view. + The `RSDFDatePickerMonthHeader` is a reusable view which used to display a month and year in the date picker view. */ @interface RSDFDatePickerMonthHeader : UICollectionReusableView @@ -15,9 +15,9 @@ */ @property (nonatomic, readonly, strong) UILabel *dateLabel; -///------------------------------------- -/// @name Accessing the Month Attributes -///------------------------------------- +///---------------------------------------- +/// @name Accessing Attributes of the Month +///---------------------------------------- /** A date which corresponds to the current view. @@ -29,4 +29,40 @@ */ @property (nonatomic, getter = isCurrentMonth) BOOL currentMonth; +///--------------------------------------- +/// @name Accessing Attributes of the View +///--------------------------------------- + +/** + The view’s background color. Default value is `[UIColor clearColor]`. + + @discussion Can be overridden in subclasses for customization. + */ +- (UIColor *)selfBackgroundColor; + +///--------------------------------------- +/// @name Accessing Attributes of Subviews +///--------------------------------------- + +/** + The font for the label of the month. Default value is [UIFont fontWithName:@"HelveticaNeue" size:16.0f]. + + @discussion Can be overridden in subclasses for customization. + */ +- (UIFont *)monthLabelFont; + +/** + The text color for the label of the month. Default value is [UIColor blackColor]. + + @discussion Can be overridden in subclasses for customization. + */ +- (UIColor *)monthLabelTextColor; + +/** + The text color for the label of the current month. Default value is [UIColor colorWithRed:32/255.0f green:135/255.0f blue:252/255.0f alpha:1.0f]. + + @discussion Can be overridden in subclasses for customization. + */ +- (UIColor *)currentMonthLabelTextColor; + @end diff --git a/RSDayFlow/RSDFDatePickerMonthHeader.m b/RSDayFlow/RSDFDatePickerMonthHeader.m index b79a14f..3d68154 100644 --- a/RSDayFlow/RSDFDatePickerMonthHeader.m +++ b/RSDayFlow/RSDFDatePickerMonthHeader.m @@ -4,13 +4,42 @@ @implementation RSDFDatePickerMonthHeader @synthesize dateLabel = _dateLabel; +#pragma mark - Lifecycle + +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + [self commonInitializer]; + } + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder +{ + self = [super initWithCoder:aDecoder]; + if (self) { + [self commonInitializer]; + } + return self; +} + +- (void)commonInitializer +{ + self.backgroundColor = [self selfBackgroundColor]; +} + +#pragma mark - Custom Accessors + - (UILabel *)dateLabel { if (!_dateLabel) { _dateLabel = [[UILabel alloc] initWithFrame:self.bounds]; + _dateLabel.backgroundColor = [UIColor clearColor]; + _dateLabel.opaque = NO; _dateLabel.textAlignment = NSTextAlignmentCenter; - _dateLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:16.0f]; - _dateLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; + _dateLabel.font = [self monthLabelFont]; + _dateLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; [self addSubview:_dateLabel]; } return _dateLabel; @@ -24,11 +53,35 @@ - (void)setDate:(RSDFDatePickerDate)date - (void)setCurrentMonth:(BOOL)currentMonth { _currentMonth = currentMonth; - if (_currentMonth) { - self.dateLabel.textColor = [UIColor colorWithRed:32/255.0f green:135/255.0f blue:252/255.0f alpha:1.0f]; + if (!_currentMonth) { + self.dateLabel.textColor = [self monthLabelTextColor]; } else { - self.dateLabel.textColor = [UIColor blackColor]; + self.dateLabel.textColor = [self currentMonthLabelTextColor]; } } +#pragma mark - Attributes of the View + +- (UIColor *)selfBackgroundColor +{ + return [UIColor clearColor]; +} + +#pragma mark - Attributes of Subviews + +- (UIFont *)monthLabelFont +{ + return [UIFont fontWithName:@"HelveticaNeue" size:16.0f]; +} + +- (UIColor *)monthLabelTextColor +{ + return [UIColor blackColor]; +} + +- (UIColor *)currentMonthLabelTextColor +{ + return [UIColor colorWithRed:32/255.0f green:135/255.0f blue:252/255.0f alpha:1.0f]; +} + @end diff --git a/RSDayFlow/RSDFDatePickerView.h b/RSDayFlow/RSDFDatePickerView.h index 4d31942..19cc75f 100644 --- a/RSDayFlow/RSDFDatePickerView.h +++ b/RSDayFlow/RSDFDatePickerView.h @@ -4,7 +4,7 @@ @protocol RSDFDatePickerViewDataSource; /** - `RSDFDatePickerView` is a calendar view with infinity scrolling. + The `RSDFDatePickerView` is a calendar view with infinity scrolling. */ @interface RSDFDatePickerView : UIView @@ -54,6 +54,45 @@ */ - (void)reloadData; +///------------------------------------ +/// @name Accessing Classes of Subviews +///------------------------------------ + +/** + The class of the view with labels for each day of the week. Default value is `RSDFDatePickerDaysOfWeekView`. + + @discussion Can be overridden in subclasses for customization. + */ +- (Class)daysOfWeekViewClass; + +/** + The class of the collection view which used to display days and months in the date picker view. Default value is `RSDFDatePickerCollectionView`. + + @discussion Can be overridden in subclasses for customization. + */ +- (Class)collectionViewClass; + +/** + The class of the layout of the collection view which used the date picker. Default value is `RSDFDatePickerCollectionViewLayout`. + + @discussion Can be overridden in subclasses for customization. + */ +- (Class)collectionViewLayoutClass; + +/** + The class of the reusable view which used to display a month and year in the date picker view. Default value is `RSDFDatePickerMonthHeader`. + + @discussion Can be overridden in subclasses for customization. + */ +- (Class)monthHeaderClass; + +/** + The class of the cell which used to display a day in the date picker view. Default value is `RSDFDatePickerDayCell`. + + @discussion Can be overridden in subclasses for customization. + */ +- (Class)dayCellClass; + @end /** diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index 6f5e878..86b71a1 100644 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -1,16 +1,18 @@ #import #import "RSDayFlow.h" #import "RSDFDatePickerCollectionView.h" +#import "RSDFDatePickerCollectionViewLayout.h" #import "RSDFDatePickerDayCell.h" #import "RSDFDatePickerMonthHeader.h" #import "RSDFDatePickerView.h" #import "RSDFDatePickerDaysOfWeekView.h" #import "NSCalendar+RSDFAdditions.h" -static NSString * const DFDatePickerViewCellIdentifier = @"dateCell"; -static NSString * const DFDatePickerViewMonthHeaderIdentifier = @"monthHeader"; -static const CGFloat DFDatePickerViewDaysOfWeekViewWidth = 320.0f; -static const CGFloat DFDatePickerViewDaysOfWeekViewHeight = 22.0f; +static NSString * const RSDFDatePickerViewMonthHeaderIdentifier = @"RSDFDatePickerViewMonthHeaderIdentifier"; +static NSString * const RSDFDatePickerViewDayCellIdentifier = @"RSDFDatePickerViewDayCellIdentifier"; + +static const CGFloat RSDFDatePickerViewDaysOfWeekViewWidth = 320.0f; +static const CGFloat RSDFDatePickerViewDaysOfWeekViewHeight = 22.0f; @interface RSDFDatePickerView () @@ -18,8 +20,8 @@ @interface RSDFDatePickerView () , objc::DenseMapInfo >::LookupBucketFor(objc_object* const&, std::pair*&) const - // 141.0ms 2.0% 141.0 DYLD-STUB$$-[_UIHostedTextServiceSession dismissTextServiceAnimated:] - // 138.0ms 1.9% 138.0 -[NSObject retain] - // 136.0ms 1.9% 136.0 -[NSIndexPath indexAtPosition:] - // 124.0ms 1.7% 124.0 -[_UICollectionViewItemKey isEqual:] - // 118.0ms 1.7% 118.0 _objc_rootReleaseWasZero - // 105.0ms 1.5% 105.0 DYLD-STUB$$CFDictionarySetValue$shim - - if (pickerCollectionView.contentOffset.y < 0.0f) { - [self appendPastDates]; - } + return [RSDFDatePickerMonthHeader class]; +} + +- (Class)dayCellClass +{ + return [RSDFDatePickerDayCell class]; +} + +#pragma mark - Public + +- (void)scrollToToday:(BOOL)animated +{ + RSDFDatePickerCollectionView *cv = self.collectionView; + RSDFDatePickerCollectionViewLayout *cvLayout = (RSDFDatePickerCollectionViewLayout *)self.collectionView.collectionViewLayout; - if (pickerCollectionView.contentOffset.y > (pickerCollectionView.contentSize.height - CGRectGetHeight(pickerCollectionView.bounds))) { - [self appendFutureDates]; - } + NSArray *visibleCells = [self.collectionView visibleCells]; + if (![visibleCells count]) + return; + + NSDateComponents *nowYearMonthComponents = [self.calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit) fromDate:[NSDate date]]; + NSDate *now = [self.calendar dateFromComponents:nowYearMonthComponents]; + + _fromDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:((^{ + NSDateComponents *components = [NSDateComponents new]; + components.month = -6; + return components; + })()) toDate:now options:0]]; + + _toDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:((^{ + NSDateComponents *components = [NSDateComponents new]; + components.month = 6; + return components; + })()) toDate:now options:0]]; + + [cv reloadData]; + [cvLayout invalidateLayout]; + [cvLayout prepareLayout]; + + RSDFDatePickerDate todayPickerDate = [self pickerDateFromDate:_today]; + NSInteger section = self.collectionView.numberOfSections / 2; + NSDate *firstDayInMonth = [self dateForFirstDayInSection:section]; + NSUInteger weekday = [self.calendar components:NSWeekdayCalendarUnit fromDate:firstDayInMonth].weekday; + + // weekday start from 1 and include first day of month + NSInteger item = weekday + todayPickerDate.day - 2; + + NSIndexPath *cellIndexPath = [NSIndexPath indexPathForItem:item inSection:section]; + [self.collectionView scrollToItemAtIndexPath:cellIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:animated]; +} + +- (void)reloadData +{ + [self.collectionView reloadData]; +} + +#pragma mark - Private + +- (void)configureCalendar +{ + NSDateComponents *nowYearMonthComponents = [self.calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit) fromDate:[NSDate date]]; + NSDate *now = [self.calendar dateFromComponents:nowYearMonthComponents]; + + _fromDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:((^{ + NSDateComponents *components = [NSDateComponents new]; + components.month = -6; + return components; + })()) toDate:now options:0]]; + + _toDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:((^{ + NSDateComponents *components = [NSDateComponents new]; + components.month = 6; + return components; + })()) toDate:now options:0]]; + + NSDateComponents *todayYearMonthDayComponents = [self.calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]]; + _today = [self.calendar dateFromComponents:todayYearMonthDayComponents]; } - (void)appendPastDates @@ -204,7 +246,6 @@ - (void)appendPastDates dateComponents.month = -6; return dateComponents; })())]; - } - (void)appendFutureDates @@ -214,13 +255,12 @@ - (void)appendFutureDates dateComponents.month = 6; return dateComponents; })())]; - } - (void)shiftDatesByComponents:(NSDateComponents *)components { - UICollectionView *cv = self.collectionView; - UICollectionViewFlowLayout *cvLayout = (UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout; + RSDFDatePickerCollectionView *cv = self.collectionView; + RSDFDatePickerCollectionViewLayout *cvLayout = (RSDFDatePickerCollectionViewLayout *)self.collectionView.collectionViewLayout; NSArray *visibleCells = [self.collectionView visibleCells]; if (![visibleCells count]) @@ -297,56 +337,6 @@ - (void)shiftDatesByComponents:(NSDateComponents *)components }]; } -- (void)scrollToToday:(BOOL)animated -{ - UICollectionView *cv = self.collectionView; - UICollectionViewFlowLayout *cvLayout = (UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout; - - NSArray *visibleCells = [self.collectionView visibleCells]; - if (![visibleCells count]) - return; - - NSDateComponents *nowYearMonthComponents = [_calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit) fromDate:[NSDate date]]; - NSDate *now = [_calendar dateFromComponents:nowYearMonthComponents]; - - _fromDate = [self pickerDateFromDate:[_calendar dateByAddingComponents:((^{ - NSDateComponents *components = [NSDateComponents new]; - components.month = -6; - return components; - })()) toDate:now options:0]]; - - _toDate = [self pickerDateFromDate:[_calendar dateByAddingComponents:((^{ - NSDateComponents *components = [NSDateComponents new]; - components.month = 6; - return components; - })()) toDate:now options:0]]; - - [cv reloadData]; - [cvLayout invalidateLayout]; - [cvLayout prepareLayout]; - - RSDFDatePickerDate todayPickerDate = [self pickerDateFromDate:_today]; - NSInteger section = self.collectionView.numberOfSections / 2; - NSDate *firstDayInMonth = [self dateForFirstDayInSection:section]; - NSUInteger weekday = [self.calendar components:NSWeekdayCalendarUnit fromDate:firstDayInMonth].weekday; - - // weekday start from 1 and include first day of month - NSInteger item = weekday + todayPickerDate.day - 2; - - NSIndexPath *cellIndexPath = [NSIndexPath indexPathForItem:item inSection:section]; - [self.collectionView scrollToItemAtIndexPath:cellIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:animated]; -} - -- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView -{ - return [self.calendar components:NSMonthCalendarUnit fromDate:[self dateFromPickerDate:self.fromDate] toDate:[self dateFromPickerDate:self.toDate] options:0].month; -} - -- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section -{ - return 7 * [self numberOfWeeksForMonthOfDate:[self dateForFirstDayInSection:section]]; -} - - (NSDate *)dateForFirstDayInSection:(NSInteger)section { return [self.calendar dateByAddingComponents:((^{ @@ -382,9 +372,45 @@ - (NSUInteger)numberOfWeeksForMonthOfDate:(NSDate *)date return 1 + [self.calendar components:NSWeekCalendarUnit fromDate:fromSunday toDate:toSunday options:0].week; } +- (NSDate *)dateFromPickerDate:(RSDFDatePickerDate)dateStruct +{ + return [self.calendar dateFromComponents:[self dateComponentsFromPickerDate:dateStruct]]; +} + +- (NSDateComponents *)dateComponentsFromPickerDate:(RSDFDatePickerDate)dateStruct +{ + NSDateComponents *components = [NSDateComponents new]; + components.year = dateStruct.year; + components.month = dateStruct.month; + components.day = dateStruct.day; + return components; +} + +- (RSDFDatePickerDate)pickerDateFromDate:(NSDate *)date +{ + NSDateComponents *components = [self.calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:date]; + return (RSDFDatePickerDate) { + components.year, + components.month, + components.day + }; +} + +#pragma mark - UICollectionViewDataSource + +- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView +{ + return [self.calendar components:NSMonthCalendarUnit fromDate:[self dateFromPickerDate:self.fromDate] toDate:[self dateFromPickerDate:self.toDate] options:0].month; +} + +- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section +{ + return 7 * [self numberOfWeeksForMonthOfDate:[self dateForFirstDayInSection:section]]; +} + - (RSDFDatePickerDayCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { - RSDFDatePickerDayCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:DFDatePickerViewCellIdentifier forIndexPath:indexPath]; + RSDFDatePickerDayCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:RSDFDatePickerViewDayCellIdentifier forIndexPath:indexPath]; NSDate *firstDayInMonth = [self dateForFirstDayInSection:indexPath.section]; RSDFDatePickerDate firstDayPickerDate = [self pickerDateFromDate:firstDayInMonth]; @@ -423,36 +449,11 @@ - (RSDFDatePickerDayCell *)collectionView:(UICollectionView *)collectionView cel return cell; } -// We are cheating by piggybacking on view state to avoid recalculation -// in -collectionView:shouldHighlightItemAtIndexPath: -// and -collectionView:shouldSelectItemAtIndexPath:. - -// A native refactoring process might introduce duplicate state which is bad too. - -- (BOOL) collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath -{ - return ((RSDFDatePickerDayCell *)[collectionView cellForItemAtIndexPath:indexPath]).enabled; -} - -- (BOOL) collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath -{ - return ((RSDFDatePickerDayCell *)[collectionView cellForItemAtIndexPath:indexPath]).enabled; -} - -- (void) collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath -{ - if ([self.delegate respondsToSelector:@selector(datePickerView:didSelectDate:)]) { - RSDFDatePickerDayCell *cell = ((RSDFDatePickerDayCell *)[collectionView cellForItemAtIndexPath:indexPath]); - NSDate *selectedDate = cell ? [self.calendar dateFromComponents:[self dateComponentsFromPickerDate:cell.date]] : nil; - [self.delegate datePickerView:self didSelectDate:selectedDate]; - } -} - -- (UICollectionReusableView *) collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath +- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath { if ([kind isEqualToString:UICollectionElementKindSectionHeader]) { - RSDFDatePickerMonthHeader *monthHeader = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:DFDatePickerViewMonthHeaderIdentifier forIndexPath:indexPath]; + RSDFDatePickerMonthHeader *monthHeader = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:RSDFDatePickerViewMonthHeaderIdentifier forIndexPath:indexPath]; NSDateFormatter *dateFormatter = [self.calendar df_dateFormatterNamed:@"calendarMonthHeader" withConstructor:^{ NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; @@ -483,33 +484,59 @@ - (UICollectionReusableView *) collectionView:(UICollectionView *)collectionView return nil; } -- (NSDate *) dateFromPickerDate:(RSDFDatePickerDate)dateStruct +#pragma mark - UICollectionViewDelegate + +// We are cheating by piggybacking on view state to avoid recalculation +// in -collectionView:shouldHighlightItemAtIndexPath: +// and -collectionView:shouldSelectItemAtIndexPath:. + +// A native refactoring process might introduce duplicate state which is bad too. + +- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath { - return [self.calendar dateFromComponents:[self dateComponentsFromPickerDate:dateStruct]]; + return ((RSDFDatePickerDayCell *)[collectionView cellForItemAtIndexPath:indexPath]).enabled; } -- (NSDateComponents *) dateComponentsFromPickerDate:(RSDFDatePickerDate)dateStruct +- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath { - NSDateComponents *components = [NSDateComponents new]; - components.year = dateStruct.year; - components.month = dateStruct.month; - components.day = dateStruct.day; - return components; + return ((RSDFDatePickerDayCell *)[collectionView cellForItemAtIndexPath:indexPath]).enabled; } -- (RSDFDatePickerDate) pickerDateFromDate:(NSDate *)date +- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { - NSDateComponents *components = [self.calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:date]; - return (RSDFDatePickerDate) { - components.year, - components.month, - components.day - }; + if ([self.delegate respondsToSelector:@selector(datePickerView:didSelectDate:)]) { + RSDFDatePickerDayCell *cell = ((RSDFDatePickerDayCell *)[collectionView cellForItemAtIndexPath:indexPath]); + NSDate *selectedDate = cell ? [self.calendar dateFromComponents:[self dateComponentsFromPickerDate:cell.date]] : nil; + [self.delegate datePickerView:self didSelectDate:selectedDate]; + } } -- (void)reloadData +#pragma mark - RSDFDatePickerCollectionViewDelegate + +- (void)pickerCollectionViewWillLayoutSubviews:(RSDFDatePickerCollectionView *)pickerCollectionView { - [self.collectionView reloadData]; + // Note: relayout is slower than calculating 3 or 6 months’ worth of data at a time + // So we punt 6 months at a time. + + // Running Time Self Symbol Name + // + // 1647.0ms 23.7% 1647.0 objc_msgSend + // 193.0ms 2.7% 193.0 -[NSIndexPath compare:] + // 163.0ms 2.3% 163.0 objc::DenseMap, objc::DenseMapInfo >::LookupBucketFor(objc_object* const&, std::pair*&) const + // 141.0ms 2.0% 141.0 DYLD-STUB$$-[_UIHostedTextServiceSession dismissTextServiceAnimated:] + // 138.0ms 1.9% 138.0 -[NSObject retain] + // 136.0ms 1.9% 136.0 -[NSIndexPath indexAtPosition:] + // 124.0ms 1.7% 124.0 -[_UICollectionViewItemKey isEqual:] + // 118.0ms 1.7% 118.0 _objc_rootReleaseWasZero + // 105.0ms 1.5% 105.0 DYLD-STUB$$CFDictionarySetValue$shim + + if (pickerCollectionView.contentOffset.y < 0.0f) { + [self appendPastDates]; + } + + if (pickerCollectionView.contentOffset.y > (pickerCollectionView.contentSize.height - CGRectGetHeight(pickerCollectionView.bounds))) { + [self appendFutureDates]; + } } @end diff --git a/RSDayFlow/RSDayFlow.h b/RSDayFlow/RSDayFlow.h index 431f683..391216e 100644 --- a/RSDayFlow/RSDayFlow.h +++ b/RSDayFlow/RSDayFlow.h @@ -2,10 +2,15 @@ `RSDayFlow` is an iOS 7 Calendar with Infinite Scrolling. */ -#import "RSDFDatePickerView.h" - typedef struct { NSUInteger year; NSUInteger month; NSUInteger day; } RSDFDatePickerDate; + +#import "RSDFDatePickerView.h" +#import "RSDFDatePickerDaysOfWeekView.h" +#import "RSDFDatePickerCollectionView.h" +#import "RSDFDatePickerCollectionViewLayout.h" +#import "RSDFDatePickerMonthHeader.h" +#import "RSDFDatePickerDayCell.h" From ca9f5c1ff22d44a55dc9a0103d74080a6e9dff47 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 19 Aug 2014 20:06:15 +0300 Subject: [PATCH 31/87] [Add] Example of customizing each view. --- .../project.pbxproj | 50 +++++++++++ .../RSDFCustomDatePickerCollectionView.h | 30 +++++++ .../RSDFCustomDatePickerCollectionView.m | 35 ++++++++ ...RSDFCustomDatePickerCollectionViewLayout.h | 30 +++++++ ...RSDFCustomDatePickerCollectionViewLayout.m | 42 +++++++++ .../RSDFCustomDatePickerDayCell.h | 30 +++++++ .../RSDFCustomDatePickerDayCell.m | 70 +++++++++++++++ .../RSDFCustomDatePickerDaysOfWeekView.h | 30 +++++++ .../RSDFCustomDatePickerDaysOfWeekView.m | 40 +++++++++ .../RSDFCustomDatePickerMonthHeader.h | 30 +++++++ .../RSDFCustomDatePickerMonthHeader.m | 50 +++++++++++ .../RSDFCustomDatePickerView.h | 30 +++++++ .../RSDFCustomDatePickerView.m | 60 +++++++++++++ .../RSDFDatePickerViewController.h | 2 - .../RSDFDatePickerViewController.m | 86 ++++++++++++++----- 15 files changed, 591 insertions(+), 24 deletions(-) create mode 100644 Example/RSDayFlowExample/RSDFCustomDatePickerCollectionView.h create mode 100644 Example/RSDayFlowExample/RSDFCustomDatePickerCollectionView.m create mode 100644 Example/RSDayFlowExample/RSDFCustomDatePickerCollectionViewLayout.h create mode 100644 Example/RSDayFlowExample/RSDFCustomDatePickerCollectionViewLayout.m create mode 100644 Example/RSDayFlowExample/RSDFCustomDatePickerDayCell.h create mode 100644 Example/RSDayFlowExample/RSDFCustomDatePickerDayCell.m create mode 100644 Example/RSDayFlowExample/RSDFCustomDatePickerDaysOfWeekView.h create mode 100644 Example/RSDayFlowExample/RSDFCustomDatePickerDaysOfWeekView.m create mode 100644 Example/RSDayFlowExample/RSDFCustomDatePickerMonthHeader.h create mode 100644 Example/RSDayFlowExample/RSDFCustomDatePickerMonthHeader.m create mode 100644 Example/RSDayFlowExample/RSDFCustomDatePickerView.h create mode 100644 Example/RSDayFlowExample/RSDFCustomDatePickerView.m diff --git a/Example/RSDayFlowExample.xcodeproj/project.pbxproj b/Example/RSDayFlowExample.xcodeproj/project.pbxproj index 5ff1cfd..8362c71 100644 --- a/Example/RSDayFlowExample.xcodeproj/project.pbxproj +++ b/Example/RSDayFlowExample.xcodeproj/project.pbxproj @@ -7,6 +7,13 @@ objects = { /* Begin PBXBuildFile section */ + B82FFF9819A35722000816FF /* RSDFDatePickerCollectionViewLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = B82FFF9719A35722000816FF /* RSDFDatePickerCollectionViewLayout.m */; }; + B82FFFA519A37EDB000816FF /* RSDFCustomDatePickerCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = B82FFF9A19A37EDB000816FF /* RSDFCustomDatePickerCollectionView.m */; }; + B82FFFA619A37EDB000816FF /* RSDFCustomDatePickerCollectionViewLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = B82FFF9C19A37EDB000816FF /* RSDFCustomDatePickerCollectionViewLayout.m */; }; + B82FFFA719A37EDB000816FF /* RSDFCustomDatePickerDayCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B82FFF9E19A37EDB000816FF /* RSDFCustomDatePickerDayCell.m */; }; + B82FFFA819A37EDB000816FF /* RSDFCustomDatePickerDaysOfWeekView.m in Sources */ = {isa = PBXBuildFile; fileRef = B82FFFA019A37EDB000816FF /* RSDFCustomDatePickerDaysOfWeekView.m */; }; + B82FFFA919A37EDB000816FF /* RSDFCustomDatePickerMonthHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = B82FFFA219A37EDB000816FF /* RSDFCustomDatePickerMonthHeader.m */; }; + B82FFFAA19A37EDB000816FF /* RSDFCustomDatePickerView.m in Sources */ = {isa = PBXBuildFile; fileRef = B82FFFA419A37EDB000816FF /* RSDFCustomDatePickerView.m */; }; B8F807C119A34B990047C24B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B8F807C019A34B990047C24B /* Foundation.framework */; }; B8F807C319A34B9A0047C24B /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B8F807C219A34B9A0047C24B /* CoreGraphics.framework */; }; B8F807C519A34B9A0047C24B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B8F807C419A34B9A0047C24B /* UIKit.framework */; }; @@ -39,6 +46,20 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + B82FFF9619A35722000816FF /* RSDFDatePickerCollectionViewLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSDFDatePickerCollectionViewLayout.h; sourceTree = ""; }; + B82FFF9719A35722000816FF /* RSDFDatePickerCollectionViewLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSDFDatePickerCollectionViewLayout.m; sourceTree = ""; }; + B82FFF9919A37EDB000816FF /* RSDFCustomDatePickerCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSDFCustomDatePickerCollectionView.h; sourceTree = ""; }; + B82FFF9A19A37EDB000816FF /* RSDFCustomDatePickerCollectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSDFCustomDatePickerCollectionView.m; sourceTree = ""; }; + B82FFF9B19A37EDB000816FF /* RSDFCustomDatePickerCollectionViewLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSDFCustomDatePickerCollectionViewLayout.h; sourceTree = ""; }; + B82FFF9C19A37EDB000816FF /* RSDFCustomDatePickerCollectionViewLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSDFCustomDatePickerCollectionViewLayout.m; sourceTree = ""; }; + B82FFF9D19A37EDB000816FF /* RSDFCustomDatePickerDayCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSDFCustomDatePickerDayCell.h; sourceTree = ""; }; + B82FFF9E19A37EDB000816FF /* RSDFCustomDatePickerDayCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSDFCustomDatePickerDayCell.m; sourceTree = ""; }; + B82FFF9F19A37EDB000816FF /* RSDFCustomDatePickerDaysOfWeekView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSDFCustomDatePickerDaysOfWeekView.h; sourceTree = ""; }; + B82FFFA019A37EDB000816FF /* RSDFCustomDatePickerDaysOfWeekView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSDFCustomDatePickerDaysOfWeekView.m; sourceTree = ""; }; + B82FFFA119A37EDB000816FF /* RSDFCustomDatePickerMonthHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSDFCustomDatePickerMonthHeader.h; sourceTree = ""; }; + B82FFFA219A37EDB000816FF /* RSDFCustomDatePickerMonthHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSDFCustomDatePickerMonthHeader.m; sourceTree = ""; }; + B82FFFA319A37EDB000816FF /* RSDFCustomDatePickerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSDFCustomDatePickerView.h; sourceTree = ""; }; + B82FFFA419A37EDB000816FF /* RSDFCustomDatePickerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSDFCustomDatePickerView.m; sourceTree = ""; }; B8F807BD19A34B990047C24B /* RSDayFlowExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RSDayFlowExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; B8F807C019A34B990047C24B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; B8F807C219A34B9A0047C24B /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; @@ -96,6 +117,25 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + B82FFFAB19A37EDF000816FF /* Views */ = { + isa = PBXGroup; + children = ( + B82FFFA319A37EDB000816FF /* RSDFCustomDatePickerView.h */, + B82FFFA419A37EDB000816FF /* RSDFCustomDatePickerView.m */, + B82FFF9F19A37EDB000816FF /* RSDFCustomDatePickerDaysOfWeekView.h */, + B82FFFA019A37EDB000816FF /* RSDFCustomDatePickerDaysOfWeekView.m */, + B82FFF9919A37EDB000816FF /* RSDFCustomDatePickerCollectionView.h */, + B82FFF9A19A37EDB000816FF /* RSDFCustomDatePickerCollectionView.m */, + B82FFF9B19A37EDB000816FF /* RSDFCustomDatePickerCollectionViewLayout.h */, + B82FFF9C19A37EDB000816FF /* RSDFCustomDatePickerCollectionViewLayout.m */, + B82FFFA119A37EDB000816FF /* RSDFCustomDatePickerMonthHeader.h */, + B82FFFA219A37EDB000816FF /* RSDFCustomDatePickerMonthHeader.m */, + B82FFF9D19A37EDB000816FF /* RSDFCustomDatePickerDayCell.h */, + B82FFF9E19A37EDB000816FF /* RSDFCustomDatePickerDayCell.m */, + ); + name = Views; + sourceTree = ""; + }; B8F807B419A34B990047C24B = { isa = PBXGroup; children = ( @@ -133,6 +173,7 @@ B8F807CF19A34B9A0047C24B /* RSDFAppDelegate.h */, B8F807D019A34B9A0047C24B /* RSDFAppDelegate.m */, B8F8080519A34CC00047C24B /* Controllers */, + B82FFFAB19A37EDF000816FF /* Views */, B8F807D219A34B9A0047C24B /* Images.xcassets */, B8F807C719A34B9A0047C24B /* Supporting Files */, ); @@ -196,6 +237,8 @@ B8F8081319A3502D0047C24B /* RSDFDatePickerDaysOfWeekView.m */, B8F8080E19A3502D0047C24B /* RSDFDatePickerCollectionView.h */, B8F8080F19A3502D0047C24B /* RSDFDatePickerCollectionView.m */, + B82FFF9619A35722000816FF /* RSDFDatePickerCollectionViewLayout.h */, + B82FFF9719A35722000816FF /* RSDFDatePickerCollectionViewLayout.m */, B8F8081419A3502D0047C24B /* RSDFDatePickerMonthHeader.h */, B8F8081519A3502D0047C24B /* RSDFDatePickerMonthHeader.m */, B8F8081019A3502D0047C24B /* RSDFDatePickerDayCell.h */, @@ -303,13 +346,20 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + B82FFFA619A37EDB000816FF /* RSDFCustomDatePickerCollectionViewLayout.m in Sources */, + B82FFFA519A37EDB000816FF /* RSDFCustomDatePickerCollectionView.m in Sources */, B8F8081C19A3502D0047C24B /* RSDFDatePickerMonthHeader.m in Sources */, + B82FFFA919A37EDB000816FF /* RSDFCustomDatePickerMonthHeader.m in Sources */, B8F807CD19A34B9A0047C24B /* main.m in Sources */, + B82FFFA819A37EDB000816FF /* RSDFCustomDatePickerDaysOfWeekView.m in Sources */, + B82FFFAA19A37EDB000816FF /* RSDFCustomDatePickerView.m in Sources */, B8F8081D19A3502D0047C24B /* RSDFDatePickerView.m in Sources */, B8F8081A19A3502D0047C24B /* RSDFDatePickerDayCell.m in Sources */, B8F8081819A3502D0047C24B /* NSCalendar+RSDFAdditions.m in Sources */, + B82FFF9819A35722000816FF /* RSDFDatePickerCollectionViewLayout.m in Sources */, B8F8081B19A3502D0047C24B /* RSDFDatePickerDaysOfWeekView.m in Sources */, B8F8080819A34CDC0047C24B /* RSDFDatePickerViewController.m in Sources */, + B82FFFA719A37EDB000816FF /* RSDFCustomDatePickerDayCell.m in Sources */, B8F807D119A34B9A0047C24B /* RSDFAppDelegate.m in Sources */, B8F8081919A3502D0047C24B /* RSDFDatePickerCollectionView.m in Sources */, ); diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionView.h b/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionView.h new file mode 100644 index 0000000..8a49588 --- /dev/null +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionView.h @@ -0,0 +1,30 @@ +// +// RSDFCustomDatePickerCollectionView.h +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "RSDFDatePickerCollectionView.h" + +@interface RSDFCustomDatePickerCollectionView : RSDFDatePickerCollectionView + +@end diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionView.m b/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionView.m new file mode 100644 index 0000000..f37832f --- /dev/null +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionView.m @@ -0,0 +1,35 @@ +// +// RSDFCustomDatePickerCollectionView.m +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "RSDFCustomDatePickerCollectionView.h" + +@implementation RSDFCustomDatePickerCollectionView + +- (UIColor *)selfBackgroundColor +{ + return [UIColor clearColor]; +} + +@end diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionViewLayout.h b/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionViewLayout.h new file mode 100644 index 0000000..2c3d7c9 --- /dev/null +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionViewLayout.h @@ -0,0 +1,30 @@ +// +// RSDFCustomDatePickerCollectionViewLayout.h +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "RSDFDatePickerCollectionViewLayout.h" + +@interface RSDFCustomDatePickerCollectionViewLayout : RSDFDatePickerCollectionViewLayout + +@end diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionViewLayout.m b/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionViewLayout.m new file mode 100644 index 0000000..cdfd768 --- /dev/null +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionViewLayout.m @@ -0,0 +1,42 @@ +// +// RSDFCustomDatePickerCollectionViewLayout.m +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "RSDFCustomDatePickerCollectionViewLayout.h" + +@implementation RSDFCustomDatePickerCollectionViewLayout + +#pragma mark - Layout Atrributes + +- (CGSize)selfHeaderReferenceSize +{ + return (CGSize){ 320, 54 }; +} + +- (CGSize)selfItemSize +{ + return (CGSize){ 44, 60 }; +} + +@end diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerDayCell.h b/Example/RSDayFlowExample/RSDFCustomDatePickerDayCell.h new file mode 100644 index 0000000..55b9d69 --- /dev/null +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerDayCell.h @@ -0,0 +1,30 @@ +// +// RSDFCustomDatePickerDayCell.h +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "RSDFDatePickerDayCell.h" + +@interface RSDFCustomDatePickerDayCell : RSDFDatePickerDayCell + +@end diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerDayCell.m b/Example/RSDayFlowExample/RSDFCustomDatePickerDayCell.m new file mode 100644 index 0000000..00366ed --- /dev/null +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerDayCell.m @@ -0,0 +1,70 @@ +// +// RSDFCustomDatePickerDayCell.m +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "RSDFCustomDatePickerDayCell.h" + +@implementation RSDFCustomDatePickerDayCell + +- (UIFont *)dayLabelFont +{ + return [UIFont fontWithName:@"AvenirNext-Regular" size:16.0f]; +} + +- (UIColor *)dayLabelTextColor +{ + return [UIColor colorWithRed:51/255.0f green:37/255.0f blue:36/255.0f alpha:1.0f]; +} + +- (UIColor *)dayOffLabelTextColor +{ + return [UIColor colorWithRed:51/255.0f green:37/255.0f blue:36/255.0f alpha:1.0f]; +} + +- (UIFont *)todayLabelFont +{ + return [UIFont fontWithName:@"AvenirNext-Bold" size:17.0f]; +} + +- (UIColor *)todayLabelTextColor +{ + return [UIColor colorWithRed:3/255.0f green:117/255.0f blue:214/255.0f alpha:1.0f]; +} + +- (UIColor *)todayImageColor +{ + return [UIColor clearColor]; +} + +- (UIColor *)overlayImageColor +{ + return [UIColor colorWithWhite:1.0f alpha:1.0f]; +} + +- (UIColor *)dividerImageColor +{ + return [UIColor clearColor]; +} + +@end diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerDaysOfWeekView.h b/Example/RSDayFlowExample/RSDFCustomDatePickerDaysOfWeekView.h new file mode 100644 index 0000000..33a6bef --- /dev/null +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerDaysOfWeekView.h @@ -0,0 +1,30 @@ +// +// RSDFCustomDatePickerDaysOfWeekView.h +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "RSDFDatePickerDaysOfWeekView.h" + +@interface RSDFCustomDatePickerDaysOfWeekView : RSDFDatePickerDaysOfWeekView + +@end diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerDaysOfWeekView.m b/Example/RSDayFlowExample/RSDFCustomDatePickerDaysOfWeekView.m new file mode 100644 index 0000000..424e3bf --- /dev/null +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerDaysOfWeekView.m @@ -0,0 +1,40 @@ +// +// RSDFCustomDatePickerDaysOfWeekView.m +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "RSDFCustomDatePickerDaysOfWeekView.h" + +@implementation RSDFCustomDatePickerDaysOfWeekView + +- (UIColor *)selfBackgroundColor +{ + return [UIColor colorWithRed:244/255.0f green:245/255.0f blue:247/255.0f alpha:1.0f]; +} + +- (UIColor *)dayOffOfWeekLabelTextColor +{ + return [UIColor blackColor]; +} + +@end diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerMonthHeader.h b/Example/RSDayFlowExample/RSDFCustomDatePickerMonthHeader.h new file mode 100644 index 0000000..5e95ad5 --- /dev/null +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerMonthHeader.h @@ -0,0 +1,30 @@ +// +// RSDFCustomDatePickerMonthHeader.h +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "RSDFDatePickerMonthHeader.h" + +@interface RSDFCustomDatePickerMonthHeader : RSDFDatePickerMonthHeader + +@end diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerMonthHeader.m b/Example/RSDayFlowExample/RSDFCustomDatePickerMonthHeader.m new file mode 100644 index 0000000..0ea987f --- /dev/null +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerMonthHeader.m @@ -0,0 +1,50 @@ +// +// RSDFCustomDatePickerMonthHeader.m +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "RSDFCustomDatePickerMonthHeader.h" + +@implementation RSDFCustomDatePickerMonthHeader + +- (UIColor *)selfBackgroundColor +{ + return [UIColor colorWithRed:244/255.0f green:245/255.0f blue:247/255.0f alpha:1.0f]; +} + +- (UIFont *)monthLabelFont +{ + return [UIFont fontWithName:@"Avenir-Medium" size:18.0f]; +} + +- (UIColor *)monthLabelTextColor +{ + return [UIColor colorWithRed:51/255.0f green:37/255.0f blue:36/255.0f alpha:1.0f]; +} + +- (UIColor *)currentMonthLabelTextColor +{ + return [UIColor colorWithRed:3/255.0f green:117/255.0f blue:214/255.0f alpha:1.0f]; +} + +@end diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerView.h b/Example/RSDayFlowExample/RSDFCustomDatePickerView.h new file mode 100644 index 0000000..0216e10 --- /dev/null +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerView.h @@ -0,0 +1,30 @@ +// +// RSDFCustomDatePickerView.h +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "RSDFDatePickerView.h" + +@interface RSDFCustomDatePickerView : RSDFDatePickerView + +@end diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerView.m b/Example/RSDayFlowExample/RSDFCustomDatePickerView.m new file mode 100644 index 0000000..72d8e1d --- /dev/null +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerView.m @@ -0,0 +1,60 @@ +// +// RSDFCustomDatePickerView.m +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "RSDFCustomDatePickerView.h" +#import "RSDFCustomDatePickerDaysOfWeekView.h" +#import "RSDFCustomDatePickerCollectionView.h" +#import "RSDFCustomDatePickerCollectionViewLayout.h" +#import "RSDFCustomDatePickerMonthHeader.h" +#import "RSDFCustomDatePickerDayCell.h" + +@implementation RSDFCustomDatePickerView + +- (Class)daysOfWeekViewClass +{ + return [RSDFCustomDatePickerDaysOfWeekView class]; +} + +- (Class)collectionViewClass +{ + return [RSDFCustomDatePickerCollectionView class]; +} + +- (Class)collectionViewLayoutClass +{ + return [RSDFCustomDatePickerCollectionViewLayout class]; +} + +- (Class)monthHeaderClass +{ + return [RSDFCustomDatePickerMonthHeader class]; +} + +- (Class)dayCellClass +{ + return [RSDFCustomDatePickerDayCell class]; +} + +@end diff --git a/Example/RSDayFlowExample/RSDFDatePickerViewController.h b/Example/RSDayFlowExample/RSDFDatePickerViewController.h index 93cf473..c555ef4 100755 --- a/Example/RSDayFlowExample/RSDFDatePickerViewController.h +++ b/Example/RSDayFlowExample/RSDFDatePickerViewController.h @@ -29,6 +29,4 @@ @interface RSDFDatePickerViewController : UIViewController -@property (strong, readonly, nonatomic) RSDFDatePickerView *datePickerView; - @end diff --git a/Example/RSDayFlowExample/RSDFDatePickerViewController.m b/Example/RSDayFlowExample/RSDFDatePickerViewController.m index 3a73a2b..9775398 100755 --- a/Example/RSDayFlowExample/RSDFDatePickerViewController.m +++ b/Example/RSDayFlowExample/RSDFDatePickerViewController.m @@ -25,15 +25,18 @@ #import "RSDFDatePickerViewController.h" #import "RSDFDatePickerView.h" +#import "RSDFCustomDatePickerView.h" @interface RSDFDatePickerViewController() +@property (strong, nonatomic) NSDictionary *markedDates; +@property (strong, nonatomic) RSDFDatePickerView *datePickerView; +@property (strong, nonatomic) RSDFCustomDatePickerView *customDatePickerView; + @end @implementation RSDFDatePickerViewController -@synthesize datePickerView = _datePickerView; - #pragma mark - Lifecycle - (void) viewDidLoad @@ -57,12 +60,41 @@ - (void) viewDidLoad UIBarButtonItem *today = [[UIBarButtonItem alloc] initWithTitle:@"Today" style:UIBarButtonItemStyleBordered target:self action:@selector(onTodayButtonTouch:)]; self.navigationItem.rightBarButtonItem = today; + UIBarButtonItem *restyle = [[UIBarButtonItem alloc] initWithTitle:@"Restyle" style:UIBarButtonItemStyleBordered target:self action:@selector(onRestyleButtonTouch:)]; + self.navigationItem.leftBarButtonItem = restyle; + self.view.backgroundColor = [UIColor colorWithWhite:0.8 alpha:0.3]; [self.view addSubview:self.datePickerView]; } #pragma mark - Custom Accessors +- (NSDictionary *)markedDates +{ + if (!_markedDates) { + NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; + NSDateComponents *todayComponents = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]]; + NSDate *today = [calendar dateFromComponents:todayComponents]; + + NSArray *numberOfDaysFromToday = @[@(-8), @(-2), @(-1), @(0), @(2), @(4), @(8), @(13), @(22)]; + + NSDateComponents *dateComponents = [[NSDateComponents alloc] init]; + NSMutableDictionary *markedDates = [[NSMutableDictionary alloc] initWithCapacity:[numberOfDaysFromToday count]]; + [numberOfDaysFromToday enumerateObjectsUsingBlock:^(NSNumber *numberOfDays, NSUInteger idx, BOOL *stop) { + dateComponents.day = [numberOfDays integerValue]; + NSDate *date = [calendar dateByAddingComponents:dateComponents toDate:today options:0]; + if ([date compare:today] == NSOrderedAscending) { + markedDates[date] = @YES; + } else { + markedDates[date] = @NO; + } + }]; + + _markedDates = [markedDates copy]; + } + return _markedDates; +} + - (RSDFDatePickerView *)datePickerView { if (!_datePickerView) { @@ -74,11 +106,39 @@ - (RSDFDatePickerView *)datePickerView return _datePickerView; } +- (RSDFCustomDatePickerView *)customDatePickerView +{ + if (!_customDatePickerView) { + _customDatePickerView = [[RSDFCustomDatePickerView alloc] initWithFrame:self.view.bounds]; + _customDatePickerView.delegate = self; + _customDatePickerView.dataSource = self; + _customDatePickerView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + } + return _customDatePickerView; +} + #pragma mark - Action handling - (void)onTodayButtonTouch:(UIBarButtonItem *)sender { - [self.datePickerView scrollToToday:YES]; + if (self.datePickerView.superview) { + [self.datePickerView scrollToToday:YES]; + } else { + [self.customDatePickerView scrollToToday:YES]; + } +} + +- (void)onRestyleButtonTouch:(UIBarButtonItem *)sender +{ + if (self.datePickerView.superview) { + self.navigationController.navigationBar.barTintColor = [UIColor colorWithRed:244/255.0f green:245/255.0f blue:247/255.0f alpha:1.0f]; + [self.datePickerView removeFromSuperview]; + [self.view addSubview:self.customDatePickerView]; + } else { + self.navigationController.navigationBar.barTintColor = [UIColor colorWithRed:248/255.0f green:248/255.0f blue:248/255.0f alpha:1.0f]; + [self.customDatePickerView removeFromSuperview]; + [self.view addSubview:self.datePickerView]; + } } #pragma mark - RSDFDatePickerViewDelegate @@ -92,25 +152,7 @@ - (void)datePickerView:(RSDFDatePickerView *)view didSelectDate:(NSDate *)date - (NSDictionary *)datePickerViewMarkedDates:(RSDFDatePickerView *)view { - NSCalendar *calendar = [NSCalendar currentCalendar]; - NSDateComponents *todayComponents = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]]; - NSDate *today = [calendar dateFromComponents:todayComponents]; - - NSArray *numberOfDaysFromToday = @[@(-8), @(-2), @(-1), @(0), @(2), @(4), @(8), @(13), @(22)]; - - NSDateComponents *dateComponents = [[NSDateComponents alloc] init]; - NSMutableDictionary *markedDates = [[NSMutableDictionary alloc] initWithCapacity:[numberOfDaysFromToday count]]; - [numberOfDaysFromToday enumerateObjectsUsingBlock:^(NSNumber *numberOfDays, NSUInteger idx, BOOL *stop) { - dateComponents.day = [numberOfDays integerValue]; - NSDate *date = [calendar dateByAddingComponents:dateComponents toDate:today options:0]; - if ([date compare:today] == NSOrderedAscending) { - markedDates[date] = @YES; - } else { - markedDates[date] = @NO; - } - }]; - - return [markedDates copy]; + return self.markedDates; } @end From 36a1ef0454be4fe9ec1c8b75e66af67c4d1e2d67 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 19 Aug 2014 21:23:37 +0300 Subject: [PATCH 32/87] [Add] Copyrights to the code. --- RSDayFlow/NSCalendar+RSDFAdditions.h | 25 +++++++++++++++++++ RSDayFlow/NSCalendar+RSDFAdditions.m | 25 +++++++++++++++++++ RSDayFlow/RSDFDatePickerCollectionView.h | 25 +++++++++++++++++++ RSDayFlow/RSDFDatePickerCollectionView.m | 25 +++++++++++++++++++ .../RSDFDatePickerCollectionViewLayout.h | 25 +++++++++++++++++++ .../RSDFDatePickerCollectionViewLayout.m | 25 +++++++++++++++++++ RSDayFlow/RSDFDatePickerDayCell.h | 25 +++++++++++++++++++ RSDayFlow/RSDFDatePickerDayCell.m | 25 +++++++++++++++++++ RSDayFlow/RSDFDatePickerDaysOfWeekView.h | 25 +++++++++++++++++++ RSDayFlow/RSDFDatePickerDaysOfWeekView.m | 25 +++++++++++++++++++ RSDayFlow/RSDFDatePickerMonthHeader.h | 25 +++++++++++++++++++ RSDayFlow/RSDFDatePickerMonthHeader.m | 25 +++++++++++++++++++ RSDayFlow/RSDFDatePickerView.h | 25 +++++++++++++++++++ RSDayFlow/RSDFDatePickerView.m | 25 +++++++++++++++++++ RSDayFlow/RSDayFlow.h | 25 +++++++++++++++++++ 15 files changed, 375 insertions(+) diff --git a/RSDayFlow/NSCalendar+RSDFAdditions.h b/RSDayFlow/NSCalendar+RSDFAdditions.h index 2503446..7b9e0c4 100644 --- a/RSDayFlow/NSCalendar+RSDFAdditions.h +++ b/RSDayFlow/NSCalendar+RSDFAdditions.h @@ -1,3 +1,28 @@ +// +// NSCalendar+RSDFAdditions.h +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + #import @interface NSCalendar (RSDFAdditions) diff --git a/RSDayFlow/NSCalendar+RSDFAdditions.m b/RSDayFlow/NSCalendar+RSDFAdditions.m index 7ce902d..9d0b55e 100644 --- a/RSDayFlow/NSCalendar+RSDFAdditions.m +++ b/RSDayFlow/NSCalendar+RSDFAdditions.m @@ -1,3 +1,28 @@ +// +// NSCalendar+RSDFAdditions.m +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + #import "NSCalendar+RSDFAdditions.h" @implementation NSCalendar (RSDFAdditions) diff --git a/RSDayFlow/RSDFDatePickerCollectionView.h b/RSDayFlow/RSDFDatePickerCollectionView.h index 8e515d3..218ed95 100644 --- a/RSDayFlow/RSDFDatePickerCollectionView.h +++ b/RSDayFlow/RSDFDatePickerCollectionView.h @@ -1,3 +1,28 @@ +// +// RSDFDatePickerCollectionView.h +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + #import @class RSDFDatePickerCollectionView; diff --git a/RSDayFlow/RSDFDatePickerCollectionView.m b/RSDayFlow/RSDFDatePickerCollectionView.m index d852358..7ec5e0c 100644 --- a/RSDayFlow/RSDFDatePickerCollectionView.m +++ b/RSDayFlow/RSDFDatePickerCollectionView.m @@ -1,3 +1,28 @@ +// +// RSDFDatePickerCollectionView.m +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + #import "RSDFDatePickerCollectionView.h" #import "RSDFDatePickerCollectionViewLayout.h" diff --git a/RSDayFlow/RSDFDatePickerCollectionViewLayout.h b/RSDayFlow/RSDFDatePickerCollectionViewLayout.h index 3d57afb..b05f873 100644 --- a/RSDayFlow/RSDFDatePickerCollectionViewLayout.h +++ b/RSDayFlow/RSDFDatePickerCollectionViewLayout.h @@ -1,3 +1,28 @@ +// +// RSDFDatePickerCollectionViewLayout.h +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + #import /** diff --git a/RSDayFlow/RSDFDatePickerCollectionViewLayout.m b/RSDayFlow/RSDFDatePickerCollectionViewLayout.m index eeb43f2..6a236e6 100644 --- a/RSDayFlow/RSDFDatePickerCollectionViewLayout.m +++ b/RSDayFlow/RSDFDatePickerCollectionViewLayout.m @@ -1,3 +1,28 @@ +// +// RSDFDatePickerCollectionViewLayout.m +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + #import "RSDFDatePickerCollectionViewLayout.h" @implementation RSDFDatePickerCollectionViewLayout diff --git a/RSDayFlow/RSDFDatePickerDayCell.h b/RSDayFlow/RSDFDatePickerDayCell.h index 52fa5e4..731326a 100644 --- a/RSDayFlow/RSDFDatePickerDayCell.h +++ b/RSDayFlow/RSDFDatePickerDayCell.h @@ -1,3 +1,28 @@ +// +// RSDFDatePickerDayCell.h +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + #import #import "RSDayFlow.h" diff --git a/RSDayFlow/RSDFDatePickerDayCell.m b/RSDayFlow/RSDFDatePickerDayCell.m index 497078a..ed989bd 100644 --- a/RSDayFlow/RSDFDatePickerDayCell.m +++ b/RSDayFlow/RSDFDatePickerDayCell.m @@ -1,3 +1,28 @@ +// +// RSDFDatePickerDayCell.m +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + #import "RSDFDatePickerDayCell.h" @interface RSDFDatePickerDayCell () diff --git a/RSDayFlow/RSDFDatePickerDaysOfWeekView.h b/RSDayFlow/RSDFDatePickerDaysOfWeekView.h index 7e77b7d..9ad61ad 100644 --- a/RSDayFlow/RSDFDatePickerDaysOfWeekView.h +++ b/RSDayFlow/RSDFDatePickerDaysOfWeekView.h @@ -1,3 +1,28 @@ +// +// RSDFDatePickerDaysOfWeekView.h +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + #import /** diff --git a/RSDayFlow/RSDFDatePickerDaysOfWeekView.m b/RSDayFlow/RSDFDatePickerDaysOfWeekView.m index 415e089..d7cf44d 100644 --- a/RSDayFlow/RSDFDatePickerDaysOfWeekView.m +++ b/RSDayFlow/RSDFDatePickerDaysOfWeekView.m @@ -1,3 +1,28 @@ +// +// RSDFDatePickerDaysOfWeekView.m +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + #import "RSDFDatePickerDaysOfWeekView.h" #import "NSCalendar+RSDFAdditions.h" diff --git a/RSDayFlow/RSDFDatePickerMonthHeader.h b/RSDayFlow/RSDFDatePickerMonthHeader.h index 3b45090..9ef3a06 100644 --- a/RSDayFlow/RSDFDatePickerMonthHeader.h +++ b/RSDayFlow/RSDFDatePickerMonthHeader.h @@ -1,3 +1,28 @@ +// +// RSDFDatePickerMonthHeader.h +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + #import #import "RSDayFlow.h" diff --git a/RSDayFlow/RSDFDatePickerMonthHeader.m b/RSDayFlow/RSDFDatePickerMonthHeader.m index 3d68154..6fe9e63 100644 --- a/RSDayFlow/RSDFDatePickerMonthHeader.m +++ b/RSDayFlow/RSDFDatePickerMonthHeader.m @@ -1,3 +1,28 @@ +// +// RSDFDatePickerMonthHeader.m +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + #import "RSDFDatePickerMonthHeader.h" @implementation RSDFDatePickerMonthHeader diff --git a/RSDayFlow/RSDFDatePickerView.h b/RSDayFlow/RSDFDatePickerView.h index 19cc75f..1128b87 100644 --- a/RSDayFlow/RSDFDatePickerView.h +++ b/RSDayFlow/RSDFDatePickerView.h @@ -1,3 +1,28 @@ +// +// RSDFDatePickerView.h +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + #import @protocol RSDFDatePickerViewDelegate; diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index 86b71a1..6a797ab 100644 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -1,3 +1,28 @@ +// +// RSDFDatePickerView.m +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + #import #import "RSDayFlow.h" #import "RSDFDatePickerCollectionView.h" diff --git a/RSDayFlow/RSDayFlow.h b/RSDayFlow/RSDayFlow.h index 391216e..249ccc9 100644 --- a/RSDayFlow/RSDayFlow.h +++ b/RSDayFlow/RSDayFlow.h @@ -1,3 +1,28 @@ +// +// RSDayFlow.h +// +// Copyright (c) 2013 Evadne Wu, http://radi.ws/ +// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + /** `RSDayFlow` is an iOS 7 Calendar with Infinite Scrolling. */ From 5f5db01d88dea373ffc54ea023fb38c410d8d89d Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 19 Aug 2014 21:25:30 +0300 Subject: [PATCH 33/87] [Update] README. --- README.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index fb8cda6..823e6d7 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Import the class header. Just create your date picker view and set a delegate / a data source if needed. ``` objective-c -- (void) viewDidLoad +- (void)viewDidLoad { [super viewDidLoad]; @@ -84,16 +84,20 @@ Then implement the data source function. } ``` -## Coming Soon +## Customization + +Every view is customizable to fit your need. +Create a subclass of the desired view and override the default values. -- Make the code more documented -- Make every view maximum customizable +## Coming Soon +- Add support for any of the calendars `NSCalendar` supports. - If you would like to request a new feature, feel free to raise as an issue. ## Demo -Look at the [Sample App](https://github.com/ruslanskorb/RSDayFlow-Sample). Have fun. Make it faster. Fork and send pull requests. Figure out hooks for customization. +Build and run the `RSDayFlowExample` project in Xcode to see `RSDayFlow` in action. +Have fun. Make it faster. Fork and send pull requests. Figure out hooks for customization. ## Contact @@ -102,7 +106,6 @@ Ruslan Skorb - http://github.com/ruslanskorb - http://twitter.com/ruslanskorb -- http://lnkd.in/gsBbvb - ruslan.skorb@gmail.com ## License From ba6ea3c6ffcdb3ca29d8f896d7bcd613122fbc05 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 19 Aug 2014 21:28:26 +0300 Subject: [PATCH 34/87] Version bump (0.3.0) --- Example/RSDayFlowExample/RSDayFlowExample-Info.plist | 4 ++-- RSDayFlow.podspec | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist index 867d386..2e18822 100644 --- a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist +++ b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.2.0 + 0.3.0 CFBundleSignature ???? CFBundleVersion - 0.2.0 + 0.3.0 LSRequiresIPhoneOS UIRequiredDeviceCapabilities diff --git a/RSDayFlow.podspec b/RSDayFlow.podspec index ed5472b..f9b93a2 100644 --- a/RSDayFlow.podspec +++ b/RSDayFlow.podspec @@ -1,11 +1,11 @@ Pod::Spec.new do |s| s.name = 'RSDayFlow' - s.version = '0.2.0' - s.summary = 'Scrollable iOS 7 Date Picker.' + s.version = '0.3.0' + s.summary = 'iOS 7 Calendar with Infinite Scrolling.' s.homepage = 'https://github.com/ruslanskorb/RSDayFlow' s.license = { :type => 'MIT', :file => 'LICENSE' } s.authors = { 'Evadne Wu' => 'ev@radi.ws', 'Ruslan Skorb' => 'ruslan.skorb@gmail.com' } - s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.2.0' } + s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.3.0' } s.platform = :ios, '7.0' s.source_files = 'RSDayFlow' s.frameworks = 'QuartzCore', 'UIKit' From 5d3f47f3f00ac88ca5ab2829fbc21a6591128bf7 Mon Sep 17 00:00:00 2001 From: ndmeiri Date: Tue, 19 Aug 2014 17:30:06 -0700 Subject: [PATCH 35/87] Fix code sample --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 823e6d7..2db4238 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ Then implement the data source function. NSDate *today = [NSDate date]; NSNumber *isCompletedAllTasks = @(NO); NSDictionary *dates = @{today: isCompletedAllTasks}; - return markedDates; + return dates; } ``` From 4d0ca20210ddfca76f8c6d9331d683b903a82a76 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Sat, 23 Aug 2014 21:39:53 +0300 Subject: [PATCH 36/87] [Fix] Deprecation of `NSDateComponents.week`. `NSDateComponents.week` was deprecated in iOS8, changed to `weekOfYear`. --- RSDayFlow/RSDFDatePickerView.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index 6a797ab..a15dd1c 100644 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -394,7 +394,7 @@ - (NSUInteger)numberOfWeeksForMonthOfDate:(NSDate *)date return dateComponents; })())]; - return 1 + [self.calendar components:NSWeekCalendarUnit fromDate:fromSunday toDate:toSunday options:0].week; + return 1 + [self.calendar components:NSWeekOfYearCalendarUnit fromDate:fromSunday toDate:toSunday options:0].weekOfYear; } - (NSDate *)dateFromPickerDate:(RSDFDatePickerDate)dateStruct From c0611b7bbd7263b362ffaf7823b06d6318240d08 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Mon, 25 Aug 2014 22:18:11 +0300 Subject: [PATCH 37/87] [Fix] Close #12. Automatic update of the current day when it's 12:00 am. --- RSDayFlow/RSDFDatePickerView.m | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index a15dd1c..1bcf467 100644 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -108,6 +108,12 @@ - (void)willMoveToSuperview:(UIView *)newSuperview UICollectionView *cv = self.collectionView; [cv layoutIfNeeded]; } + + if (newSuperview && !self.superview) { + [self registerForNotifications]; + } else if (!newSuperview) { + [self unregisterForNotifications]; + } } #pragma mark - Custom Accessors @@ -421,6 +427,31 @@ - (RSDFDatePickerDate)pickerDateFromDate:(NSDate *)date }; } +#pragma mark - Notifications + +- (void)registerForNotifications +{ + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(significantTimeChange:) + name:UIApplicationSignificantTimeChangeNotification + object:nil]; +} + +- (void)unregisterForNotifications +{ + [[NSNotificationCenter defaultCenter] removeObserver:self + name:UIApplicationSignificantTimeChangeNotification + object:nil]; +} + +- (void)significantTimeChange:(NSNotification *)notification +{ + NSDateComponents *todayYearMonthDayComponents = [self.calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]]; + _today = [self.calendar dateFromComponents:todayYearMonthDayComponents]; + + [self.collectionView reloadData]; +} + #pragma mark - UICollectionViewDataSource - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView From 3da0770ae49854503ae34e402e80ee9e382e024c Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Mon, 25 Aug 2014 22:26:30 +0300 Subject: [PATCH 38/87] Version bump (0.3.1) --- Example/RSDayFlowExample/RSDayFlowExample-Info.plist | 4 ++-- RSDayFlow.podspec | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist index 2e18822..4cc703e 100644 --- a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist +++ b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.3.0 + 0.3.1 CFBundleSignature ???? CFBundleVersion - 0.3.0 + 0.3.1 LSRequiresIPhoneOS UIRequiredDeviceCapabilities diff --git a/RSDayFlow.podspec b/RSDayFlow.podspec index f9b93a2..321d776 100644 --- a/RSDayFlow.podspec +++ b/RSDayFlow.podspec @@ -1,11 +1,11 @@ Pod::Spec.new do |s| s.name = 'RSDayFlow' - s.version = '0.3.0' + s.version = '0.3.1' s.summary = 'iOS 7 Calendar with Infinite Scrolling.' s.homepage = 'https://github.com/ruslanskorb/RSDayFlow' s.license = { :type => 'MIT', :file => 'LICENSE' } s.authors = { 'Evadne Wu' => 'ev@radi.ws', 'Ruslan Skorb' => 'ruslan.skorb@gmail.com' } - s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.3.0' } + s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.3.1' } s.platform = :ios, '7.0' s.source_files = 'RSDayFlow' s.frameworks = 'QuartzCore', 'UIKit' From ec8f1bf071fcef1731efdbfa62f6e3cae6db6aec Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 26 Aug 2014 12:43:51 +0300 Subject: [PATCH 39/87] [Update] Handling Notifications. #12 --- RSDayFlow/RSDFDatePickerView.m | 57 ++++++++++++++-------------------- 1 file changed, 23 insertions(+), 34 deletions(-) diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index 1bcf467..a2727e6 100644 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -62,11 +62,16 @@ @implementation RSDFDatePickerView #pragma mark - Lifecycle +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + - (instancetype)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { - [self configureCalendar]; + [self commonInitializer]; } return self; } @@ -75,7 +80,7 @@ - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { - [self configureCalendar]; + [self commonInitializer]; } return self; } @@ -108,12 +113,6 @@ - (void)willMoveToSuperview:(UIView *)newSuperview UICollectionView *cv = self.collectionView; [cv layoutIfNeeded]; } - - if (newSuperview && !self.superview) { - [self registerForNotifications]; - } else if (!newSuperview) { - [self unregisterForNotifications]; - } } #pragma mark - Custom Accessors @@ -200,6 +199,16 @@ - (Class)dayCellClass return [RSDFDatePickerDayCell class]; } +#pragma mark - Handling Notifications + +- (void)significantTimeChange:(NSNotification *)notification +{ + NSDateComponents *todayYearMonthDayComponents = [self.calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]]; + _today = [self.calendar dateFromComponents:todayYearMonthDayComponents]; + + [self.collectionView reloadData]; +} + #pragma mark - Public - (void)scrollToToday:(BOOL)animated @@ -249,7 +258,7 @@ - (void)reloadData #pragma mark - Private -- (void)configureCalendar +- (void)commonInitializer { NSDateComponents *nowYearMonthComponents = [self.calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit) fromDate:[NSDate date]]; NSDate *now = [self.calendar dateFromComponents:nowYearMonthComponents]; @@ -268,6 +277,11 @@ - (void)configureCalendar NSDateComponents *todayYearMonthDayComponents = [self.calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]]; _today = [self.calendar dateFromComponents:todayYearMonthDayComponents]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(significantTimeChange:) + name:UIApplicationSignificantTimeChangeNotification + object:nil]; } - (void)appendPastDates @@ -427,31 +441,6 @@ - (RSDFDatePickerDate)pickerDateFromDate:(NSDate *)date }; } -#pragma mark - Notifications - -- (void)registerForNotifications -{ - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(significantTimeChange:) - name:UIApplicationSignificantTimeChangeNotification - object:nil]; -} - -- (void)unregisterForNotifications -{ - [[NSNotificationCenter defaultCenter] removeObserver:self - name:UIApplicationSignificantTimeChangeNotification - object:nil]; -} - -- (void)significantTimeChange:(NSNotification *)notification -{ - NSDateComponents *todayYearMonthDayComponents = [self.calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]]; - _today = [self.calendar dateFromComponents:todayYearMonthDayComponents]; - - [self.collectionView reloadData]; -} - #pragma mark - UICollectionViewDataSource - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView From a09a4f4541f5becb6ff4eaafadb93a329048b02f Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 26 Aug 2014 21:42:26 +0300 Subject: [PATCH 40/87] [Add] Support for any of the calendars NSCalendar supports. --- Example/RSDayFlowExample/RSDFAppDelegate.m | 78 ++++++++++++------- .../RSDFDatePickerViewController.h | 2 + .../RSDFDatePickerViewController.m | 31 ++++++-- RSDayFlow/RSDFDatePickerDaysOfWeekView.m | 7 +- RSDayFlow/RSDFDatePickerView.h | 8 ++ RSDayFlow/RSDFDatePickerView.m | 74 +++++++++++++++--- 6 files changed, 149 insertions(+), 51 deletions(-) diff --git a/Example/RSDayFlowExample/RSDFAppDelegate.m b/Example/RSDayFlowExample/RSDFAppDelegate.m index 0aeddc6..12ccc22 100644 --- a/Example/RSDayFlowExample/RSDFAppDelegate.m +++ b/Example/RSDayFlowExample/RSDFAppDelegate.m @@ -33,40 +33,58 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.window.backgroundColor = [UIColor whiteColor]; - RSDFDatePickerViewController *datePickerVC = [[RSDFDatePickerViewController alloc] init]; - UINavigationController *rootNC = [[UINavigationController alloc] initWithRootViewController:datePickerVC]; - self.window.rootViewController = rootNC; + // ------------------ + // Gregorian calendar + // ------------------ + + RSDFDatePickerViewController *gregorianVC = [[RSDFDatePickerViewController alloc] init]; + gregorianVC.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; + gregorianVC.calendar.locale = [NSLocale currentLocale]; + UINavigationController *gregorianNC = [[UINavigationController alloc] initWithRootViewController:gregorianVC]; + + // --------------- + // Hebrew calendar + // --------------- + + RSDFDatePickerViewController *hebrewVC = [[RSDFDatePickerViewController alloc] init]; + hebrewVC.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSHebrewCalendar]; + hebrewVC.calendar.locale = [NSLocale currentLocale]; + UINavigationController *hebrewNC = [[UINavigationController alloc] initWithRootViewController:hebrewVC]; + + // ---------------- + // Islamic calendar + // ---------------- + + RSDFDatePickerViewController *islamicVC = [[RSDFDatePickerViewController alloc] init]; + islamicVC.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSIslamicCalendar]; + islamicVC.calendar.locale = [NSLocale currentLocale]; + UINavigationController *islamicNC = [[UINavigationController alloc] initWithRootViewController:islamicVC]; + + // --------------- + // Indian calendar + // --------------- + + RSDFDatePickerViewController *indianVC = [[RSDFDatePickerViewController alloc] init]; + indianVC.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSIndianCalendar]; + indianVC.calendar.locale = [NSLocale currentLocale]; + UINavigationController *indianNC = [[UINavigationController alloc] initWithRootViewController:indianVC]; + + // ---------------- + // Persian calendar + // ---------------- + + RSDFDatePickerViewController *persianVC = [[RSDFDatePickerViewController alloc] init]; + persianVC.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSPersianCalendar]; + persianVC.calendar.locale = [NSLocale currentLocale]; + UINavigationController *persianNC = [[UINavigationController alloc] initWithRootViewController:persianVC]; + + UITabBarController *tabBarController = [[UITabBarController alloc] init]; + tabBarController.viewControllers = @[gregorianNC, hebrewNC, islamicNC, indianNC, persianNC]; + self.window.rootViewController = tabBarController; [self.window makeKeyAndVisible]; return YES; } -- (void)applicationWillResignActive:(UIApplication *)application -{ - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication *)application -{ - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication *)application -{ - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application -{ - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication *)application -{ - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - @end diff --git a/Example/RSDayFlowExample/RSDFDatePickerViewController.h b/Example/RSDayFlowExample/RSDFDatePickerViewController.h index c555ef4..6efcbfa 100755 --- a/Example/RSDayFlowExample/RSDFDatePickerViewController.h +++ b/Example/RSDayFlowExample/RSDFDatePickerViewController.h @@ -29,4 +29,6 @@ @interface RSDFDatePickerViewController : UIViewController +@property (strong, nonatomic) NSCalendar *calendar; + @end diff --git a/Example/RSDayFlowExample/RSDFDatePickerViewController.m b/Example/RSDayFlowExample/RSDFDatePickerViewController.m index 9775398..8fae62f 100755 --- a/Example/RSDayFlowExample/RSDFDatePickerViewController.m +++ b/Example/RSDayFlowExample/RSDFDatePickerViewController.m @@ -30,6 +30,7 @@ @interface RSDFDatePickerViewController() @property (strong, nonatomic) NSDictionary *markedDates; +@property (strong, nonatomic) NSDateFormatter *dateFormatter; @property (strong, nonatomic) RSDFDatePickerView *datePickerView; @property (strong, nonatomic) RSDFCustomDatePickerView *customDatePickerView; @@ -39,15 +40,13 @@ @implementation RSDFDatePickerViewController #pragma mark - Lifecycle -- (void) viewDidLoad +- (void)viewDidLoad { [super viewDidLoad]; self.edgesForExtendedLayout = UIRectEdgeNone; self.automaticallyAdjustsScrollViewInsets = NO; - self.navigationItem.title = @"RSDayFlow"; - self.navigationController.navigationBar.translucent = NO; self.navigationController.navigationBar.opaque = YES; self.navigationController.navigationBar.barTintColor = [UIColor colorWithRed:248/255.0f green:248/255.0f blue:248/255.0f alpha:1.0f]; @@ -69,6 +68,15 @@ - (void) viewDidLoad #pragma mark - Custom Accessors +- (void)setCalendar:(NSCalendar *)calendar +{ + if (![_calendar isEqual:calendar]) { + _calendar = calendar; + + self.title = [_calendar.calendarIdentifier capitalizedString]; + } +} + - (NSDictionary *)markedDates { if (!_markedDates) { @@ -95,10 +103,21 @@ - (NSDictionary *)markedDates return _markedDates; } +- (NSDateFormatter *)dateFormatter +{ + if (!_dateFormatter) { + _dateFormatter = [[NSDateFormatter alloc] init]; + [_dateFormatter setCalendar:self.calendar]; + [_dateFormatter setLocale:[self.calendar locale]]; + [_dateFormatter setDateStyle:NSDateFormatterFullStyle]; + } + return _dateFormatter; +} + - (RSDFDatePickerView *)datePickerView { if (!_datePickerView) { - _datePickerView = [[RSDFDatePickerView alloc] initWithFrame:self.view.bounds]; + _datePickerView = [[RSDFDatePickerView alloc] initWithFrame:self.view.bounds calendar:self.calendar]; _datePickerView.delegate = self; _datePickerView.dataSource = self; _datePickerView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; @@ -109,7 +128,7 @@ - (RSDFDatePickerView *)datePickerView - (RSDFCustomDatePickerView *)customDatePickerView { if (!_customDatePickerView) { - _customDatePickerView = [[RSDFCustomDatePickerView alloc] initWithFrame:self.view.bounds]; + _customDatePickerView = [[RSDFCustomDatePickerView alloc] initWithFrame:self.view.bounds calendar:self.calendar]; _customDatePickerView.delegate = self; _customDatePickerView.dataSource = self; _customDatePickerView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; @@ -145,7 +164,7 @@ - (void)onRestyleButtonTouch:(UIBarButtonItem *)sender - (void)datePickerView:(RSDFDatePickerView *)view didSelectDate:(NSDate *)date { - [[[UIAlertView alloc] initWithTitle:@"Picked Date" message:[date description] delegate:nil cancelButtonTitle:@":D" otherButtonTitles:nil] show]; + [[[UIAlertView alloc] initWithTitle:@"Picked Date" message:[self.dateFormatter stringFromDate:date] delegate:nil cancelButtonTitle:@":D" otherButtonTitles:nil] show]; } #pragma mark - RSDFDatePickerViewDataSource diff --git a/RSDayFlow/RSDFDatePickerDaysOfWeekView.m b/RSDayFlow/RSDFDatePickerDaysOfWeekView.m index d7cf44d..25cb695 100644 --- a/RSDayFlow/RSDFDatePickerDaysOfWeekView.m +++ b/RSDayFlow/RSDFDatePickerDaysOfWeekView.m @@ -95,10 +95,11 @@ - (void)commonInitializer CGFloat y = 0; __block CGFloat x = 0; - NSDateFormatter *dateFormatter = [self.calendar df_dateFormatterNamed:@"calendarDaysOfWeekView" withConstructor:^{ + NSString *dateFormatterName = [NSString stringWithFormat:@"calendarDaysOfWeekView_%@_%@", [self.calendar calendarIdentifier], [[self.calendar locale] localeIdentifier]]; + NSDateFormatter *dateFormatter = [self.calendar df_dateFormatterNamed:dateFormatterName withConstructor:^{ NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; - dateFormatter.calendar = self.calendar; - dateFormatter.locale = [self.calendar locale]; + [dateFormatter setCalendar:self.calendar]; + [dateFormatter setLocale:[self.calendar locale]]; return dateFormatter; }]; diff --git a/RSDayFlow/RSDFDatePickerView.h b/RSDayFlow/RSDFDatePickerView.h index 1128b87..4c90ab5 100644 --- a/RSDayFlow/RSDFDatePickerView.h +++ b/RSDayFlow/RSDFDatePickerView.h @@ -33,6 +33,14 @@ */ @interface RSDFDatePickerView : UIView +/** + Designated initializer. Initializes and returns a newly allocated view object with the specified frame rectangle and the specified calendar. + + @param frame The frame rectangle for the view, measured in points. + @param calendar The calendar for the date picker view. + */ +- (instancetype)initWithFrame:(CGRect)frame calendar:(NSCalendar *)calendar; + ///----------------------------- /// @name Accessing the Delegate ///----------------------------- diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index a2727e6..c23e90e 100644 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -48,6 +48,7 @@ @interface RSDFDatePickerView () Date: Tue, 26 Aug 2014 21:51:35 +0300 Subject: [PATCH 41/87] [Update] Replace the property 'enabled' by the property 'notThisMonth'. RSDFDatePickerDayCell --- RSDayFlow/RSDFDatePickerDayCell.h | 6 +++--- RSDayFlow/RSDFDatePickerDayCell.m | 15 ++++++++++----- RSDayFlow/RSDFDatePickerView.m | 8 ++++---- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/RSDayFlow/RSDFDatePickerDayCell.h b/RSDayFlow/RSDFDatePickerDayCell.h index 731326a..b7c0288 100644 --- a/RSDayFlow/RSDFDatePickerDayCell.h +++ b/RSDayFlow/RSDFDatePickerDayCell.h @@ -50,11 +50,11 @@ @property (nonatomic, readwrite, assign) RSDFDatePickerDate date; /** - A Boolean value that determines whether the cell's day is enabled. + A Boolean value that determines whether the cell's day that's not this month. - @discussion Cells with inactive days do not display the content. + @discussion Cells with these days do not display the today image, the overlay image, the marks and the divider image. */ -@property (nonatomic, getter = isEnabled) BOOL enabled; +@property (nonatomic, getter = isNotThisMonth) BOOL notThisMonth; /** A Boolean value that determines whether the cell's day is day off. diff --git a/RSDayFlow/RSDFDatePickerDayCell.m b/RSDayFlow/RSDFDatePickerDayCell.m index ed989bd..5370c13 100644 --- a/RSDayFlow/RSDFDatePickerDayCell.m +++ b/RSDayFlow/RSDFDatePickerDayCell.m @@ -89,15 +89,20 @@ - (void)setDate:(RSDFDatePickerDate)date _date = date; } -- (void)setEnabled:(BOOL)enabled +- (void)setNotThisMonth:(BOOL)notThisMonth { - _enabled = enabled; - if (!_enabled) { + _notThisMonth = notThisMonth; + if (_notThisMonth) { self.todayImageView.hidden = YES; self.markImageView.hidden = YES; + self.dateLabel.hidden = YES; + self.dividerImageView.hidden = YES; + } else { + self.todayImageView.hidden = !self.today; + self.markImageView.hidden = !self.marked; + self.dateLabel.hidden = NO; + self.dividerImageView.hidden = NO; } - self.dateLabel.hidden = !_enabled; - self.dividerImageView.hidden = !_enabled; } - (void)setDayOff:(BOOL)dayOff diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index c23e90e..b9c52c4 100644 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -520,8 +520,8 @@ - (RSDFDatePickerDayCell *)collectionView:(UICollectionView *)collectionView cel cell.date = cellPickerDate; cell.dateLabel.text = [NSString stringWithFormat:@"%lu", (unsigned long)(cellPickerDate.day)]; - cell.enabled = ((firstDayPickerDate.year == cellPickerDate.year) && (firstDayPickerDate.month == cellPickerDate.month)); - if (cell.enabled) { + cell.notThisMonth = !((firstDayPickerDate.year == cellPickerDate.year) && (firstDayPickerDate.month == cellPickerDate.month)); + if (!cell.isNotThisMonth) { weekday = [self.calendar components:NSWeekdayCalendarUnit fromDate:cellDate].weekday; cell.dayOff = (weekday == 1) || (weekday == 7); @@ -589,12 +589,12 @@ - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView - (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath { - return ((RSDFDatePickerDayCell *)[collectionView cellForItemAtIndexPath:indexPath]).enabled; + return !((RSDFDatePickerDayCell *)[collectionView cellForItemAtIndexPath:indexPath]).isNotThisMonth; } - (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath { - return ((RSDFDatePickerDayCell *)[collectionView cellForItemAtIndexPath:indexPath]).enabled; + return !((RSDFDatePickerDayCell *)[collectionView cellForItemAtIndexPath:indexPath]).isNotThisMonth; } - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath From c7e1111143450e9adb42ed898fcdecfd046549fb Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 26 Aug 2014 22:04:44 +0300 Subject: [PATCH 42/87] [Add] The ability to customize the text color for the label of the day that's not this month. --- RSDayFlow/RSDFDatePickerDayCell.h | 7 +++++++ RSDayFlow/RSDFDatePickerDayCell.m | 19 +++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/RSDayFlow/RSDFDatePickerDayCell.h b/RSDayFlow/RSDFDatePickerDayCell.h index b7c0288..1eceddf 100644 --- a/RSDayFlow/RSDFDatePickerDayCell.h +++ b/RSDayFlow/RSDFDatePickerDayCell.h @@ -112,6 +112,13 @@ */ - (UIColor *)dayOffLabelTextColor; +/** + The text color for the label of the day that's not this month. Default value is [UIColor clearColor]. + + @discussion Can be overridden in subclasses for customization. + */ +- (UIColor *)notThisMonthLabelTextColor; + /** The font for the label of the current day. Default value is [UIFont fontWithName:@"HelveticaNeue-Bold" size:19.0f]. diff --git a/RSDayFlow/RSDFDatePickerDayCell.m b/RSDayFlow/RSDFDatePickerDayCell.m index 5370c13..e3ac8ec 100644 --- a/RSDayFlow/RSDFDatePickerDayCell.m +++ b/RSDayFlow/RSDFDatePickerDayCell.m @@ -93,14 +93,24 @@ - (void)setNotThisMonth:(BOOL)notThisMonth { _notThisMonth = notThisMonth; if (_notThisMonth) { + self.dateLabel.textColor = [self notThisMonthLabelTextColor]; + self.dateLabel.font = [self dayLabelFont]; self.todayImageView.hidden = YES; self.markImageView.hidden = YES; - self.dateLabel.hidden = YES; self.dividerImageView.hidden = YES; } else { + if (!self.isDayOff) { + self.dateLabel.textColor = [self dayLabelTextColor]; + } else { + self.dateLabel.textColor = [self dayOffLabelTextColor]; + } + if (!self.isToday) { + self.dateLabel.font = [self dayLabelFont]; + } else { + self.dateLabel.font = [self todayLabelFont]; + } self.todayImageView.hidden = !self.today; self.markImageView.hidden = !self.marked; - self.dateLabel.hidden = NO; self.dividerImageView.hidden = NO; } } @@ -299,6 +309,11 @@ - (UIColor *)dayOffLabelTextColor return [UIColor colorWithRed:184/255.0f green:184/255.0f blue:184/255.0f alpha:1.0f]; } +- (UIColor *)notThisMonthLabelTextColor +{ + return [UIColor clearColor]; +} + - (UIFont *)todayLabelFont { return [UIFont fontWithName:@"HelveticaNeue-Bold" size:19.0f]; From 12e30dd197a4267ca364dfe685473eefe5a76450 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 26 Aug 2014 22:13:14 +0300 Subject: [PATCH 43/87] [Update] README. Coming Soon. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2db4238..49a03b2 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ Create a subclass of the desired view and override the default values. ## Coming Soon -- Add support for any of the calendars `NSCalendar` supports. +- Add more customization points. - If you would like to request a new feature, feel free to raise as an issue. ## Demo From 7a75f7b7018af43e1c024ab316b69364f4c2cf13 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 26 Aug 2014 22:14:23 +0300 Subject: [PATCH 44/87] Version bump (0.4.0) --- Example/RSDayFlowExample/RSDayFlowExample-Info.plist | 4 ++-- RSDayFlow.podspec | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist index 4cc703e..ad2c17e 100644 --- a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist +++ b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.3.1 + 0.4.0 CFBundleSignature ???? CFBundleVersion - 0.3.1 + 0.4.0 LSRequiresIPhoneOS UIRequiredDeviceCapabilities diff --git a/RSDayFlow.podspec b/RSDayFlow.podspec index 321d776..ca9ab81 100644 --- a/RSDayFlow.podspec +++ b/RSDayFlow.podspec @@ -1,11 +1,11 @@ Pod::Spec.new do |s| s.name = 'RSDayFlow' - s.version = '0.3.1' + s.version = '0.4.0' s.summary = 'iOS 7 Calendar with Infinite Scrolling.' s.homepage = 'https://github.com/ruslanskorb/RSDayFlow' s.license = { :type => 'MIT', :file => 'LICENSE' } s.authors = { 'Evadne Wu' => 'ev@radi.ws', 'Ruslan Skorb' => 'ruslan.skorb@gmail.com' } - s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.3.1' } + s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.4.0' } s.platform = :ios, '7.0' s.source_files = 'RSDayFlow' s.frameworks = 'QuartzCore', 'UIKit' From a4cf39ea58d0ad01bc616b5b9f06b88a052e889d Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Fri, 29 Aug 2014 23:04:04 +0300 Subject: [PATCH 45/87] [Fix] Code sample in the README. --- README.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 49a03b2..9bbc861 100644 --- a/README.md +++ b/README.md @@ -77,10 +77,19 @@ Then implement the data source function. // Returns dates to mark. - (NSDictionary *)datePickerViewMarkedDates:(RSDFDatePickerView *)view { - NSDate *today = [NSDate date]; + // Create an `NSDate` object without time components. + NSCalendar *calendar = [NSCalendar currentCalendar]; + unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit; + NSDateComponents *todayComponents = [calendar components:unitFlags fromDate:[NSDate date]]; + NSDate *today = [calendar dateFromComponents:todayComponents]; + + // Create an `NSNumber` object that determines whether the date is marked. NSNumber *isCompletedAllTasks = @(NO); - NSDictionary *dates = @{today: isCompletedAllTasks}; - return dates; + + // Create a dictionary with the date to mark. + NSDictionary *markedDates = @{today: isCompletedAllTasks}; + + return markedDates; } ``` From 2c23cf99ed365dea2a2e44b65cb6d863cecc6c5a Mon Sep 17 00:00:00 2001 From: dave Date: Mon, 1 Sep 2014 22:05:34 +0200 Subject: [PATCH 46/87] Extracted and exposed scrollToDate:animated method --- RSDayFlow/RSDFDatePickerView.h | 10 +++++- RSDayFlow/RSDFDatePickerView.m | 59 ++++++++++++++++++---------------- 2 files changed, 41 insertions(+), 28 deletions(-) diff --git a/RSDayFlow/RSDFDatePickerView.h b/RSDayFlow/RSDFDatePickerView.h index 4c90ab5..7e3f210 100644 --- a/RSDayFlow/RSDFDatePickerView.h +++ b/RSDayFlow/RSDFDatePickerView.h @@ -65,7 +65,7 @@ @property (nonatomic, readwrite, weak) id dataSource; ///----------------------------------- -/// @name Scrolling to the Current Day +/// @name Scrolling to date ///----------------------------------- /** @@ -76,6 +76,14 @@ - (void)scrollToToday:(BOOL)animated; +/** + Scrolls the date picker view to the given date. + + @param animated YES if you want to animate the change in position, NO if it should be immediate. + */ + +- (void)scrollToDate:(NSDate *)date animated:(BOOL)animated; + ///------------------------- /// @name Reloading the Data ///------------------------- diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index b9c52c4..8ec964e 100644 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -233,40 +233,45 @@ - (void)significantTimeChange:(NSNotification *)notification - (void)scrollToToday:(BOOL)animated { - RSDFDatePickerCollectionView *cv = self.collectionView; + [self scrollToDate:self.today animated:animated]; +} + +- (void)scrollToDate:(NSDate *)date animated:(BOOL)animated +{ + RSDFDatePickerCollectionView *cv = self.collectionView; RSDFDatePickerCollectionViewLayout *cvLayout = (RSDFDatePickerCollectionViewLayout *)self.collectionView.collectionViewLayout; NSArray *visibleCells = [self.collectionView visibleCells]; if (![visibleCells count]) return; - - NSDateComponents *nowYearMonthComponents = [self.calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit) fromDate:[NSDate date]]; - NSDate *now = [self.calendar dateFromComponents:nowYearMonthComponents]; - - _fromDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:((^{ - NSDateComponents *components = [NSDateComponents new]; - components.month = -6; - return components; - })()) toDate:now options:0]]; - - _toDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:((^{ - NSDateComponents *components = [NSDateComponents new]; - components.month = 6; - return components; - })()) toDate:now options:0]]; - - [cv reloadData]; + + NSDateComponents *nowYearMonthComponents = [self.calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit) fromDate:[NSDate date]]; + NSDate *now = [self.calendar dateFromComponents:nowYearMonthComponents]; + + _fromDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:((^{ + NSDateComponents *components = [NSDateComponents new]; + components.month = -6; + return components; + })()) toDate:now options:0]]; + + _toDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:((^{ + NSDateComponents *components = [NSDateComponents new]; + components.month = 6; + return components; + })()) toDate:now options:0]]; + + [cv reloadData]; [cvLayout invalidateLayout]; [cvLayout prepareLayout]; - - NSInteger section = [self sectionForDate:_today]; - - NSDate *firstDayInMonth = [self dateForFirstDayInSection:section]; - NSUInteger weekday = [self.calendar components:NSWeekdayCalendarUnit fromDate:firstDayInMonth].weekday; - NSInteger item = [self.calendar components:NSDayCalendarUnit fromDate:firstDayInMonth toDate:self.today options:0].day + (weekday - self.calendar.firstWeekday); - - NSIndexPath *cellIndexPath = [NSIndexPath indexPathForItem:item inSection:section]; - [self.collectionView scrollToItemAtIndexPath:cellIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:animated]; + + NSInteger section = [self sectionForDate:date]; + + NSDate *firstDayInMonth = [self dateForFirstDayInSection:section]; + NSUInteger weekday = [self.calendar components:NSWeekdayCalendarUnit fromDate:firstDayInMonth].weekday; + NSInteger item = [self.calendar components:NSDayCalendarUnit fromDate:firstDayInMonth toDate:date options:0].day + (weekday - self.calendar.firstWeekday); + + NSIndexPath *cellIndexPath = [NSIndexPath indexPathForItem:item inSection:section]; + [self.collectionView scrollToItemAtIndexPath:cellIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:animated]; } - (void)reloadData From 7eeaae188c263ff215abbcc9c41d391f364938cf Mon Sep 17 00:00:00 2001 From: dave Date: Mon, 1 Sep 2014 22:16:26 +0200 Subject: [PATCH 47/87] Calculate date range from given date --- RSDayFlow/RSDFDatePickerView.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index 8ec964e..8304750 100644 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -245,7 +245,7 @@ - (void)scrollToDate:(NSDate *)date animated:(BOOL)animated if (![visibleCells count]) return; - NSDateComponents *nowYearMonthComponents = [self.calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit) fromDate:[NSDate date]]; + NSDateComponents *nowYearMonthComponents = [self.calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit) fromDate:date]; NSDate *now = [self.calendar dateFromComponents:nowYearMonthComponents]; _fromDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:((^{ From a7ebb80d190af307cadd958ef6fa38c3ff48986d Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Mon, 15 Sep 2014 21:47:30 +0300 Subject: [PATCH 48/87] [Update] Rename some variables in the method `scrollToDate:animated:`. --- RSDayFlow/RSDFDatePickerView.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index 8304750..5898f1e 100644 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -245,20 +245,20 @@ - (void)scrollToDate:(NSDate *)date animated:(BOOL)animated if (![visibleCells count]) return; - NSDateComponents *nowYearMonthComponents = [self.calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit) fromDate:date]; - NSDate *now = [self.calendar dateFromComponents:nowYearMonthComponents]; + NSDateComponents *dateYearMonthComponents = [self.calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit) fromDate:date]; + NSDate *month = [self.calendar dateFromComponents:dateYearMonthComponents]; _fromDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:((^{ NSDateComponents *components = [NSDateComponents new]; components.month = -6; return components; - })()) toDate:now options:0]]; + })()) toDate:month options:0]]; _toDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:((^{ NSDateComponents *components = [NSDateComponents new]; components.month = 6; return components; - })()) toDate:now options:0]]; + })()) toDate:month options:0]]; [cv reloadData]; [cvLayout invalidateLayout]; From 61150fc789350485f4c6b2372c1a082c6ac0cdc5 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 16 Sep 2014 20:54:00 +0300 Subject: [PATCH 49/87] [Fix] An initial mark image. --- RSDayFlow/RSDFDatePickerDayCell.m | 1 + 1 file changed, 1 insertion(+) diff --git a/RSDayFlow/RSDFDatePickerDayCell.m b/RSDayFlow/RSDFDatePickerDayCell.m index e3ac8ec..6d9f131 100644 --- a/RSDayFlow/RSDFDatePickerDayCell.m +++ b/RSDayFlow/RSDFDatePickerDayCell.m @@ -211,6 +211,7 @@ - (UIImageView *)markImageView _markImageView.backgroundColor = [UIColor clearColor]; _markImageView.center = CGPointMake(self.frame.size.width / 2, 50.0f); _markImageView.contentMode = UIViewContentModeCenter; + _markImageView.image = [self incompleteMarkImage]; } return _markImageView; } From d12fa4f86717f0496a9e547f34cf086d0b51778b Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 16 Sep 2014 23:33:14 +0300 Subject: [PATCH 50/87] [Update] Improve the data source of `RSDFDatePickerView`. Replace the method `datePickerViewMarkedDates:` by two new methods `datePickerView:shouldMarkDate:` and `datePickerView:isCompletedAllTasksOnDate:`. Resolve #21 --- .../RSDFDatePickerViewController.m | 45 ++++++++++++++----- RSDayFlow/RSDFDatePickerView.h | 17 +++++-- RSDayFlow/RSDFDatePickerView.m | 14 +++--- 3 files changed, 52 insertions(+), 24 deletions(-) diff --git a/Example/RSDayFlowExample/RSDFDatePickerViewController.m b/Example/RSDayFlowExample/RSDFDatePickerViewController.m index 8fae62f..926019b 100755 --- a/Example/RSDayFlowExample/RSDFDatePickerViewController.m +++ b/Example/RSDayFlowExample/RSDFDatePickerViewController.m @@ -29,7 +29,8 @@ @interface RSDFDatePickerViewController() -@property (strong, nonatomic) NSDictionary *markedDates; +@property (strong, nonatomic) NSArray *datesToMark; +@property (strong, nonatomic) NSDictionary *statesOfTasks; @property (strong, nonatomic) NSDateFormatter *dateFormatter; @property (strong, nonatomic) RSDFDatePickerView *datePickerView; @property (strong, nonatomic) RSDFCustomDatePickerView *customDatePickerView; @@ -77,9 +78,9 @@ - (void)setCalendar:(NSCalendar *)calendar } } -- (NSDictionary *)markedDates +- (NSArray *)datesToMark { - if (!_markedDates) { + if (!_datesToMark) { NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents *todayComponents = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]]; NSDate *today = [calendar dateFromComponents:todayComponents]; @@ -87,20 +88,37 @@ - (NSDictionary *)markedDates NSArray *numberOfDaysFromToday = @[@(-8), @(-2), @(-1), @(0), @(2), @(4), @(8), @(13), @(22)]; NSDateComponents *dateComponents = [[NSDateComponents alloc] init]; - NSMutableDictionary *markedDates = [[NSMutableDictionary alloc] initWithCapacity:[numberOfDaysFromToday count]]; + NSMutableArray *datesToMark = [[NSMutableArray alloc] initWithCapacity:[numberOfDaysFromToday count]]; [numberOfDaysFromToday enumerateObjectsUsingBlock:^(NSNumber *numberOfDays, NSUInteger idx, BOOL *stop) { dateComponents.day = [numberOfDays integerValue]; NSDate *date = [calendar dateByAddingComponents:dateComponents toDate:today options:0]; + [datesToMark addObject:date]; + }]; + + _datesToMark = [datesToMark copy]; + } + return _datesToMark; +} + +- (NSDictionary *)statesOfTasks +{ + if (!_statesOfTasks) { + NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; + NSDateComponents *todayComponents = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]]; + NSDate *today = [calendar dateFromComponents:todayComponents]; + + NSMutableDictionary *statesOfTasks = [[NSMutableDictionary alloc] initWithCapacity:[self.datesToMark count]]; + [self.datesToMark enumerateObjectsUsingBlock:^(NSDate *date, NSUInteger idx, BOOL *stop) { + BOOL isCompletedAllTasks = NO; if ([date compare:today] == NSOrderedAscending) { - markedDates[date] = @YES; - } else { - markedDates[date] = @NO; + isCompletedAllTasks = YES; } + statesOfTasks[date] = @(isCompletedAllTasks); }]; - _markedDates = [markedDates copy]; + _statesOfTasks = [statesOfTasks copy]; } - return _markedDates; + return _statesOfTasks; } - (NSDateFormatter *)dateFormatter @@ -169,9 +187,14 @@ - (void)datePickerView:(RSDFDatePickerView *)view didSelectDate:(NSDate *)date #pragma mark - RSDFDatePickerViewDataSource -- (NSDictionary *)datePickerViewMarkedDates:(RSDFDatePickerView *)view +- (BOOL)datePickerView:(RSDFDatePickerView *)view shouldMarkDate:(NSDate *)date +{ + return [self.datesToMark containsObject:date]; +} + +- (BOOL)datePickerView:(RSDFDatePickerView *)view isCompletedAllTasksOnDate:(NSDate *)date { - return self.markedDates; + return [self.statesOfTasks[date] boolValue]; } @end diff --git a/RSDayFlow/RSDFDatePickerView.h b/RSDayFlow/RSDFDatePickerView.h index 7e3f210..31abc95 100644 --- a/RSDayFlow/RSDFDatePickerView.h +++ b/RSDayFlow/RSDFDatePickerView.h @@ -169,12 +169,21 @@ @optional /** - Provides dates to mark for the data source. + Asks the data source if the date should be marked. - @param view The view to whom dates are provided. + @param view The date picker view object that is asking whether the date should mark. - @return The dictionary that contains dates (as keys) and completeness of tasks on these days (as objects). + @return YES if the date should be marked or NO if it should not. */ -- (NSDictionary *)datePickerViewMarkedDates:(RSDFDatePickerView *)view; +- (BOOL)datePickerView:(RSDFDatePickerView *)view shouldMarkDate:(NSDate *)date; + +/** + Asks the data source if all tasks on the date are completed. + + @param view The date picker view object that is asking about the completion of tasks on the date. + + @return YES if all tasks on the date are completed or NO if they are not completed. + */ +- (BOOL)datePickerView:(RSDFDatePickerView *)view isCompletedAllTasksOnDate:(NSDate *)date; @end diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index 5898f1e..2c94eec 100644 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -530,15 +530,11 @@ - (RSDFDatePickerDayCell *)collectionView:(UICollectionView *)collectionView cel weekday = [self.calendar components:NSWeekdayCalendarUnit fromDate:cellDate].weekday; cell.dayOff = (weekday == 1) || (weekday == 7); - if ([self.dataSource respondsToSelector:@selector(datePickerViewMarkedDates:)]) { - NSDictionary *markedDates = [self.dataSource datePickerViewMarkedDates:self]; - NSNumber *markedDateState = [markedDates objectForKey:cellDate]; - if (markedDateState) { - cell.marked = YES; - cell.completed = [markedDateState boolValue]; - } else { - cell.marked = NO; - cell.completed = NO; + if ([self.dataSource respondsToSelector:@selector(datePickerView:shouldMarkDate:)]) { + cell.marked = [self.dataSource datePickerView:self shouldMarkDate:cellDate]; + + if (cell.marked && [self.dataSource respondsToSelector:@selector(datePickerView:isCompletedAllTasksOnDate:)]) { + cell.completed = [self.dataSource datePickerView:self isCompletedAllTasksOnDate:cellDate]; } } From b4a5be381a80b4e0a27209bb96762fdc08c0c821 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 16 Sep 2014 23:35:07 +0300 Subject: [PATCH 51/87] [Update] README. DataSource (optional). --- README.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 9bbc861..763e484 100644 --- a/README.md +++ b/README.md @@ -65,31 +65,33 @@ Then implement the delegate function. ## DataSource (optional) -`RSDFDatePickerView` provides one data source method `datePickerViewMarkedDates`. It uses to mark dates by using markers of different colors like iOS 7 Calendar app. To use it, implement the data source in your view controller. +`RSDFDatePickerView` provides two data source methods. The method `datePickerView:shouldMarkDate:` asks the data source if the date should be marked. The method `datePickerView:isCompletedAllTasksOnDate:` asks the data source if all tasks on the date are completed. To use them, implement the data source in your view controller. ```objective-c @interface ViewController () ``` -Then implement the data source function. +Then implement the data source functions. ```objective-c -// Returns dates to mark. -- (NSDictionary *)datePickerViewMarkedDates:(RSDFDatePickerView *)view +// Returns YES if the date should be marked or NO if it should not. +- (BOOL)datePickerView:(RSDFDatePickerView *)view shouldMarkDate:(NSDate *)date { - // Create an `NSDate` object without time components. + // The date is an `NSDate` object without time components. + // So, we need to use dates without time components. + NSCalendar *calendar = [NSCalendar currentCalendar]; unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit; NSDateComponents *todayComponents = [calendar components:unitFlags fromDate:[NSDate date]]; NSDate *today = [calendar dateFromComponents:todayComponents]; + + return [date isEqual:today]; +} - // Create an `NSNumber` object that determines whether the date is marked. - NSNumber *isCompletedAllTasks = @(NO); - - // Create a dictionary with the date to mark. - NSDictionary *markedDates = @{today: isCompletedAllTasks}; - - return markedDates; +// Returns YES if all tasks on the date are completed or NO if they are not completed. +- (BOOL)datePickerView:(RSDFDatePickerView *)view isCompletedAllTasksOnDate:(NSDate *)date +{ + return YES; } ``` From 943492d61a2616047d3b4f4764f07d62dfa6e696 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 16 Sep 2014 23:55:30 +0300 Subject: [PATCH 52/87] Version bump (0.5.0) --- Example/RSDayFlowExample/RSDayFlowExample-Info.plist | 4 ++-- RSDayFlow.podspec | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist index ad2c17e..2399adf 100644 --- a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist +++ b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.4.0 + 0.5.0 CFBundleSignature ???? CFBundleVersion - 0.4.0 + 0.5.0 LSRequiresIPhoneOS UIRequiredDeviceCapabilities diff --git a/RSDayFlow.podspec b/RSDayFlow.podspec index ca9ab81..8731fb6 100644 --- a/RSDayFlow.podspec +++ b/RSDayFlow.podspec @@ -1,11 +1,11 @@ Pod::Spec.new do |s| s.name = 'RSDayFlow' - s.version = '0.4.0' + s.version = '0.5.0' s.summary = 'iOS 7 Calendar with Infinite Scrolling.' s.homepage = 'https://github.com/ruslanskorb/RSDayFlow' s.license = { :type => 'MIT', :file => 'LICENSE' } s.authors = { 'Evadne Wu' => 'ev@radi.ws', 'Ruslan Skorb' => 'ruslan.skorb@gmail.com' } - s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.4.0' } + s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.5.0' } s.platform = :ios, '7.0' s.source_files = 'RSDayFlow' s.frameworks = 'QuartzCore', 'UIKit' From 9316ee5e03923564c7142b6a1e84243ed5d361d3 Mon Sep 17 00:00:00 2001 From: Alexey Hippie Date: Wed, 8 Oct 2014 18:24:59 +0400 Subject: [PATCH 53/87] Not default FirstWeekDay fix; --- RSDayFlow/RSDFDatePickerView.m | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) mode change 100644 => 100755 RSDayFlow/RSDFDatePickerView.m diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m old mode 100644 new mode 100755 index 2c94eec..4961b03 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -454,19 +454,22 @@ - (NSUInteger)numberOfWeeksForMonthOfDate:(NSDate *)date return dateComponents; })()) toDate:firstDayInMonth options:0]; - NSDate *fromSunday = [self.calendar dateFromComponents:((^{ + NSDate *fromFirstWeeday = [self.calendar dateFromComponents:((^{ NSDateComponents *dateComponents = [self.calendar components:NSWeekOfYearCalendarUnit|NSYearForWeekOfYearCalendarUnit fromDate:firstDayInMonth]; - dateComponents.weekday = 1; + dateComponents.weekday = self.calendar.firstWeekday; return dateComponents; })())]; - NSDate *toSunday = [self.calendar dateFromComponents:((^{ + NSDate *toFirstWeekday = [self.calendar dateFromComponents:((^{ NSDateComponents *dateComponents = [self.calendar components:NSWeekOfYearCalendarUnit|NSYearForWeekOfYearCalendarUnit fromDate:lastDayInMonth]; - dateComponents.weekday = 1; + dateComponents.weekday = self.calendar.firstWeekday; return dateComponents; })())]; - return 1 + [self.calendar components:NSWeekOfYearCalendarUnit fromDate:fromSunday toDate:toSunday options:0].weekOfYear; + return 1 + [self.calendar components:NSWeekOfYearCalendarUnit + fromDate:fromFirstWeeday + toDate:toFirstWeekday + options:0].weekOfYear; #endif } @@ -507,17 +510,26 @@ - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSe return self.daysInWeek * [self numberOfWeeksForMonthOfDate:[self dateForFirstDayInSection:section]]; } +- (NSUInteger)weekdayOrderForWeekdayNumber:(NSUInteger)weekday { + NSInteger ordered = weekday - (self.calendar.firstWeekday - 1); + if (ordered < 1) { + ordered = 7 - ABS(ordered); + } + + return ordered; +} + - (RSDFDatePickerDayCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { RSDFDatePickerDayCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:RSDFDatePickerViewDayCellIdentifier forIndexPath:indexPath]; NSDate *firstDayInMonth = [self dateForFirstDayInSection:indexPath.section]; RSDFDatePickerDate firstDayPickerDate = [self pickerDateFromDate:firstDayInMonth]; - NSUInteger weekday = [self.calendar components:NSWeekdayCalendarUnit fromDate:firstDayInMonth].weekday; + NSUInteger weekday = [self weekdayOrderForWeekdayNumber:[self.calendar components:NSWeekdayCalendarUnit fromDate:firstDayInMonth].weekday]; NSDate *cellDate = [self.calendar dateByAddingComponents:((^{ NSDateComponents *dateComponents = [NSDateComponents new]; - dateComponents.day = indexPath.item - (weekday - self.calendar.firstWeekday); + dateComponents.day = indexPath.item - (weekday - 1); return dateComponents; })()) toDate:firstDayInMonth options:0]; RSDFDatePickerDate cellPickerDate = [self pickerDateFromDate:cellDate]; From 2e9183f2fc3e46d3d88493ab2ee44d9d28fe99cc Mon Sep 17 00:00:00 2001 From: Alexey Hippie Date: Wed, 8 Oct 2014 18:28:45 +0400 Subject: [PATCH 54/87] Relocate util method; --- RSDayFlow/RSDFDatePickerView.m | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index 4961b03..64add92 100755 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -498,6 +498,15 @@ - (RSDFDatePickerDate)pickerDateFromDate:(NSDate *)date }; } +- (NSUInteger)weekdayOrderForWeekdayNumber:(NSUInteger)weekday { + NSInteger ordered = weekday - (self.calendar.firstWeekday - 1); + if (ordered < 1) { + ordered = 7 - ABS(ordered); + } + + return ordered; +} + #pragma mark - UICollectionViewDataSource - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView @@ -510,15 +519,6 @@ - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSe return self.daysInWeek * [self numberOfWeeksForMonthOfDate:[self dateForFirstDayInSection:section]]; } -- (NSUInteger)weekdayOrderForWeekdayNumber:(NSUInteger)weekday { - NSInteger ordered = weekday - (self.calendar.firstWeekday - 1); - if (ordered < 1) { - ordered = 7 - ABS(ordered); - } - - return ordered; -} - - (RSDFDatePickerDayCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { RSDFDatePickerDayCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:RSDFDatePickerViewDayCellIdentifier forIndexPath:indexPath]; From ff5a8c8929ce175c84ae82f325ed58ab762f5cb4 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Fri, 10 Oct 2014 12:27:54 +0300 Subject: [PATCH 55/87] [Update] Reordering of weekday. #28 --- RSDayFlow/RSDFDatePickerView.m | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index 64add92..b72e07c 100755 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -454,7 +454,7 @@ - (NSUInteger)numberOfWeeksForMonthOfDate:(NSDate *)date return dateComponents; })()) toDate:firstDayInMonth options:0]; - NSDate *fromFirstWeeday = [self.calendar dateFromComponents:((^{ + NSDate *fromFirstWeekday = [self.calendar dateFromComponents:((^{ NSDateComponents *dateComponents = [self.calendar components:NSWeekOfYearCalendarUnit|NSYearForWeekOfYearCalendarUnit fromDate:firstDayInMonth]; dateComponents.weekday = self.calendar.firstWeekday; return dateComponents; @@ -466,10 +466,7 @@ - (NSUInteger)numberOfWeeksForMonthOfDate:(NSDate *)date return dateComponents; })())]; - return 1 + [self.calendar components:NSWeekOfYearCalendarUnit - fromDate:fromFirstWeeday - toDate:toFirstWeekday - options:0].weekOfYear; + return 1 + [self.calendar components:NSWeekOfYearCalendarUnit fromDate:fromFirstWeekday toDate:toFirstWeekday options:0].weekOfYear; #endif } @@ -498,10 +495,11 @@ - (RSDFDatePickerDate)pickerDateFromDate:(NSDate *)date }; } -- (NSUInteger)weekdayOrderForWeekdayNumber:(NSUInteger)weekday { - NSInteger ordered = weekday - (self.calendar.firstWeekday - 1); - if (ordered < 1) { - ordered = 7 - ABS(ordered); +- (NSUInteger)reorderedWeekday:(NSUInteger)weekday +{ + NSInteger ordered = weekday - self.calendar.firstWeekday; + if (ordered < 0) { + ordered = self.daysInWeek + ordered; } return ordered; @@ -525,11 +523,11 @@ - (RSDFDatePickerDayCell *)collectionView:(UICollectionView *)collectionView cel NSDate *firstDayInMonth = [self dateForFirstDayInSection:indexPath.section]; RSDFDatePickerDate firstDayPickerDate = [self pickerDateFromDate:firstDayInMonth]; - NSUInteger weekday = [self weekdayOrderForWeekdayNumber:[self.calendar components:NSWeekdayCalendarUnit fromDate:firstDayInMonth].weekday]; + NSUInteger weekday = [self reorderedWeekday:[self.calendar components:NSWeekdayCalendarUnit fromDate:firstDayInMonth].weekday]; NSDate *cellDate = [self.calendar dateByAddingComponents:((^{ NSDateComponents *dateComponents = [NSDateComponents new]; - dateComponents.day = indexPath.item - (weekday - 1); + dateComponents.day = indexPath.item - weekday; return dateComponents; })()) toDate:firstDayInMonth options:0]; RSDFDatePickerDate cellPickerDate = [self pickerDateFromDate:cellDate]; From 1dfcd18ae8a2bf2dbb165b8c26610223a028c5a5 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Sat, 11 Oct 2014 12:33:14 +0300 Subject: [PATCH 56/87] [Add] Support for iPhone 6, iPhone 6 Plus, iPad, landscape and portrait. Resolves #17. Resolves #18. Resolves #23. --- .../project.pbxproj | 15 + .../Base.lproj/LaunchScreen.xib | 19 + ...RSDFCustomDatePickerCollectionViewLayout.m | 4 +- .../RSDFDatePickerViewController.m | 16 +- .../RSDayFlowExample-Info.plist | 2 + .../RSDFDatePickerCollectionViewLayout.h | 4 +- .../RSDFDatePickerCollectionViewLayout.m | 21 +- RSDayFlow/RSDFDatePickerDayCell.m | 109 ++-- RSDayFlow/RSDFDatePickerDaysOfWeekView.h | 9 +- RSDayFlow/RSDFDatePickerDaysOfWeekView.m | 156 +++++- RSDayFlow/RSDFDatePickerView.m | 513 +++++++++--------- 11 files changed, 536 insertions(+), 332 deletions(-) create mode 100644 Example/RSDayFlowExample/Base.lproj/LaunchScreen.xib diff --git a/Example/RSDayFlowExample.xcodeproj/project.pbxproj b/Example/RSDayFlowExample.xcodeproj/project.pbxproj index 8362c71..bacf14a 100644 --- a/Example/RSDayFlowExample.xcodeproj/project.pbxproj +++ b/Example/RSDayFlowExample.xcodeproj/project.pbxproj @@ -14,6 +14,7 @@ B82FFFA819A37EDB000816FF /* RSDFCustomDatePickerDaysOfWeekView.m in Sources */ = {isa = PBXBuildFile; fileRef = B82FFFA019A37EDB000816FF /* RSDFCustomDatePickerDaysOfWeekView.m */; }; B82FFFA919A37EDB000816FF /* RSDFCustomDatePickerMonthHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = B82FFFA219A37EDB000816FF /* RSDFCustomDatePickerMonthHeader.m */; }; B82FFFAA19A37EDB000816FF /* RSDFCustomDatePickerView.m in Sources */ = {isa = PBXBuildFile; fileRef = B82FFFA419A37EDB000816FF /* RSDFCustomDatePickerView.m */; }; + B872EE8319E82DF000E52146 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = B872EE8119E82DF000E52146 /* LaunchScreen.xib */; }; B8F807C119A34B990047C24B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B8F807C019A34B990047C24B /* Foundation.framework */; }; B8F807C319A34B9A0047C24B /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B8F807C219A34B9A0047C24B /* CoreGraphics.framework */; }; B8F807C519A34B9A0047C24B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B8F807C419A34B9A0047C24B /* UIKit.framework */; }; @@ -60,6 +61,7 @@ B82FFFA219A37EDB000816FF /* RSDFCustomDatePickerMonthHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSDFCustomDatePickerMonthHeader.m; sourceTree = ""; }; B82FFFA319A37EDB000816FF /* RSDFCustomDatePickerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSDFCustomDatePickerView.h; sourceTree = ""; }; B82FFFA419A37EDB000816FF /* RSDFCustomDatePickerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSDFCustomDatePickerView.m; sourceTree = ""; }; + B872EE8219E82DF000E52146 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; B8F807BD19A34B990047C24B /* RSDayFlowExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RSDayFlowExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; B8F807C019A34B990047C24B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; B8F807C219A34B9A0047C24B /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; @@ -175,6 +177,7 @@ B8F8080519A34CC00047C24B /* Controllers */, B82FFFAB19A37EDF000816FF /* Views */, B8F807D219A34B9A0047C24B /* Images.xcassets */, + B872EE8119E82DF000E52146 /* LaunchScreen.xib */, B8F807C719A34B9A0047C24B /* Supporting Files */, ); name = Classes; @@ -309,6 +312,7 @@ hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = B8F807B419A34B990047C24B; productRefGroup = B8F807BE19A34B990047C24B /* Products */; @@ -327,6 +331,7 @@ buildActionMask = 2147483647; files = ( B8F807CB19A34B9A0047C24B /* InfoPlist.strings in Resources */, + B872EE8319E82DF000E52146 /* LaunchScreen.xib in Resources */, B8F807D319A34B9A0047C24B /* Images.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -384,6 +389,14 @@ /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ + B872EE8119E82DF000E52146 /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + B872EE8219E82DF000E52146 /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; B8F807C919A34B9A0047C24B /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( @@ -482,6 +495,7 @@ GCC_PREFIX_HEADER = "RSDayFlowExample/RSDayFlowExample-Prefix.pch"; INFOPLIST_FILE = "RSDayFlowExample/RSDayFlowExample-Info.plist"; PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; WRAPPER_EXTENSION = app; }; name = Debug; @@ -495,6 +509,7 @@ GCC_PREFIX_HEADER = "RSDayFlowExample/RSDayFlowExample-Prefix.pch"; INFOPLIST_FILE = "RSDayFlowExample/RSDayFlowExample-Info.plist"; PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; WRAPPER_EXTENSION = app; }; name = Release; diff --git a/Example/RSDayFlowExample/Base.lproj/LaunchScreen.xib b/Example/RSDayFlowExample/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..72df6e5 --- /dev/null +++ b/Example/RSDayFlowExample/Base.lproj/LaunchScreen.xib @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionViewLayout.m b/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionViewLayout.m index cdfd768..d1ae635 100644 --- a/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionViewLayout.m +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionViewLayout.m @@ -31,12 +31,12 @@ @implementation RSDFCustomDatePickerCollectionViewLayout - (CGSize)selfHeaderReferenceSize { - return (CGSize){ 320, 54 }; + return (CGSize){ [super selfHeaderReferenceSize].width, 54 }; } - (CGSize)selfItemSize { - return (CGSize){ 44, 60 }; + return (CGSize){ [super selfItemSize].width, 60 }; } @end diff --git a/Example/RSDayFlowExample/RSDFDatePickerViewController.m b/Example/RSDayFlowExample/RSDFDatePickerViewController.m index 926019b..996d224 100755 --- a/Example/RSDayFlowExample/RSDFDatePickerViewController.m +++ b/Example/RSDayFlowExample/RSDFDatePickerViewController.m @@ -64,6 +64,10 @@ - (void)viewDidLoad self.navigationItem.leftBarButtonItem = restyle; self.view.backgroundColor = [UIColor colorWithWhite:0.8 alpha:0.3]; + + self.customDatePickerView.hidden = YES; + + [self.view addSubview:self.customDatePickerView]; [self.view addSubview:self.datePickerView]; } @@ -158,7 +162,7 @@ - (RSDFCustomDatePickerView *)customDatePickerView - (void)onTodayButtonTouch:(UIBarButtonItem *)sender { - if (self.datePickerView.superview) { + if (!self.datePickerView.hidden) { [self.datePickerView scrollToToday:YES]; } else { [self.customDatePickerView scrollToToday:YES]; @@ -167,14 +171,14 @@ - (void)onTodayButtonTouch:(UIBarButtonItem *)sender - (void)onRestyleButtonTouch:(UIBarButtonItem *)sender { - if (self.datePickerView.superview) { + if (!self.datePickerView.hidden) { self.navigationController.navigationBar.barTintColor = [UIColor colorWithRed:244/255.0f green:245/255.0f blue:247/255.0f alpha:1.0f]; - [self.datePickerView removeFromSuperview]; - [self.view addSubview:self.customDatePickerView]; + self.datePickerView.hidden = YES; + self.customDatePickerView.hidden = NO; } else { self.navigationController.navigationBar.barTintColor = [UIColor colorWithRed:248/255.0f green:248/255.0f blue:248/255.0f alpha:1.0f]; - [self.customDatePickerView removeFromSuperview]; - [self.view addSubview:self.datePickerView]; + self.customDatePickerView.hidden = YES; + self.datePickerView.hidden = NO; } } diff --git a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist index 2399adf..1682c46 100644 --- a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist +++ b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist @@ -24,6 +24,8 @@ 0.5.0 LSRequiresIPhoneOS + UILaunchStoryboardName + LaunchScreen UIRequiredDeviceCapabilities armv7 diff --git a/RSDayFlow/RSDFDatePickerCollectionViewLayout.h b/RSDayFlow/RSDFDatePickerCollectionViewLayout.h index b05f873..7a9690b 100644 --- a/RSDayFlow/RSDFDatePickerCollectionViewLayout.h +++ b/RSDayFlow/RSDFDatePickerCollectionViewLayout.h @@ -35,14 +35,14 @@ ///----------------------------------------- /** - The default sizes to use for section headers. Default value is {320, 64}. + The default size to use for section headers. Default height is `64.0f`. Default width is calculated based on the width of the collection view. @discussion Can be overridden in subclasses for customization. */ - (CGSize)selfHeaderReferenceSize; /** - The default size to use for cells. Default value is {44, 70}. + The default size to use for cells. Default height is `70.0f`. Default width is calculated based on the width of the collection view. @discussion Can be overridden in subclasses for customization. */ diff --git a/RSDayFlow/RSDFDatePickerCollectionViewLayout.m b/RSDayFlow/RSDFDatePickerCollectionViewLayout.m index 6a236e6..080a60b 100644 --- a/RSDayFlow/RSDFDatePickerCollectionViewLayout.m +++ b/RSDayFlow/RSDFDatePickerCollectionViewLayout.m @@ -49,13 +49,6 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder - (void)commonInitializer { - // Hard key these things. - // 44 * 7 + 2 * 6 = 320; this is how the Calendar.app works - // and this also avoids the “one pixel” confusion which might or might not work - // If you need to decorate, key decorative views in. - - self.headerReferenceSize = [self selfHeaderReferenceSize]; - self.itemSize = [self selfItemSize]; self.minimumLineSpacing = [self selfMinimumLineSpacing]; self.minimumInteritemSpacing = [self selfMinimumInteritemSpacing]; } @@ -64,12 +57,22 @@ - (void)commonInitializer - (CGSize)selfHeaderReferenceSize { - return (CGSize){ 320, 64 }; + CGFloat selfHeaderReferenceWidth = CGRectGetWidth(self.collectionView.frame); + CGFloat selfHeaderReferenceHeight = 64.0f; + + return (CGSize){ selfHeaderReferenceWidth, selfHeaderReferenceHeight }; } - (CGSize)selfItemSize { - return (CGSize){ 44, 70 }; + NSUInteger numberOfItemsInTheSameRow = 7; + CGFloat totalInteritemSpacing = [self minimumInteritemSpacing] * (numberOfItemsInTheSameRow - 1); + + CGFloat selfItemWidth = (CGRectGetWidth(self.collectionView.frame) - totalInteritemSpacing) / numberOfItemsInTheSameRow; + selfItemWidth = floor(selfItemWidth * 1000) / 1000; + CGFloat selfItemHeight = 70.0f; + + return (CGSize){ selfItemWidth, selfItemHeight }; } - (CGFloat)selfMinimumLineSpacing diff --git a/RSDayFlow/RSDFDatePickerDayCell.m b/RSDayFlow/RSDFDatePickerDayCell.m index 6d9f131..2ff6611 100644 --- a/RSDayFlow/RSDFDatePickerDayCell.m +++ b/RSDayFlow/RSDFDatePickerDayCell.m @@ -49,11 +49,11 @@ @implementation RSDFDatePickerDayCell - (instancetype)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { - [self commonInitializer]; - } - return self; + self = [super initWithFrame:frame]; + if (self) { + [self commonInitializer]; + } + return self; } - (instancetype)initWithCoder:(NSCoder *)aDecoder @@ -82,6 +82,18 @@ - (void)commonInitializer [self addSubview:self.dateLabel]; } +- (void)layoutSubviews +{ + [super layoutSubviews]; + + self.dateLabel.frame = [self todayImageViewFrame]; + self.todayImageView.frame = [self todayImageViewFrame]; + self.overlayImageView.frame = [self todayImageViewFrame]; + self.markImageView.frame = [self markImageViewFrame]; + self.dividerImageView.frame = [self dividerImageViewFrame]; + self.dividerImageView.image = [self dividerImage]; +} + #pragma mark - Custom Accessors - (void)setDate:(RSDFDatePickerDate)date @@ -160,93 +172,100 @@ - (void)setToday:(BOOL)today - (void)setHighlighted:(BOOL)highlighted { - [super setHighlighted:highlighted]; - self.overlayImageView.hidden = !self.highlighted; + [super setHighlighted:highlighted]; + self.overlayImageView.hidden = !self.highlighted; } -- (UILabel *)dateLabel +- (CGRect)todayImageViewFrame { - if (!_dateLabel) { - CGRect frame = CGRectMake(self.bounds.origin.x, self.todayImageView.frame.origin.y, - self.bounds.size.width, self.todayImageView.frame.size.height); - _dateLabel = [[UILabel alloc] initWithFrame:frame]; - _dateLabel.backgroundColor = [UIColor clearColor]; - _dateLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; - _dateLabel.textAlignment = NSTextAlignmentCenter; - } - return _dateLabel; + return CGRectMake(CGRectGetWidth(self.frame) / 2 - 17.5f, 5.5f, 35.0f, 35.0f); } - (UIImageView *)todayImageView { if (!_todayImageView) { - CGRect frame = CGRectMake(0.0f, 0.0f, 35.0f, 35.0f); - _todayImageView = [[UIImageView alloc] initWithFrame:frame]; + _todayImageView = [[UIImageView alloc] initWithFrame:[self todayImageViewFrame]]; _todayImageView.backgroundColor = [UIColor clearColor]; - _todayImageView.center = CGPointMake(self.frame.size.width / 2, 23.0f); _todayImageView.contentMode = UIViewContentModeCenter; _todayImageView.image = [self todayImage]; } return _todayImageView; } +- (UILabel *)dateLabel +{ + if (!_dateLabel) { + _dateLabel = [[UILabel alloc] initWithFrame:[self todayImageViewFrame]]; + _dateLabel.backgroundColor = [UIColor clearColor]; + _dateLabel.textAlignment = NSTextAlignmentCenter; + } + return _dateLabel; +} + - (UIImageView *)overlayImageView { - if (!_overlayImageView) { - _overlayImageView = [[UIImageView alloc] initWithFrame:self.todayImageView.frame]; + if (!_overlayImageView) { + _overlayImageView = [[UIImageView alloc] initWithFrame:[self todayImageViewFrame]]; _overlayImageView.backgroundColor = [UIColor clearColor]; _overlayImageView.opaque = NO; _overlayImageView.alpha = 0.5f; _overlayImageView.contentMode = UIViewContentModeCenter; _overlayImageView.image = [self overlayImage]; - } - return _overlayImageView; + } + return _overlayImageView; +} + +- (CGRect)markImageViewFrame +{ + return CGRectMake(CGRectGetWidth(self.frame) / 2 - 4.5f, 45.5f, 9.0f, 9.0f); } - (UIImageView *)markImageView { if (!_markImageView) { - CGRect frame = CGRectMake(0.0f, 0.0f, 9.0f, 9.0f); - _markImageView = [[UIImageView alloc] initWithFrame:frame]; + _markImageView = [[UIImageView alloc] initWithFrame:[self markImageViewFrame]]; _markImageView.backgroundColor = [UIColor clearColor]; - _markImageView.center = CGPointMake(self.frame.size.width / 2, 50.0f); _markImageView.contentMode = UIViewContentModeCenter; _markImageView.image = [self incompleteMarkImage]; } return _markImageView; } +- (CGRect)dividerImageViewFrame +{ + return CGRectMake(0.0f, 0.0f, CGRectGetWidth(self.frame) + 3.0f, 0.5f); +} + - (UIImageView *)dividerImageView { - if (!_dividerImageView) { - CGRect frame = CGRectMake(0.0f, 0.0f, 50.0f, 0.5f); - _dividerImageView = [[UIImageView alloc] initWithFrame:frame]; + if (!_dividerImageView) { + _dividerImageView = [[UIImageView alloc] initWithFrame:[self dividerImageViewFrame]]; _dividerImageView.contentMode = UIViewContentModeCenter; _dividerImageView.image = [self dividerImage]; - } - return _dividerImageView; + } + return _dividerImageView; } #pragma mark - Private + (NSCache *)imageCache { - static NSCache *cache; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - cache = [NSCache new]; - }); - return cache; + static NSCache *cache; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + cache = [NSCache new]; + }); + return cache; } + (id)fetchObjectForKey:(id)key withCreator:(id(^)(void))block { - id answer = [[self imageCache] objectForKey:key]; - if (!answer) { - answer = block(); - [[self imageCache] setObject:answer forKey:key]; - } - return answer; + id answer = [[self imageCache] objectForKey:key]; + if (!answer) { + answer = block(); + [[self imageCache] setObject:answer forKey:key]; + } + return answer; } - (UIImage *)ellipseImageWithKey:(NSString *)key frame:(CGRect)frame color:(UIColor *)color @@ -424,7 +443,7 @@ - (UIImage *)dividerImage UIImage *dividerImage = [self customDividerImage]; if (!dividerImage) { UIColor *dividerImageColor = [self dividerImageColor]; - NSString *dividerImageKey = [NSString stringWithFormat:@"img_divider_%@", [dividerImageColor description]]; + NSString *dividerImageKey = [NSString stringWithFormat:@"img_divider_%@_%g", [dividerImageColor description], CGRectGetWidth(self.dividerImageView.frame)]; dividerImage = [self rectImageWithKey:dividerImageKey frame:self.dividerImageView.frame color:dividerImageColor]; } return dividerImage; diff --git a/RSDayFlow/RSDFDatePickerDaysOfWeekView.h b/RSDayFlow/RSDFDatePickerDaysOfWeekView.h index 9ad61ad..d7d18fd 100644 --- a/RSDayFlow/RSDFDatePickerDaysOfWeekView.h +++ b/RSDayFlow/RSDFDatePickerDaysOfWeekView.h @@ -54,7 +54,7 @@ ///----------------------------------------- /** - The size to use for labels of weekdays. Default value is {44, 22}. + The size to use for labels of weekdays. Default size is calculated based on the size of the view. @discussion Can be overridden in subclasses for customization. */ @@ -72,7 +72,10 @@ ///--------------------------------------- /** - The font for the label of the weekday. Default value is [UIFont fontWithName:@"HelveticaNeue-Light" size:10.0]. + The font for the label of the weekday. + Default value is [UIFont fontWithName:@"HelveticaNeue-Light" size:10.0] for user interface idiom 'Phone' with portrait interface orientation. + Default value is [UIFont fontWithName:@"HelveticaNeue-Light" size:12.0] for user interface idiom 'Phone' with landscape interface orientation. + Default value is [UIFont fontWithName:@"HelveticaNeue-Light" size:16.0] for user interface idiom 'Pad' with any interface orientation. @discussion Can be overridden in subclasses for customization. */ @@ -86,7 +89,7 @@ - (UIColor *)dayOfWeekLabelTextColor; /** - The text color for the label of the day off of the week. Default value is [UIColor colorWithRed:150.0/255 green:150.0/255 blue:150.0/255 alpha:1.0].å + The text color for the label of the day off of the week. Default value is [UIColor colorWithRed:150.0/255 green:150.0/255 blue:150.0/255 alpha:1.0]. @discussion Can be overridden in subclasses for customization. */ diff --git a/RSDayFlow/RSDFDatePickerDaysOfWeekView.m b/RSDayFlow/RSDFDatePickerDaysOfWeekView.m index 25cb695..9fa0d94 100644 --- a/RSDayFlow/RSDFDatePickerDaysOfWeekView.m +++ b/RSDayFlow/RSDFDatePickerDaysOfWeekView.m @@ -29,6 +29,10 @@ @interface RSDFDatePickerDaysOfWeekView () @property (strong, nonatomic) NSCalendar *calendar; +@property (strong, nonatomic) NSArray *weekdayLabels; +@property (strong, nonatomic) NSArray *veryShortStandaloneWeekdaySymbols; +@property (strong, nonatomic) NSArray *shortStandaloneWeekdaySymbols; +@property (strong, nonatomic) NSArray *standaloneWeekdaySymbols; @end @@ -38,11 +42,11 @@ @implementation RSDFDatePickerDaysOfWeekView - (instancetype)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { - [self commonInitializer]; - } - return self; + self = [super initWithFrame:frame]; + if (self) { + [self commonInitializer]; + } + return self; } - (instancetype)initWithCoder:(NSCoder *)aDecoder @@ -64,6 +68,14 @@ - (instancetype)initWithFrame:(CGRect)frame calendar:(NSCalendar *)calendar return self; } +- (void)layoutSubviews +{ + [super layoutSubviews]; + + [self layoutWeekdayLabels]; + [self updateWeekdayLabels]; +} + #pragma mark - Custom Accessors - (NSCalendar *)calendar @@ -86,15 +98,6 @@ - (void)commonInitializer UIColor *dayOfWeekLabelTextColor = [self dayOfWeekLabelTextColor]; UIColor *dayOffOfWeekLabelTextColor = [self dayOffOfWeekLabelTextColor]; - // Hard key these things. - // 44 * 7 + 2 * 6 = 320; in accordance with RSDFDatePickerCollectionViewLayout - - CGSize itemSize = [self selfItemSize]; - CGFloat interitemSpacing = [self selfInteritemSpacing]; - - CGFloat y = 0; - __block CGFloat x = 0; - NSString *dateFormatterName = [NSString stringWithFormat:@"calendarDaysOfWeekView_%@_%@", [self.calendar calendarIdentifier], [[self.calendar locale] localeIdentifier]]; NSDateFormatter *dateFormatter = [self.calendar df_dateFormatterNamed:dateFormatterName withConstructor:^{ NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; @@ -103,20 +106,61 @@ - (void)commonInitializer return dateFormatter; }]; - NSArray *weekdaySymbols = [dateFormatter veryShortStandaloneWeekdaySymbols]; + BOOL isPhone = [self isPhone]; + BOOL isPortraitInterfaceOrientation = [self isPortraitInterfaceOrientation]; + + NSArray *weekdaySymbols = nil; + if (isPhone) { + self.veryShortStandaloneWeekdaySymbols = [dateFormatter veryShortStandaloneWeekdaySymbols]; + self.shortStandaloneWeekdaySymbols = [dateFormatter shortStandaloneWeekdaySymbols]; + + if (isPortraitInterfaceOrientation) { + weekdaySymbols = self.veryShortStandaloneWeekdaySymbols; + } else { + weekdaySymbols = self.shortStandaloneWeekdaySymbols; + } + } else { + self.shortStandaloneWeekdaySymbols = [dateFormatter shortStandaloneWeekdaySymbols]; + self.standaloneWeekdaySymbols = [dateFormatter standaloneWeekdaySymbols]; + + if (isPortraitInterfaceOrientation) { + weekdaySymbols = self.shortStandaloneWeekdaySymbols; + } else { + weekdaySymbols = self.standaloneWeekdaySymbols; + } + } + NSArray *reorderedWeekdaySymbols = nil; // weekday start from 1 NSUInteger firstWeekdayIndex = [self.calendar firstWeekday] - 1; if (firstWeekdayIndex > 0) { - reorderedWeekdaySymbols = [[weekdaySymbols subarrayWithRange:NSMakeRange(firstWeekdayIndex, [weekdaySymbols count] - firstWeekdayIndex)] - arrayByAddingObjectsFromArray:[weekdaySymbols subarrayWithRange:NSMakeRange(0, firstWeekdayIndex)]]; + if (isPhone) { + self.veryShortStandaloneWeekdaySymbols = [self reorderedWeekdaySymbols:self.veryShortStandaloneWeekdaySymbols firstWeekdayIndex:firstWeekdayIndex]; + self.shortStandaloneWeekdaySymbols = [self reorderedWeekdaySymbols:self.shortStandaloneWeekdaySymbols firstWeekdayIndex:firstWeekdayIndex]; + + if (isPortraitInterfaceOrientation) { + reorderedWeekdaySymbols = self.veryShortStandaloneWeekdaySymbols; + } else { + reorderedWeekdaySymbols = self.shortStandaloneWeekdaySymbols; + } + } else { + self.shortStandaloneWeekdaySymbols = [self reorderedWeekdaySymbols:self.shortStandaloneWeekdaySymbols firstWeekdayIndex:firstWeekdayIndex]; + self.standaloneWeekdaySymbols = [self reorderedWeekdaySymbols:self.standaloneWeekdaySymbols firstWeekdayIndex:firstWeekdayIndex]; + + if (isPortraitInterfaceOrientation) { + reorderedWeekdaySymbols = self.shortStandaloneWeekdaySymbols; + } else { + reorderedWeekdaySymbols = self.standaloneWeekdaySymbols; + } + } } else { reorderedWeekdaySymbols = weekdaySymbols; } + NSMutableArray *weekdayLabels = [NSMutableArray arrayWithCapacity:[reorderedWeekdaySymbols count]]; [reorderedWeekdaySymbols enumerateObjectsUsingBlock:^(NSString *weekdaySymbol, NSUInteger idx, BOOL *stop) { - UILabel *weekdayLabel = [[UILabel alloc] initWithFrame:CGRectMake(x, y, itemSize.width, itemSize.height)]; + UILabel *weekdayLabel = [[UILabel alloc] init]; weekdayLabel.textAlignment = NSTextAlignmentCenter; weekdayLabel.backgroundColor = dayOfWeekLabelBackgroundColor; weekdayLabel.font = dayOfWeekLabelFont; @@ -126,12 +170,67 @@ - (void)commonInitializer weekdayLabel.textColor = dayOffOfWeekLabelTextColor; } weekdayLabel.text = weekdaySymbol; + [weekdayLabels addObject:weekdayLabel]; [self addSubview:weekdayLabel]; - + }]; + + self.weekdayLabels = [weekdayLabels copy]; +} + +- (NSArray *)reorderedWeekdaySymbols:(NSArray *)weekdaySymbols firstWeekdayIndex:(NSUInteger)firstWeekdayIndex +{ + return [[weekdaySymbols subarrayWithRange:NSMakeRange(firstWeekdayIndex, [weekdaySymbols count] - firstWeekdayIndex)] + arrayByAddingObjectsFromArray:[weekdaySymbols subarrayWithRange:NSMakeRange(0, firstWeekdayIndex)]]; +} + +- (void)layoutWeekdayLabels +{ + CGSize itemSize = [self selfItemSize]; + CGFloat interitemSpacing = [self selfInteritemSpacing]; + + CGFloat y = 0; + __block CGFloat x = 0; + + [self.weekdayLabels enumerateObjectsUsingBlock:^(UILabel *weekdayLabel, NSUInteger idx, BOOL *stop) { + CGRect weekdayLabelFrame = CGRectMake(x, y, itemSize.width, itemSize.height); + weekdayLabel.frame = weekdayLabelFrame; x += (itemSize.width + interitemSpacing); }]; } +- (void)updateWeekdayLabels +{ + BOOL isPhone = [self isPhone]; + BOOL isPortraitInterfaceOrientation = [self isPortraitInterfaceOrientation]; + + [self.weekdayLabels enumerateObjectsUsingBlock:^(UILabel *weekdayLabel, NSUInteger idx, BOOL *stop) { + weekdayLabel.font = [self dayOfWeekLabelFont]; + if (isPhone) { + if (isPortraitInterfaceOrientation) { + weekdayLabel.text = self.veryShortStandaloneWeekdaySymbols[idx]; + } else { + weekdayLabel.text = self.shortStandaloneWeekdaySymbols[idx]; + } + } else { + if (isPortraitInterfaceOrientation) { + weekdayLabel.text = self.shortStandaloneWeekdaySymbols[idx]; + } else { + weekdayLabel.text = self.standaloneWeekdaySymbols[idx]; + } + } + }]; +} + +- (BOOL)isPhone +{ + return UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone; +} + +- (BOOL)isPortraitInterfaceOrientation +{ + return UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]); +} + #pragma mark - Attributes of the View - (UIColor *)selfBackgroundColor @@ -143,7 +242,14 @@ - (UIColor *)selfBackgroundColor - (CGSize)selfItemSize { - return (CGSize){ 44, 22 }; + NSUInteger numberOfItems = 7; + CGFloat totalInteritemSpacing = [self selfInteritemSpacing] * (numberOfItems - 1); + + CGFloat selfItemWidth = (CGRectGetWidth(self.frame) - totalInteritemSpacing) / numberOfItems; + selfItemWidth = floor(selfItemWidth * 1000) / 1000; + CGFloat selfItemHeight = CGRectGetHeight(self.frame); + + return (CGSize){ selfItemWidth, selfItemHeight }; } - (CGFloat)selfInteritemSpacing @@ -155,7 +261,15 @@ - (CGFloat)selfInteritemSpacing - (UIFont *)dayOfWeekLabelFont { - return [UIFont fontWithName:@"HelveticaNeue-Light" size:10.0]; + if ([self isPhone]) { + if ([self isPortraitInterfaceOrientation]) { + return [UIFont fontWithName:@"HelveticaNeue-Light" size:10.0]; + } else { + return [UIFont fontWithName:@"HelveticaNeue-Light" size:12.0]; + } + } else { + return [UIFont fontWithName:@"HelveticaNeue-Light" size:16.0]; + } } - (UIColor *)dayOfWeekLabelTextColor diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index b72e07c..53fbefc 100755 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -36,10 +36,7 @@ static NSString * const RSDFDatePickerViewMonthHeaderIdentifier = @"RSDFDatePickerViewMonthHeaderIdentifier"; static NSString * const RSDFDatePickerViewDayCellIdentifier = @"RSDFDatePickerViewDayCellIdentifier"; -static const CGFloat RSDFDatePickerViewDaysOfWeekViewWidth = 320.0f; -static const CGFloat RSDFDatePickerViewDaysOfWeekViewHeight = 22.0f; - -@interface RSDFDatePickerView () +@interface RSDFDatePickerView () @property (nonatomic, readonly, strong) NSCalendar *calendar; @property (nonatomic, readonly, assign) RSDFDatePickerDate fromDate; @@ -80,11 +77,11 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder - (instancetype)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; + self = [super initWithFrame:frame]; if (self) { - [self commonInitializer]; - } - return self; + [self commonInitializer]; + } + return self; } - (instancetype)initWithFrame:(CGRect)frame calendar:(NSCalendar *)calendar @@ -99,32 +96,38 @@ - (instancetype)initWithFrame:(CGRect)frame calendar:(NSCalendar *)calendar - (void)layoutSubviews { + CGPoint beforeLayoutSubviewsContentOffset = self.collectionView.contentOffset; + [super layoutSubviews]; - + self.daysOfWeekView.frame = [self daysOfWeekViewFrame]; if (!self.daysOfWeekView.superview) { [self addSubview:self.daysOfWeekView]; } self.collectionView.frame = [self collectionViewFrame]; - if (!self.collectionView.superview) { + if (!self.collectionView.superview) { [self scrollToToday:NO]; - [self addSubview:self.collectionView]; - } + [self addSubview:self.collectionView]; + } else { + [self.collectionViewLayout invalidateLayout]; + [self.collectionViewLayout prepareLayout]; + self.collectionView.contentOffset = beforeLayoutSubviewsContentOffset; + } } - (void)willMoveToSuperview:(UIView *)newSuperview { - [super willMoveToSuperview:newSuperview]; - - if (newSuperview && !_collectionView) { - // do some initialization! + [super willMoveToSuperview:newSuperview]; + + if (newSuperview && !_collectionView) { + // do some initialization! RSDFDatePickerDaysOfWeekView *v = self.daysOfWeekView; [v layoutIfNeeded]; - UICollectionView *cv = self.collectionView; + UICollectionView *cv = self.collectionView; [cv layoutIfNeeded]; - } + } } #pragma mark - Custom Accessors @@ -140,10 +143,20 @@ - (NSCalendar *)calendar - (CGRect)daysOfWeekViewFrame { + BOOL isPhone = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone; + BOOL isPortraitInterfaceOrientation = UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]); + CGRect namesOfDaysViewFrame = self.bounds; - namesOfDaysViewFrame.origin.x = (CGRectGetWidth(self.bounds) - RSDFDatePickerViewDaysOfWeekViewWidth) / 2; - namesOfDaysViewFrame.size.width = RSDFDatePickerViewDaysOfWeekViewWidth; - namesOfDaysViewFrame.size.height = RSDFDatePickerViewDaysOfWeekViewHeight; + if (isPhone) { + if (isPortraitInterfaceOrientation) { + namesOfDaysViewFrame.size.height = 22.0f; + } else { + namesOfDaysViewFrame.size.height = 26.0f; + } + } else { + namesOfDaysViewFrame.size.height = 36.0f; + } + return namesOfDaysViewFrame; } @@ -167,25 +180,25 @@ - (Class)collectionViewClass - (CGRect)collectionViewFrame { + CGFloat daysOfWeekViewHeight = CGRectGetHeight([self daysOfWeekViewFrame]); + CGRect collectionViewFrame = self.bounds; - collectionViewFrame.origin.x = (CGRectGetWidth(self.bounds) - RSDFDatePickerViewDaysOfWeekViewWidth) / 2; - collectionViewFrame.origin.y += RSDFDatePickerViewDaysOfWeekViewHeight; - collectionViewFrame.size.width = RSDFDatePickerViewDaysOfWeekViewWidth; - collectionViewFrame.size.height -= RSDFDatePickerViewDaysOfWeekViewHeight; + collectionViewFrame.origin.y += daysOfWeekViewHeight; + collectionViewFrame.size.height -= daysOfWeekViewHeight; return collectionViewFrame; } - (RSDFDatePickerCollectionView *)collectionView { - if (!_collectionView) { + if (!_collectionView) { _collectionView = [[[self collectionViewClass] alloc] initWithFrame:[self collectionViewFrame] collectionViewLayout:self.collectionViewLayout]; _collectionView.dataSource = self; _collectionView.delegate = self; [_collectionView registerClass:[self monthHeaderClass] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:RSDFDatePickerViewMonthHeaderIdentifier]; [_collectionView registerClass:[self dayCellClass] forCellWithReuseIdentifier:RSDFDatePickerViewDayCellIdentifier]; [_collectionView reloadData]; - } - return _collectionView; + } + return _collectionView; } - (Class)collectionViewLayoutClass @@ -195,10 +208,10 @@ - (Class)collectionViewLayoutClass - (RSDFDatePickerCollectionViewLayout *)collectionViewLayout { - if (!_collectionViewLayout) { + if (!_collectionViewLayout) { _collectionViewLayout = [[[self collectionViewLayoutClass] alloc] init]; - } - return _collectionViewLayout; + } + return _collectionViewLayout; } - (Class)monthHeaderClass @@ -233,45 +246,45 @@ - (void)significantTimeChange:(NSNotification *)notification - (void)scrollToToday:(BOOL)animated { - [self scrollToDate:self.today animated:animated]; + [self scrollToDate:self.today animated:animated]; } - (void)scrollToDate:(NSDate *)date animated:(BOOL)animated { - RSDFDatePickerCollectionView *cv = self.collectionView; - RSDFDatePickerCollectionViewLayout *cvLayout = (RSDFDatePickerCollectionViewLayout *)self.collectionView.collectionViewLayout; - - NSArray *visibleCells = [self.collectionView visibleCells]; - if (![visibleCells count]) - return; - - NSDateComponents *dateYearMonthComponents = [self.calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit) fromDate:date]; - NSDate *month = [self.calendar dateFromComponents:dateYearMonthComponents]; - - _fromDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:((^{ - NSDateComponents *components = [NSDateComponents new]; - components.month = -6; - return components; - })()) toDate:month options:0]]; - - _toDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:((^{ - NSDateComponents *components = [NSDateComponents new]; - components.month = 6; - return components; - })()) toDate:month options:0]]; - - [cv reloadData]; - [cvLayout invalidateLayout]; - [cvLayout prepareLayout]; - - NSInteger section = [self sectionForDate:date]; - - NSDate *firstDayInMonth = [self dateForFirstDayInSection:section]; - NSUInteger weekday = [self.calendar components:NSWeekdayCalendarUnit fromDate:firstDayInMonth].weekday; - NSInteger item = [self.calendar components:NSDayCalendarUnit fromDate:firstDayInMonth toDate:date options:0].day + (weekday - self.calendar.firstWeekday); - - NSIndexPath *cellIndexPath = [NSIndexPath indexPathForItem:item inSection:section]; - [self.collectionView scrollToItemAtIndexPath:cellIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:animated]; + RSDFDatePickerCollectionView *cv = self.collectionView; + RSDFDatePickerCollectionViewLayout *cvLayout = (RSDFDatePickerCollectionViewLayout *)self.collectionView.collectionViewLayout; + + NSArray *visibleCells = [self.collectionView visibleCells]; + if (![visibleCells count]) + return; + + NSDateComponents *dateYearMonthComponents = [self.calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit) fromDate:date]; + NSDate *month = [self.calendar dateFromComponents:dateYearMonthComponents]; + + _fromDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:((^{ + NSDateComponents *components = [NSDateComponents new]; + components.month = -6; + return components; + })()) toDate:month options:0]]; + + _toDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:((^{ + NSDateComponents *components = [NSDateComponents new]; + components.month = 6; + return components; + })()) toDate:month options:0]]; + + [cv reloadData]; + [cvLayout invalidateLayout]; + [cvLayout prepareLayout]; + + NSInteger section = [self sectionForDate:date]; + + NSDate *firstDayInMonth = [self dateForFirstDayInSection:section]; + NSUInteger weekday = [self.calendar components:NSWeekdayCalendarUnit fromDate:firstDayInMonth].weekday; + NSInteger item = [self.calendar components:NSDayCalendarUnit fromDate:firstDayInMonth toDate:date options:0].day + (weekday - self.calendar.firstWeekday); + + NSIndexPath *cellIndexPath = [NSIndexPath indexPathForItem:item inSection:section]; + [self.collectionView scrollToItemAtIndexPath:cellIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:animated]; } - (void)reloadData @@ -309,100 +322,100 @@ - (void)commonInitializer - (void)appendPastDates { - [self shiftDatesByComponents:((^{ - NSDateComponents *dateComponents = [NSDateComponents new]; - dateComponents.month = -6; - return dateComponents; - })())]; + [self shiftDatesByComponents:((^{ + NSDateComponents *dateComponents = [NSDateComponents new]; + dateComponents.month = -6; + return dateComponents; + })())]; } - (void)appendFutureDates { - [self shiftDatesByComponents:((^{ - NSDateComponents *dateComponents = [NSDateComponents new]; - dateComponents.month = 6; - return dateComponents; - })())]; + [self shiftDatesByComponents:((^{ + NSDateComponents *dateComponents = [NSDateComponents new]; + dateComponents.month = 6; + return dateComponents; + })())]; } - (void)shiftDatesByComponents:(NSDateComponents *)components { - RSDFDatePickerCollectionView *cv = self.collectionView; - RSDFDatePickerCollectionViewLayout *cvLayout = (RSDFDatePickerCollectionViewLayout *)self.collectionView.collectionViewLayout; - - NSArray *visibleCells = [self.collectionView visibleCells]; - if (![visibleCells count]) - return; - - NSIndexPath *fromIndexPath = [cv indexPathForCell:((UICollectionViewCell *)visibleCells[0]) ]; - NSInteger fromSection = fromIndexPath.section; - NSDate *fromSectionOfDate = [self dateForFirstDayInSection:fromSection]; + RSDFDatePickerCollectionView *cv = self.collectionView; + RSDFDatePickerCollectionViewLayout *cvLayout = (RSDFDatePickerCollectionViewLayout *)self.collectionView.collectionViewLayout; + + NSArray *visibleCells = [self.collectionView visibleCells]; + if (![visibleCells count]) + return; + + NSIndexPath *fromIndexPath = [cv indexPathForCell:((UICollectionViewCell *)visibleCells[0]) ]; + NSInteger fromSection = fromIndexPath.section; + NSDate *fromSectionOfDate = [self dateForFirstDayInSection:fromSection]; UICollectionViewLayoutAttributes *fromAttrs = [cvLayout layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:fromSection]]; - CGPoint fromSectionOrigin = [self convertPoint:fromAttrs.frame.origin fromView:cv]; - - _fromDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:components toDate:[self dateFromPickerDate:self.fromDate] options:0]]; - _toDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:components toDate:[self dateFromPickerDate:self.toDate] options:0]]; + CGPoint fromSectionOrigin = [self convertPoint:fromAttrs.frame.origin fromView:cv]; + + _fromDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:components toDate:[self dateFromPickerDate:self.fromDate] options:0]]; + _toDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:components toDate:[self dateFromPickerDate:self.toDate] options:0]]; #if 0 - - // This solution trips up the collection view a bit - // because our reload is reactionary, and happens before a relayout - // since we must do it to avoid flickering and to heckle the CA transaction (?) - // that could be a small red flag too - - [cv performBatchUpdates:^{ - - if (components.month < 0) { - - [cv deleteSections:[NSIndexSet indexSetWithIndexesInRange:(NSRange){ - cv.numberOfSections - abs(components.month), - abs(components.month) - }]]; - - [cv insertSections:[NSIndexSet indexSetWithIndexesInRange:(NSRange){ - 0, - abs(components.month) - }]]; - - } else { - - [cv insertSections:[NSIndexSet indexSetWithIndexesInRange:(NSRange){ - cv.numberOfSections, - abs(components.month) - }]]; - - [cv deleteSections:[NSIndexSet indexSetWithIndexesInRange:(NSRange){ - 0, - abs(components.month) - }]]; - - } - - } completion:^(BOOL finished) { - - NSLog(@"%s %x", __PRETTY_FUNCTION__, finished); - - }]; - - for (UIView *view in cv.subviews) - [view.layer removeAllAnimations]; - + + // This solution trips up the collection view a bit + // because our reload is reactionary, and happens before a relayout + // since we must do it to avoid flickering and to heckle the CA transaction (?) + // that could be a small red flag too + + [cv performBatchUpdates:^{ + + if (components.month < 0) { + + [cv deleteSections:[NSIndexSet indexSetWithIndexesInRange:(NSRange){ + cv.numberOfSections - abs(components.month), + abs(components.month) + }]]; + + [cv insertSections:[NSIndexSet indexSetWithIndexesInRange:(NSRange){ + 0, + abs(components.month) + }]]; + + } else { + + [cv insertSections:[NSIndexSet indexSetWithIndexesInRange:(NSRange){ + cv.numberOfSections, + abs(components.month) + }]]; + + [cv deleteSections:[NSIndexSet indexSetWithIndexesInRange:(NSRange){ + 0, + abs(components.month) + }]]; + + } + + } completion:^(BOOL finished) { + + NSLog(@"%s %x", __PRETTY_FUNCTION__, finished); + + }]; + + for (UIView *view in cv.subviews) + [view.layer removeAllAnimations]; + #else - - [cv reloadData]; - [cvLayout invalidateLayout]; - [cvLayout prepareLayout]; + + [cv reloadData]; + [cvLayout invalidateLayout]; + [cvLayout prepareLayout]; #endif - - NSInteger toSection = [self sectionForDate:fromSectionOfDate]; - UICollectionViewLayoutAttributes *toAttrs = [cvLayout layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:toSection]]; - CGPoint toSectionOrigin = [self convertPoint:toAttrs.frame.origin fromView:cv]; - - [cv setContentOffset:(CGPoint) { - cv.contentOffset.x, - cv.contentOffset.y + (toSectionOrigin.y - fromSectionOrigin.y) - }]; + + NSInteger toSection = [self sectionForDate:fromSectionOfDate]; + UICollectionViewLayoutAttributes *toAttrs = [cvLayout layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:toSection]]; + CGPoint toSectionOrigin = [self convertPoint:toAttrs.frame.origin fromView:cv]; + + [cv setContentOffset:(CGPoint) { + cv.contentOffset.x, + cv.contentOffset.y + (toSectionOrigin.y - fromSectionOrigin.y) + }]; } - (NSInteger)sectionForDate:(NSDate *)date; @@ -412,11 +425,11 @@ - (NSInteger)sectionForDate:(NSDate *)date; - (NSDate *)dateForFirstDayInSection:(NSInteger)section { - return [self.calendar dateByAddingComponents:((^{ - NSDateComponents *dateComponents = [NSDateComponents new]; - dateComponents.month = section; - return dateComponents; - })()) toDate:[self dateFromPickerDate:self.fromDate] options:0]; + return [self.calendar dateByAddingComponents:((^{ + NSDateComponents *dateComponents = [NSDateComponents new]; + dateComponents.month = section; + return dateComponents; + })()) toDate:[self dateFromPickerDate:self.fromDate] options:0]; } - (NSUInteger)numberOfWeeksForMonthOfDate:(NSDate *)date @@ -445,54 +458,54 @@ - (NSUInteger)numberOfWeeksForMonthOfDate:(NSDate *)date #else - NSDate *firstDayInMonth = [self.calendar dateFromComponents:[self.calendar components:NSYearCalendarUnit|NSMonthCalendarUnit fromDate:date]]; - - NSDate *lastDayInMonth = [self.calendar dateByAddingComponents:((^{ - NSDateComponents *dateComponents = [NSDateComponents new]; - dateComponents.month = 1; - dateComponents.day = -1; - return dateComponents; - })()) toDate:firstDayInMonth options:0]; - - NSDate *fromFirstWeekday = [self.calendar dateFromComponents:((^{ - NSDateComponents *dateComponents = [self.calendar components:NSWeekOfYearCalendarUnit|NSYearForWeekOfYearCalendarUnit fromDate:firstDayInMonth]; - dateComponents.weekday = self.calendar.firstWeekday; - return dateComponents; - })())]; - - NSDate *toFirstWeekday = [self.calendar dateFromComponents:((^{ - NSDateComponents *dateComponents = [self.calendar components:NSWeekOfYearCalendarUnit|NSYearForWeekOfYearCalendarUnit fromDate:lastDayInMonth]; - dateComponents.weekday = self.calendar.firstWeekday; - return dateComponents; - })())]; - - return 1 + [self.calendar components:NSWeekOfYearCalendarUnit fromDate:fromFirstWeekday toDate:toFirstWeekday options:0].weekOfYear; + NSDate *firstDayInMonth = [self.calendar dateFromComponents:[self.calendar components:NSYearCalendarUnit|NSMonthCalendarUnit fromDate:date]]; + + NSDate *lastDayInMonth = [self.calendar dateByAddingComponents:((^{ + NSDateComponents *dateComponents = [NSDateComponents new]; + dateComponents.month = 1; + dateComponents.day = -1; + return dateComponents; + })()) toDate:firstDayInMonth options:0]; + + NSDate *fromFirstWeekday = [self.calendar dateFromComponents:((^{ + NSDateComponents *dateComponents = [self.calendar components:NSWeekOfYearCalendarUnit|NSYearForWeekOfYearCalendarUnit fromDate:firstDayInMonth]; + dateComponents.weekday = self.calendar.firstWeekday; + return dateComponents; + })())]; + + NSDate *toFirstWeekday = [self.calendar dateFromComponents:((^{ + NSDateComponents *dateComponents = [self.calendar components:NSWeekOfYearCalendarUnit|NSYearForWeekOfYearCalendarUnit fromDate:lastDayInMonth]; + dateComponents.weekday = self.calendar.firstWeekday; + return dateComponents; + })())]; + + return 1 + [self.calendar components:NSWeekOfYearCalendarUnit fromDate:fromFirstWeekday toDate:toFirstWeekday options:0].weekOfYear; #endif } - (NSDate *)dateFromPickerDate:(RSDFDatePickerDate)dateStruct { - return [self.calendar dateFromComponents:[self dateComponentsFromPickerDate:dateStruct]]; + return [self.calendar dateFromComponents:[self dateComponentsFromPickerDate:dateStruct]]; } - (NSDateComponents *)dateComponentsFromPickerDate:(RSDFDatePickerDate)dateStruct { - NSDateComponents *components = [NSDateComponents new]; - components.year = dateStruct.year; - components.month = dateStruct.month; - components.day = dateStruct.day; - return components; + NSDateComponents *components = [NSDateComponents new]; + components.year = dateStruct.year; + components.month = dateStruct.month; + components.day = dateStruct.day; + return components; } - (RSDFDatePickerDate)pickerDateFromDate:(NSDate *)date { - NSDateComponents *components = [self.calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:date]; - return (RSDFDatePickerDate) { - components.year, - components.month, - components.day - }; + NSDateComponents *components = [self.calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:date]; + return (RSDFDatePickerDate) { + components.year, + components.month, + components.day + }; } - (NSUInteger)reorderedWeekday:(NSUInteger)weekday @@ -509,33 +522,33 @@ - (NSUInteger)reorderedWeekday:(NSUInteger)weekday - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { - return [self.calendar components:NSMonthCalendarUnit fromDate:[self dateFromPickerDate:self.fromDate] toDate:[self dateFromPickerDate:self.toDate] options:0].month; + return [self.calendar components:NSMonthCalendarUnit fromDate:[self dateFromPickerDate:self.fromDate] toDate:[self dateFromPickerDate:self.toDate] options:0].month; } - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { - return self.daysInWeek * [self numberOfWeeksForMonthOfDate:[self dateForFirstDayInSection:section]]; + return self.daysInWeek * [self numberOfWeeksForMonthOfDate:[self dateForFirstDayInSection:section]]; } - (RSDFDatePickerDayCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { - RSDFDatePickerDayCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:RSDFDatePickerViewDayCellIdentifier forIndexPath:indexPath]; - - NSDate *firstDayInMonth = [self dateForFirstDayInSection:indexPath.section]; - RSDFDatePickerDate firstDayPickerDate = [self pickerDateFromDate:firstDayInMonth]; - NSUInteger weekday = [self reorderedWeekday:[self.calendar components:NSWeekdayCalendarUnit fromDate:firstDayInMonth].weekday]; - - NSDate *cellDate = [self.calendar dateByAddingComponents:((^{ - NSDateComponents *dateComponents = [NSDateComponents new]; - dateComponents.day = indexPath.item - weekday; - return dateComponents; - })()) toDate:firstDayInMonth options:0]; - RSDFDatePickerDate cellPickerDate = [self pickerDateFromDate:cellDate]; - - cell.date = cellPickerDate; + RSDFDatePickerDayCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:RSDFDatePickerViewDayCellIdentifier forIndexPath:indexPath]; + + NSDate *firstDayInMonth = [self dateForFirstDayInSection:indexPath.section]; + RSDFDatePickerDate firstDayPickerDate = [self pickerDateFromDate:firstDayInMonth]; + NSUInteger weekday = [self reorderedWeekday:[self.calendar components:NSWeekdayCalendarUnit fromDate:firstDayInMonth].weekday]; + + NSDate *cellDate = [self.calendar dateByAddingComponents:((^{ + NSDateComponents *dateComponents = [NSDateComponents new]; + dateComponents.day = indexPath.item - weekday; + return dateComponents; + })()) toDate:firstDayInMonth options:0]; + RSDFDatePickerDate cellPickerDate = [self pickerDateFromDate:cellDate]; + + cell.date = cellPickerDate; cell.dateLabel.text = [NSString stringWithFormat:@"%lu", (unsigned long)(cellPickerDate.day)]; - cell.notThisMonth = !((firstDayPickerDate.year == cellPickerDate.year) && (firstDayPickerDate.month == cellPickerDate.month)); + cell.notThisMonth = !((firstDayPickerDate.year == cellPickerDate.year) && (firstDayPickerDate.month == cellPickerDate.month)); if (!cell.isNotThisMonth) { weekday = [self.calendar components:NSWeekdayCalendarUnit fromDate:cellDate].weekday; cell.dayOff = (weekday == 1) || (weekday == 7); @@ -551,31 +564,31 @@ - (RSDFDatePickerDayCell *)collectionView:(UICollectionView *)collectionView cel cell.today = ([cellDate compare:_today] == NSOrderedSame) ? YES : NO; } - return cell; + return cell; } - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath { - if ([kind isEqualToString:UICollectionElementKindSectionHeader]) { - - RSDFDatePickerMonthHeader *monthHeader = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:RSDFDatePickerViewMonthHeaderIdentifier forIndexPath:indexPath]; - + if ([kind isEqualToString:UICollectionElementKindSectionHeader]) { + + RSDFDatePickerMonthHeader *monthHeader = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:RSDFDatePickerViewMonthHeaderIdentifier forIndexPath:indexPath]; + NSString *dateFormatterName = [NSString stringWithFormat:@"calendarMonthHeader_%@_%@", [self.calendar calendarIdentifier], [[self.calendar locale] localeIdentifier]]; - NSDateFormatter *dateFormatter = [self.calendar df_dateFormatterNamed:dateFormatterName withConstructor:^{ - NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; - [dateFormatter setCalendar:self.calendar]; + NSDateFormatter *dateFormatter = [self.calendar df_dateFormatterNamed:dateFormatterName withConstructor:^{ + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setCalendar:self.calendar]; [dateFormatter setLocale:[self.calendar locale]]; - return dateFormatter; - }]; - - NSDate *formattedDate = [self dateForFirstDayInSection:indexPath.section]; + return dateFormatter; + }]; + + NSDate *formattedDate = [self dateForFirstDayInSection:indexPath.section]; RSDFDatePickerDate date = [self pickerDateFromDate:formattedDate]; monthHeader.date = date; NSString *monthString = [dateFormatter shortStandaloneMonthSymbols][date.month - 1]; monthHeader.dateLabel.text = [[NSString stringWithFormat:@"%@ %lu", monthString, (unsigned long)(date.year)] uppercaseString]; - + RSDFDatePickerDate today = [self pickerDateFromDate:_today]; if ( (today.month == date.month) && (today.year == date.year) ) { monthHeader.currentMonth = YES; @@ -583,11 +596,11 @@ - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView monthHeader.currentMonth = NO; } - return monthHeader; - - } - - return nil; + return monthHeader; + + } + + return nil; } #pragma mark - UICollectionViewDelegate @@ -600,12 +613,12 @@ - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView - (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath { - return !((RSDFDatePickerDayCell *)[collectionView cellForItemAtIndexPath:indexPath]).isNotThisMonth; + return !((RSDFDatePickerDayCell *)[collectionView cellForItemAtIndexPath:indexPath]).isNotThisMonth; } - (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath { - return !((RSDFDatePickerDayCell *)[collectionView cellForItemAtIndexPath:indexPath]).isNotThisMonth; + return !((RSDFDatePickerDayCell *)[collectionView cellForItemAtIndexPath:indexPath]).isNotThisMonth; } - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath @@ -617,32 +630,44 @@ - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPa } } +#pragma mark - UICollectionViewDelegateFlowLayout + +- (CGSize)collectionView:(UICollectionView *)collectionView layout:(RSDFDatePickerCollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section +{ + return [collectionViewLayout selfHeaderReferenceSize]; +} + +- (CGSize)collectionView:(UICollectionView *)collectionView layout:(RSDFDatePickerCollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath +{ + return [collectionViewLayout selfItemSize]; +} + #pragma mark - RSDFDatePickerCollectionViewDelegate - (void)pickerCollectionViewWillLayoutSubviews:(RSDFDatePickerCollectionView *)pickerCollectionView { - // Note: relayout is slower than calculating 3 or 6 months’ worth of data at a time - // So we punt 6 months at a time. - - // Running Time Self Symbol Name - // - // 1647.0ms 23.7% 1647.0 objc_msgSend - // 193.0ms 2.7% 193.0 -[NSIndexPath compare:] - // 163.0ms 2.3% 163.0 objc::DenseMap, objc::DenseMapInfo >::LookupBucketFor(objc_object* const&, std::pair*&) const - // 141.0ms 2.0% 141.0 DYLD-STUB$$-[_UIHostedTextServiceSession dismissTextServiceAnimated:] - // 138.0ms 1.9% 138.0 -[NSObject retain] - // 136.0ms 1.9% 136.0 -[NSIndexPath indexAtPosition:] - // 124.0ms 1.7% 124.0 -[_UICollectionViewItemKey isEqual:] - // 118.0ms 1.7% 118.0 _objc_rootReleaseWasZero - // 105.0ms 1.5% 105.0 DYLD-STUB$$CFDictionarySetValue$shim - - if (pickerCollectionView.contentOffset.y < 0.0f) { - [self appendPastDates]; - } - - if (pickerCollectionView.contentOffset.y > (pickerCollectionView.contentSize.height - CGRectGetHeight(pickerCollectionView.bounds))) { - [self appendFutureDates]; - } + // Note: relayout is slower than calculating 3 or 6 months’ worth of data at a time + // So we punt 6 months at a time. + + // Running Time Self Symbol Name + // + // 1647.0ms 23.7% 1647.0 objc_msgSend + // 193.0ms 2.7% 193.0 -[NSIndexPath compare:] + // 163.0ms 2.3% 163.0 objc::DenseMap, objc::DenseMapInfo >::LookupBucketFor(objc_object* const&, std::pair*&) const + // 141.0ms 2.0% 141.0 DYLD-STUB$$-[_UIHostedTextServiceSession dismissTextServiceAnimated:] + // 138.0ms 1.9% 138.0 -[NSObject retain] + // 136.0ms 1.9% 136.0 -[NSIndexPath indexAtPosition:] + // 124.0ms 1.7% 124.0 -[_UICollectionViewItemKey isEqual:] + // 118.0ms 1.7% 118.0 _objc_rootReleaseWasZero + // 105.0ms 1.5% 105.0 DYLD-STUB$$CFDictionarySetValue$shim + + if (pickerCollectionView.contentOffset.y < 0.0f) { + [self appendPastDates]; + } + + if (pickerCollectionView.contentOffset.y > (pickerCollectionView.contentSize.height - CGRectGetHeight(pickerCollectionView.bounds))) { + [self appendFutureDates]; + } } @end From d58944531f1efd6cb9d40ed366e84cca4196efcf Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Sat, 11 Oct 2014 13:55:21 +0300 Subject: [PATCH 57/87] Version bump (0.6.0) --- Example/RSDayFlowExample/RSDayFlowExample-Info.plist | 4 ++-- RSDayFlow.podspec | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist index 1682c46..0cdf46e 100644 --- a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist +++ b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.5.0 + 0.6.0 CFBundleSignature ???? CFBundleVersion - 0.5.0 + 0.6.0 LSRequiresIPhoneOS UILaunchStoryboardName diff --git a/RSDayFlow.podspec b/RSDayFlow.podspec index 8731fb6..33fec3c 100644 --- a/RSDayFlow.podspec +++ b/RSDayFlow.podspec @@ -1,11 +1,11 @@ Pod::Spec.new do |s| s.name = 'RSDayFlow' - s.version = '0.5.0' + s.version = '0.6.0' s.summary = 'iOS 7 Calendar with Infinite Scrolling.' s.homepage = 'https://github.com/ruslanskorb/RSDayFlow' s.license = { :type => 'MIT', :file => 'LICENSE' } s.authors = { 'Evadne Wu' => 'ev@radi.ws', 'Ruslan Skorb' => 'ruslan.skorb@gmail.com' } - s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.5.0' } + s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.6.0' } s.platform = :ios, '7.0' s.source_files = 'RSDayFlow' s.frameworks = 'QuartzCore', 'UIKit' From 90418ac09714784c74e4ca36a69fd6d087deb8f1 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Mon, 13 Oct 2014 22:10:44 +0300 Subject: [PATCH 58/87] [Fix] Deprecation warnings on iOS 7+. --- .../project.pbxproj | 1 + Example/RSDayFlowExample/RSDFAppDelegate.m | 10 +++--- .../RSDFDatePickerViewController.m | 12 +++---- RSDayFlow/RSDFDatePickerDaysOfWeekView.m | 2 +- RSDayFlow/RSDFDatePickerView.m | 34 +++++++++---------- 5 files changed, 30 insertions(+), 29 deletions(-) diff --git a/Example/RSDayFlowExample.xcodeproj/project.pbxproj b/Example/RSDayFlowExample.xcodeproj/project.pbxproj index bacf14a..b430179 100644 --- a/Example/RSDayFlowExample.xcodeproj/project.pbxproj +++ b/Example/RSDayFlowExample.xcodeproj/project.pbxproj @@ -439,6 +439,7 @@ GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", + "NS_ENABLE_CALENDAR_NEW_API=1", "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; diff --git a/Example/RSDayFlowExample/RSDFAppDelegate.m b/Example/RSDayFlowExample/RSDFAppDelegate.m index 12ccc22..1d12bb7 100644 --- a/Example/RSDayFlowExample/RSDFAppDelegate.m +++ b/Example/RSDayFlowExample/RSDFAppDelegate.m @@ -38,7 +38,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( // ------------------ RSDFDatePickerViewController *gregorianVC = [[RSDFDatePickerViewController alloc] init]; - gregorianVC.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; + gregorianVC.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; gregorianVC.calendar.locale = [NSLocale currentLocale]; UINavigationController *gregorianNC = [[UINavigationController alloc] initWithRootViewController:gregorianVC]; @@ -47,7 +47,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( // --------------- RSDFDatePickerViewController *hebrewVC = [[RSDFDatePickerViewController alloc] init]; - hebrewVC.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSHebrewCalendar]; + hebrewVC.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierHebrew]; hebrewVC.calendar.locale = [NSLocale currentLocale]; UINavigationController *hebrewNC = [[UINavigationController alloc] initWithRootViewController:hebrewVC]; @@ -56,7 +56,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( // ---------------- RSDFDatePickerViewController *islamicVC = [[RSDFDatePickerViewController alloc] init]; - islamicVC.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSIslamicCalendar]; + islamicVC.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierIslamic]; islamicVC.calendar.locale = [NSLocale currentLocale]; UINavigationController *islamicNC = [[UINavigationController alloc] initWithRootViewController:islamicVC]; @@ -65,7 +65,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( // --------------- RSDFDatePickerViewController *indianVC = [[RSDFDatePickerViewController alloc] init]; - indianVC.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSIndianCalendar]; + indianVC.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierIndian]; indianVC.calendar.locale = [NSLocale currentLocale]; UINavigationController *indianNC = [[UINavigationController alloc] initWithRootViewController:indianVC]; @@ -74,7 +74,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( // ---------------- RSDFDatePickerViewController *persianVC = [[RSDFDatePickerViewController alloc] init]; - persianVC.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSPersianCalendar]; + persianVC.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierPersian]; persianVC.calendar.locale = [NSLocale currentLocale]; UINavigationController *persianNC = [[UINavigationController alloc] initWithRootViewController:persianVC]; diff --git a/Example/RSDayFlowExample/RSDFDatePickerViewController.m b/Example/RSDayFlowExample/RSDFDatePickerViewController.m index 996d224..999f892 100755 --- a/Example/RSDayFlowExample/RSDFDatePickerViewController.m +++ b/Example/RSDayFlowExample/RSDFDatePickerViewController.m @@ -57,10 +57,10 @@ - (void)viewDidLoad [self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault]; self.navigationController.navigationBar.shadowImage = [[UIImage alloc] init]; - UIBarButtonItem *today = [[UIBarButtonItem alloc] initWithTitle:@"Today" style:UIBarButtonItemStyleBordered target:self action:@selector(onTodayButtonTouch:)]; + UIBarButtonItem *today = [[UIBarButtonItem alloc] initWithTitle:@"Today" style:UIBarButtonItemStylePlain target:self action:@selector(onTodayButtonTouch:)]; self.navigationItem.rightBarButtonItem = today; - UIBarButtonItem *restyle = [[UIBarButtonItem alloc] initWithTitle:@"Restyle" style:UIBarButtonItemStyleBordered target:self action:@selector(onRestyleButtonTouch:)]; + UIBarButtonItem *restyle = [[UIBarButtonItem alloc] initWithTitle:@"Restyle" style:UIBarButtonItemStylePlain target:self action:@selector(onRestyleButtonTouch:)]; self.navigationItem.leftBarButtonItem = restyle; self.view.backgroundColor = [UIColor colorWithWhite:0.8 alpha:0.3]; @@ -85,8 +85,8 @@ - (void)setCalendar:(NSCalendar *)calendar - (NSArray *)datesToMark { if (!_datesToMark) { - NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; - NSDateComponents *todayComponents = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]]; + NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; + NSDateComponents *todayComponents = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:[NSDate date]]; NSDate *today = [calendar dateFromComponents:todayComponents]; NSArray *numberOfDaysFromToday = @[@(-8), @(-2), @(-1), @(0), @(2), @(4), @(8), @(13), @(22)]; @@ -107,8 +107,8 @@ - (NSArray *)datesToMark - (NSDictionary *)statesOfTasks { if (!_statesOfTasks) { - NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; - NSDateComponents *todayComponents = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]]; + NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; + NSDateComponents *todayComponents = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:[NSDate date]]; NSDate *today = [calendar dateFromComponents:todayComponents]; NSMutableDictionary *statesOfTasks = [[NSMutableDictionary alloc] initWithCapacity:[self.datesToMark count]]; diff --git a/RSDayFlow/RSDFDatePickerDaysOfWeekView.m b/RSDayFlow/RSDFDatePickerDaysOfWeekView.m index 9fa0d94..c49fa4c 100644 --- a/RSDayFlow/RSDFDatePickerDaysOfWeekView.m +++ b/RSDayFlow/RSDFDatePickerDaysOfWeekView.m @@ -81,7 +81,7 @@ - (void)layoutSubviews - (NSCalendar *)calendar { if (!_calendar) { - _calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; + _calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; _calendar.locale = [NSLocale currentLocale]; } return _calendar; diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index 53fbefc..9819b21 100755 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -135,7 +135,7 @@ - (void)willMoveToSuperview:(UIView *)newSuperview - (NSCalendar *)calendar { if (!_calendar) { - _calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; + _calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; _calendar.locale = [NSLocale currentLocale]; } return _calendar; @@ -227,7 +227,7 @@ - (Class)dayCellClass - (NSUInteger)daysInWeek { if (_daysInWeek == 0) { - _daysInWeek = [self.calendar maximumRangeOfUnit:NSWeekdayCalendarUnit].length; + _daysInWeek = [self.calendar maximumRangeOfUnit:NSCalendarUnitWeekday].length; } return _daysInWeek; } @@ -236,7 +236,7 @@ - (NSUInteger)daysInWeek - (void)significantTimeChange:(NSNotification *)notification { - NSDateComponents *todayYearMonthDayComponents = [self.calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]]; + NSDateComponents *todayYearMonthDayComponents = [self.calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:[NSDate date]]; _today = [self.calendar dateFromComponents:todayYearMonthDayComponents]; [self.collectionView reloadData]; @@ -258,7 +258,7 @@ - (void)scrollToDate:(NSDate *)date animated:(BOOL)animated if (![visibleCells count]) return; - NSDateComponents *dateYearMonthComponents = [self.calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit) fromDate:date]; + NSDateComponents *dateYearMonthComponents = [self.calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth) fromDate:date]; NSDate *month = [self.calendar dateFromComponents:dateYearMonthComponents]; _fromDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:((^{ @@ -280,8 +280,8 @@ - (void)scrollToDate:(NSDate *)date animated:(BOOL)animated NSInteger section = [self sectionForDate:date]; NSDate *firstDayInMonth = [self dateForFirstDayInSection:section]; - NSUInteger weekday = [self.calendar components:NSWeekdayCalendarUnit fromDate:firstDayInMonth].weekday; - NSInteger item = [self.calendar components:NSDayCalendarUnit fromDate:firstDayInMonth toDate:date options:0].day + (weekday - self.calendar.firstWeekday); + NSUInteger weekday = [self.calendar components:NSCalendarUnitWeekday fromDate:firstDayInMonth].weekday; + NSInteger item = [self.calendar components:NSCalendarUnitDay fromDate:firstDayInMonth toDate:date options:0].day + (weekday - self.calendar.firstWeekday); NSIndexPath *cellIndexPath = [NSIndexPath indexPathForItem:item inSection:section]; [self.collectionView scrollToItemAtIndexPath:cellIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:animated]; @@ -296,7 +296,7 @@ - (void)reloadData - (void)commonInitializer { - NSDateComponents *nowYearMonthComponents = [self.calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit) fromDate:[NSDate date]]; + NSDateComponents *nowYearMonthComponents = [self.calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth) fromDate:[NSDate date]]; NSDate *now = [self.calendar dateFromComponents:nowYearMonthComponents]; _fromDate = [self pickerDateFromDate:[self.calendar dateByAddingComponents:((^{ @@ -311,7 +311,7 @@ - (void)commonInitializer return components; })()) toDate:now options:0]]; - NSDateComponents *todayYearMonthDayComponents = [self.calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]]; + NSDateComponents *todayYearMonthDayComponents = [self.calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:[NSDate date]]; _today = [self.calendar dateFromComponents:todayYearMonthDayComponents]; [[NSNotificationCenter defaultCenter] addObserver:self @@ -420,7 +420,7 @@ - (void)shiftDatesByComponents:(NSDateComponents *)components - (NSInteger)sectionForDate:(NSDate *)date; { - return [self.calendar components:NSMonthCalendarUnit fromDate:[self dateForFirstDayInSection:0] toDate:date options:0].month; + return [self.calendar components:NSCalendarUnitMonth fromDate:[self dateForFirstDayInSection:0] toDate:date options:0].month; } - (NSDate *)dateForFirstDayInSection:(NSInteger)section @@ -458,7 +458,7 @@ - (NSUInteger)numberOfWeeksForMonthOfDate:(NSDate *)date #else - NSDate *firstDayInMonth = [self.calendar dateFromComponents:[self.calendar components:NSYearCalendarUnit|NSMonthCalendarUnit fromDate:date]]; + NSDate *firstDayInMonth = [self.calendar dateFromComponents:[self.calendar components:NSCalendarUnitYear|NSCalendarUnitMonth fromDate:date]]; NSDate *lastDayInMonth = [self.calendar dateByAddingComponents:((^{ NSDateComponents *dateComponents = [NSDateComponents new]; @@ -468,18 +468,18 @@ - (NSUInteger)numberOfWeeksForMonthOfDate:(NSDate *)date })()) toDate:firstDayInMonth options:0]; NSDate *fromFirstWeekday = [self.calendar dateFromComponents:((^{ - NSDateComponents *dateComponents = [self.calendar components:NSWeekOfYearCalendarUnit|NSYearForWeekOfYearCalendarUnit fromDate:firstDayInMonth]; + NSDateComponents *dateComponents = [self.calendar components:NSCalendarUnitWeekOfYear|NSCalendarUnitYearForWeekOfYear fromDate:firstDayInMonth]; dateComponents.weekday = self.calendar.firstWeekday; return dateComponents; })())]; NSDate *toFirstWeekday = [self.calendar dateFromComponents:((^{ - NSDateComponents *dateComponents = [self.calendar components:NSWeekOfYearCalendarUnit|NSYearForWeekOfYearCalendarUnit fromDate:lastDayInMonth]; + NSDateComponents *dateComponents = [self.calendar components:NSCalendarUnitWeekOfYear|NSCalendarUnitYearForWeekOfYear fromDate:lastDayInMonth]; dateComponents.weekday = self.calendar.firstWeekday; return dateComponents; })())]; - return 1 + [self.calendar components:NSWeekOfYearCalendarUnit fromDate:fromFirstWeekday toDate:toFirstWeekday options:0].weekOfYear; + return 1 + [self.calendar components:NSCalendarUnitWeekOfYear fromDate:fromFirstWeekday toDate:toFirstWeekday options:0].weekOfYear; #endif } @@ -500,7 +500,7 @@ - (NSDateComponents *)dateComponentsFromPickerDate:(RSDFDatePickerDate)dateStruc - (RSDFDatePickerDate)pickerDateFromDate:(NSDate *)date { - NSDateComponents *components = [self.calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:date]; + NSDateComponents *components = [self.calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:date]; return (RSDFDatePickerDate) { components.year, components.month, @@ -522,7 +522,7 @@ - (NSUInteger)reorderedWeekday:(NSUInteger)weekday - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { - return [self.calendar components:NSMonthCalendarUnit fromDate:[self dateFromPickerDate:self.fromDate] toDate:[self dateFromPickerDate:self.toDate] options:0].month; + return [self.calendar components:NSCalendarUnitMonth fromDate:[self dateFromPickerDate:self.fromDate] toDate:[self dateFromPickerDate:self.toDate] options:0].month; } - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section @@ -536,7 +536,7 @@ - (RSDFDatePickerDayCell *)collectionView:(UICollectionView *)collectionView cel NSDate *firstDayInMonth = [self dateForFirstDayInSection:indexPath.section]; RSDFDatePickerDate firstDayPickerDate = [self pickerDateFromDate:firstDayInMonth]; - NSUInteger weekday = [self reorderedWeekday:[self.calendar components:NSWeekdayCalendarUnit fromDate:firstDayInMonth].weekday]; + NSUInteger weekday = [self reorderedWeekday:[self.calendar components:NSCalendarUnitWeekday fromDate:firstDayInMonth].weekday]; NSDate *cellDate = [self.calendar dateByAddingComponents:((^{ NSDateComponents *dateComponents = [NSDateComponents new]; @@ -550,7 +550,7 @@ - (RSDFDatePickerDayCell *)collectionView:(UICollectionView *)collectionView cel cell.notThisMonth = !((firstDayPickerDate.year == cellPickerDate.year) && (firstDayPickerDate.month == cellPickerDate.month)); if (!cell.isNotThisMonth) { - weekday = [self.calendar components:NSWeekdayCalendarUnit fromDate:cellDate].weekday; + weekday = [self.calendar components:NSCalendarUnitWeekday fromDate:cellDate].weekday; cell.dayOff = (weekday == 1) || (weekday == 7); if ([self.dataSource respondsToSelector:@selector(datePickerView:shouldMarkDate:)]) { From 15aae61f936dc03c100b1a1b0bb700a0ec48882e Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Mon, 13 Oct 2014 22:19:10 +0300 Subject: [PATCH 59/87] =?UTF-8?q?[Update]=20Use=20the=20calendar=20from=20?= =?UTF-8?q?the=20property=20instead=20of=20creating=20=D0=B0=20new=20one.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RSDayFlowExample/RSDFDatePickerViewController.m | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/Example/RSDayFlowExample/RSDFDatePickerViewController.m b/Example/RSDayFlowExample/RSDFDatePickerViewController.m index 999f892..18689e2 100755 --- a/Example/RSDayFlowExample/RSDFDatePickerViewController.m +++ b/Example/RSDayFlowExample/RSDFDatePickerViewController.m @@ -85,9 +85,8 @@ - (void)setCalendar:(NSCalendar *)calendar - (NSArray *)datesToMark { if (!_datesToMark) { - NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; - NSDateComponents *todayComponents = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:[NSDate date]]; - NSDate *today = [calendar dateFromComponents:todayComponents]; + NSDateComponents *todayComponents = [self.calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:[NSDate date]]; + NSDate *today = [self.calendar dateFromComponents:todayComponents]; NSArray *numberOfDaysFromToday = @[@(-8), @(-2), @(-1), @(0), @(2), @(4), @(8), @(13), @(22)]; @@ -95,7 +94,7 @@ - (NSArray *)datesToMark NSMutableArray *datesToMark = [[NSMutableArray alloc] initWithCapacity:[numberOfDaysFromToday count]]; [numberOfDaysFromToday enumerateObjectsUsingBlock:^(NSNumber *numberOfDays, NSUInteger idx, BOOL *stop) { dateComponents.day = [numberOfDays integerValue]; - NSDate *date = [calendar dateByAddingComponents:dateComponents toDate:today options:0]; + NSDate *date = [self.calendar dateByAddingComponents:dateComponents toDate:today options:0]; [datesToMark addObject:date]; }]; @@ -107,9 +106,8 @@ - (NSArray *)datesToMark - (NSDictionary *)statesOfTasks { if (!_statesOfTasks) { - NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; - NSDateComponents *todayComponents = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:[NSDate date]]; - NSDate *today = [calendar dateFromComponents:todayComponents]; + NSDateComponents *todayComponents = [self.calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:[NSDate date]]; + NSDate *today = [self.calendar dateFromComponents:todayComponents]; NSMutableDictionary *statesOfTasks = [[NSMutableDictionary alloc] initWithCapacity:[self.datesToMark count]]; [self.datesToMark enumerateObjectsUsingBlock:^(NSDate *date, NSUInteger idx, BOOL *stop) { From ff9976a44da889047b72a79a7ecba62daf92078c Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Sat, 18 Oct 2014 20:15:56 +0300 Subject: [PATCH 60/87] Version bump (0.6.1) --- Example/RSDayFlowExample/RSDayFlowExample-Info.plist | 4 ++-- RSDayFlow.podspec | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist index 0cdf46e..de724ca 100644 --- a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist +++ b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.6.0 + 0.6.1 CFBundleSignature ???? CFBundleVersion - 0.6.0 + 0.6.1 LSRequiresIPhoneOS UILaunchStoryboardName diff --git a/RSDayFlow.podspec b/RSDayFlow.podspec index 33fec3c..63ef9c8 100644 --- a/RSDayFlow.podspec +++ b/RSDayFlow.podspec @@ -1,11 +1,11 @@ Pod::Spec.new do |s| s.name = 'RSDayFlow' - s.version = '0.6.0' + s.version = '0.6.1' s.summary = 'iOS 7 Calendar with Infinite Scrolling.' s.homepage = 'https://github.com/ruslanskorb/RSDayFlow' s.license = { :type => 'MIT', :file => 'LICENSE' } s.authors = { 'Evadne Wu' => 'ev@radi.ws', 'Ruslan Skorb' => 'ruslan.skorb@gmail.com' } - s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.6.0' } + s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.6.1' } s.platform = :ios, '7.0' s.source_files = 'RSDayFlow' s.frameworks = 'QuartzCore', 'UIKit' From 496164601bee321e8a99eece23a11c2e71583f22 Mon Sep 17 00:00:00 2001 From: Leo Natan Date: Thu, 4 Sep 2014 15:30:01 +0300 Subject: [PATCH 61/87] Better scrollToToday behavior Scroll month to top, including section header (month name). The behavior is now similar to native calendar. --- RSDayFlow/RSDFDatePickerView.m | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index b9c52c4..3e191c3 100644 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -259,14 +259,9 @@ - (void)scrollToToday:(BOOL)animated [cvLayout invalidateLayout]; [cvLayout prepareLayout]; - NSInteger section = [self sectionForDate:_today]; - - NSDate *firstDayInMonth = [self dateForFirstDayInSection:section]; - NSUInteger weekday = [self.calendar components:NSWeekdayCalendarUnit fromDate:firstDayInMonth].weekday; - NSInteger item = [self.calendar components:NSDayCalendarUnit fromDate:firstDayInMonth toDate:self.today options:0].day + (weekday - self.calendar.firstWeekday); - - NSIndexPath *cellIndexPath = [NSIndexPath indexPathForItem:item inSection:section]; - [self.collectionView scrollToItemAtIndexPath:cellIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:animated]; + NSInteger section = [self sectionForDate:_today]; + + [self _scrollToTopOfSection:section animated:animated]; } - (void)reloadData @@ -490,6 +485,21 @@ - (RSDFDatePickerDate)pickerDateFromDate:(NSDate *)date }; } +- (CGRect)_frameForHeaderForSection:(NSInteger)section { + NSIndexPath *indexPath = [NSIndexPath indexPathForItem:1 inSection:section]; + UICollectionViewLayoutAttributes *attributes = [self.collectionView layoutAttributesForItemAtIndexPath:indexPath]; + CGRect frameForFirstCell = attributes.frame; + CGFloat headerHeight = self.collectionViewLayout.headerReferenceSize.height; + + return CGRectOffset(frameForFirstCell, 0, -headerHeight); +} + +- (void)_scrollToTopOfSection:(NSInteger)section animated:(BOOL)animated { + CGRect headerRect = [self _frameForHeaderForSection:section]; + CGPoint topOfHeader = CGPointMake(0, headerRect.origin.y - _collectionView.contentInset.top); + [_collectionView setContentOffset:topOfHeader animated:animated]; +} + #pragma mark - UICollectionViewDataSource - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView From 22223069a7ae6f212d2a2b08fcbf43e49f966113 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Sat, 18 Oct 2014 22:27:07 +0300 Subject: [PATCH 62/87] [Update] Names of some methods. --- RSDayFlow/RSDFDatePickerView.m | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index dec2f46..6d8f71e 100755 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -279,7 +279,7 @@ - (void)scrollToDate:(NSDate *)date animated:(BOOL)animated NSInteger section = [self sectionForDate:_today]; - [self _scrollToTopOfSection:section animated:animated]; + [self scrollToTopOfSection:section animated:animated]; } - (void)reloadData @@ -513,7 +513,8 @@ - (NSUInteger)reorderedWeekday:(NSUInteger)weekday return ordered; } -- (CGRect)_frameForHeaderForSection:(NSInteger)section { +- (CGRect)frameForHeaderForSection:(NSInteger)section +{ NSIndexPath *indexPath = [NSIndexPath indexPathForItem:1 inSection:section]; UICollectionViewLayoutAttributes *attributes = [self.collectionView layoutAttributesForItemAtIndexPath:indexPath]; CGRect frameForFirstCell = attributes.frame; @@ -522,8 +523,9 @@ - (CGRect)_frameForHeaderForSection:(NSInteger)section { return CGRectOffset(frameForFirstCell, 0, -headerHeight); } -- (void)_scrollToTopOfSection:(NSInteger)section animated:(BOOL)animated { - CGRect headerRect = [self _frameForHeaderForSection:section]; +- (void)scrollToTopOfSection:(NSInteger)section animated:(BOOL)animated +{ + CGRect headerRect = [self frameForHeaderForSection:section]; CGPoint topOfHeader = CGPointMake(0, headerRect.origin.y - _collectionView.contentInset.top); [_collectionView setContentOffset:topOfHeader animated:animated]; } From 29f5d770ac0e78f8417037d9ebbf75180effc34f Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Sat, 18 Oct 2014 22:33:11 +0300 Subject: [PATCH 63/87] [Fix] Frame for header for section. --- RSDayFlow/RSDFDatePickerView.m | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index 6d8f71e..3047c19 100755 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -515,12 +515,10 @@ - (NSUInteger)reorderedWeekday:(NSUInteger)weekday - (CGRect)frameForHeaderForSection:(NSInteger)section { - NSIndexPath *indexPath = [NSIndexPath indexPathForItem:1 inSection:section]; - UICollectionViewLayoutAttributes *attributes = [self.collectionView layoutAttributesForItemAtIndexPath:indexPath]; - CGRect frameForFirstCell = attributes.frame; - CGFloat headerHeight = self.collectionViewLayout.headerReferenceSize.height; - - return CGRectOffset(frameForFirstCell, 0, -headerHeight); + NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:section]; + UICollectionViewLayoutAttributes *attributes = [self.collectionView layoutAttributesForSupplementaryElementOfKind:UICollectionElementKindSectionHeader atIndexPath:indexPath]; + + return attributes.frame; } - (void)scrollToTopOfSection:(NSInteger)section animated:(BOOL)animated From 1f74cd000c4c62eaa356892c5a8e8b661eb171b3 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Sat, 18 Oct 2014 22:39:50 +0300 Subject: [PATCH 64/87] [Fix] Section in the method "scrollToDate:animated:". --- RSDayFlow/RSDFDatePickerView.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index 3047c19..c1344a2 100755 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -277,7 +277,7 @@ - (void)scrollToDate:(NSDate *)date animated:(BOOL)animated [cvLayout invalidateLayout]; [cvLayout prepareLayout]; - NSInteger section = [self sectionForDate:_today]; + NSInteger section = [self sectionForDate:date]; [self scrollToTopOfSection:section animated:animated]; } From b3fbdbb948fa3ac80b9c29d9c3602ee96dad67e6 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Sat, 18 Oct 2014 23:49:13 +0300 Subject: [PATCH 65/87] [Update] Scrolling for the landscape interface orientation. --- RSDayFlow/RSDFDatePickerView.m | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index c1344a2..a16f14d 100755 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -277,9 +277,23 @@ - (void)scrollToDate:(NSDate *)date animated:(BOOL)animated [cvLayout invalidateLayout]; [cvLayout prepareLayout]; - NSInteger section = [self sectionForDate:date]; - - [self scrollToTopOfSection:section animated:animated]; + NSInteger monthSection = [self sectionForDate:date]; + + NSDate *firstDayInMonth = [self dateForFirstDayInSection:monthSection]; + NSUInteger weekday = [self.calendar components:NSCalendarUnitWeekday fromDate:firstDayInMonth].weekday; + NSInteger dateItem = [self.calendar components:NSCalendarUnitDay fromDate:firstDayInMonth toDate:date options:0].day + (weekday - self.calendar.firstWeekday); + + CGRect dateItemRect = [self frameForItem:dateItem inSection:monthSection]; + CGRect monthHeaderRect = [self frameForHeaderForSection:monthSection]; + + CGFloat delta = CGRectGetMaxY(dateItemRect) - CGRectGetMinY(monthHeaderRect); + CGFloat actualViewHeight = CGRectGetHeight(self.collectionView.frame) - self.collectionView.contentInset.top - self.collectionView.contentInset.bottom; + + if (delta <= actualViewHeight) { + [self scrollToTopOfSection:monthSection animated:animated]; + } else { + [self scrollToBottomOfItem:dateItem inSection:monthSection animated:animated]; + } } - (void)reloadData @@ -521,6 +535,14 @@ - (CGRect)frameForHeaderForSection:(NSInteger)section return attributes.frame; } +- (CGRect)frameForItem:(NSInteger)item inSection:(NSInteger)section +{ + NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section]; + UICollectionViewLayoutAttributes *attributes = [self.collectionView layoutAttributesForItemAtIndexPath:indexPath]; + + return attributes.frame; +} + - (void)scrollToTopOfSection:(NSInteger)section animated:(BOOL)animated { CGRect headerRect = [self frameForHeaderForSection:section]; @@ -528,6 +550,12 @@ - (void)scrollToTopOfSection:(NSInteger)section animated:(BOOL)animated [_collectionView setContentOffset:topOfHeader animated:animated]; } +- (void)scrollToBottomOfItem:(NSInteger)item inSection:(NSInteger)section animated:(BOOL)animated +{ + NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section]; + [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionBottom animated:animated]; +} + #pragma mark - UICollectionViewDataSource - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView From 7bd9d6a7d5a309551a27d62fa7744998cadfeecf Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Thu, 23 Oct 2014 09:17:00 +0300 Subject: [PATCH 66/87] [Add] Visual feedback of the currently selected cell. Resolves #25, close #31. --- .../RSDFCustomDatePickerDayCell.m | 27 ++- .../RSDFDatePickerViewController.m | 12 +- RSDayFlow/RSDFDatePickerDayCell.h | 52 +++- RSDayFlow/RSDFDatePickerDayCell.m | 227 +++++++++--------- RSDayFlow/RSDFDatePickerView.h | 53 +++- RSDayFlow/RSDFDatePickerView.m | 155 +++++++++--- 6 files changed, 362 insertions(+), 164 deletions(-) diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerDayCell.m b/Example/RSDayFlowExample/RSDFCustomDatePickerDayCell.m index 00366ed..1eff969 100644 --- a/Example/RSDayFlowExample/RSDFCustomDatePickerDayCell.m +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerDayCell.m @@ -37,6 +37,21 @@ - (UIColor *)dayLabelTextColor return [UIColor colorWithRed:51/255.0f green:37/255.0f blue:36/255.0f alpha:1.0f]; } +- (UIColor *)selectedDayImageColor +{ + return [UIColor clearColor]; +} + +- (UIFont *)selectedDayLabelFont +{ + return [self dayLabelFont]; +} + +- (UIColor *)selectedDayLabelTextColor +{ + return [self dayLabelTextColor]; +} + - (UIColor *)dayOffLabelTextColor { return [UIColor colorWithRed:51/255.0f green:37/255.0f blue:36/255.0f alpha:1.0f]; @@ -52,11 +67,21 @@ - (UIColor *)todayLabelTextColor return [UIColor colorWithRed:3/255.0f green:117/255.0f blue:214/255.0f alpha:1.0f]; } -- (UIColor *)todayImageColor +- (UIColor *)selectedTodayImageColor { return [UIColor clearColor]; } +- (UIFont *)selectedTodayLabelFont +{ + return [self todayLabelFont]; +} + +- (UIColor *)selectedTodayLabelTextColor +{ + return [self todayLabelTextColor]; +} + - (UIColor *)overlayImageColor { return [UIColor colorWithWhite:1.0f alpha:1.0f]; diff --git a/Example/RSDayFlowExample/RSDFDatePickerViewController.m b/Example/RSDayFlowExample/RSDFDatePickerViewController.m index 18689e2..79f289d 100755 --- a/Example/RSDayFlowExample/RSDFDatePickerViewController.m +++ b/Example/RSDayFlowExample/RSDFDatePickerViewController.m @@ -57,14 +57,18 @@ - (void)viewDidLoad [self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault]; self.navigationController.navigationBar.shadowImage = [[UIImage alloc] init]; - UIBarButtonItem *today = [[UIBarButtonItem alloc] initWithTitle:@"Today" style:UIBarButtonItemStylePlain target:self action:@selector(onTodayButtonTouch:)]; - self.navigationItem.rightBarButtonItem = today; + UIBarButtonItem *todayBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Today" style:UIBarButtonItemStylePlain target:self action:@selector(onTodayButtonTouch:)]; + self.navigationItem.rightBarButtonItem = todayBarButtonItem; - UIBarButtonItem *restyle = [[UIBarButtonItem alloc] initWithTitle:@"Restyle" style:UIBarButtonItemStylePlain target:self action:@selector(onRestyleButtonTouch:)]; - self.navigationItem.leftBarButtonItem = restyle; + UIBarButtonItem *restyleBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Restyle" style:UIBarButtonItemStylePlain target:self action:@selector(onRestyleButtonTouch:)]; + self.navigationItem.leftBarButtonItem = restyleBarButtonItem; self.view.backgroundColor = [UIColor colorWithWhite:0.8 alpha:0.3]; + NSDateComponents *todayComponents = [self.calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:[NSDate date]]; + NSDate *today = [self.calendar dateFromComponents:todayComponents]; + [self.datePickerView selectDate:today]; + self.customDatePickerView.hidden = YES; [self.view addSubview:self.customDatePickerView]; diff --git a/RSDayFlow/RSDFDatePickerDayCell.h b/RSDayFlow/RSDFDatePickerDayCell.h index 1eceddf..fa3f928 100644 --- a/RSDayFlow/RSDFDatePickerDayCell.h +++ b/RSDayFlow/RSDFDatePickerDayCell.h @@ -120,32 +120,74 @@ - (UIColor *)notThisMonthLabelTextColor; /** - The font for the label of the current day. Default value is [UIFont fontWithName:@"HelveticaNeue-Bold" size:19.0f]. + The font for the label of the current day. Default value is [UIFont fontWithName:@"HelveticaNeue" size:18.0f]. @discussion Can be overridden in subclasses for customization. */ - (UIFont *)todayLabelFont; /** - The text color for the label of the current day. Default value is [UIColor whiteColor]. + The text color for the label of the current day. Default value is [UIColor colorWithRed:0/255.0f green:121/255.0f blue:255/255.0f alpha:1.0f]. @discussion Can be overridden in subclasses for customization. */ - (UIColor *)todayLabelTextColor; +/** + The font for the label of the current day when it is selected. Default value is [UIFont fontWithName:@"HelveticaNeue-Bold" size:19.0f]. + + @discussion Can be overridden in subclasses for customization. + */ +- (UIFont *)selectedTodayLabelFont; + +/** + The text color for the label of the current day when it is selected. Default value is [UIColor whiteColor]. + + @discussion Can be overridden in subclasses for customization. + */ +- (UIColor *)selectedTodayLabelTextColor; + /** The color of the background image for the cell of the current day. Default value is [UIColor colorWithRed:0/255.0f green:121/255.0f blue:255/255.0f alpha:1.0f]. - @discussion Can be overridden in subclasses for customization. Ignored if `customTodayImage` is not equal to `nil`. + @discussion Can be overridden in subclasses for customization. Ignored if `customSelectedTodayImage` is not equal to `nil`. */ -- (UIColor *)todayImageColor; +- (UIColor *)selectedTodayImageColor; /** The custom background image for the cell of the current day. Default value is `nil`. @discussion Can be overridden in subclasses for customization. */ -- (UIImage *)customTodayImage; +- (UIImage *)customSelectedTodayImage; + +/** + The font for the label of the day when it is selected. Default value is [UIFont fontWithName:@"HelveticaNeue-Bold" size:19.0f]. + + @discussion Can be overridden in subclasses for customization. + */ +- (UIFont *)selectedDayLabelFont; + +/** + The text color for the label of the day when it is selected. Default value is [UIColor whiteColor]. + + @discussion Can be overridden in subclasses for customization. + */ +- (UIColor *)selectedDayLabelTextColor; + +/** + The color of the background image for the cell of the day when it is selected. Default value is [UIColor colorWithRed:255/255.0f green:59/255.0f blue:48/255.0f alpha:1.0f]. + + @discussion Can be overridden in subclasses for customization. Ignored if `customSelectedDayImage` is not equal to `nil`. + */ +- (UIColor *)selectedDayImageColor; + +/** + The custom background image for the cell of the day when it is selected. Default value is `nil`. + + @discussion Can be overridden in subclasses for customization. + */ +- (UIImage *)customSelectedDayImage; /** The color of the overlay image for the cell of the day. Default value is [UIColor colorWithRed:184/255.0f green:184/255.0f blue:184/255.0f alpha:1.0f]. diff --git a/RSDayFlow/RSDFDatePickerDayCell.m b/RSDayFlow/RSDFDatePickerDayCell.m index 2ff6611..fbec07f 100644 --- a/RSDayFlow/RSDFDatePickerDayCell.m +++ b/RSDayFlow/RSDFDatePickerDayCell.m @@ -30,7 +30,7 @@ @interface RSDFDatePickerDayCell () + (NSCache *)imageCache; + (id)fetchObjectForKey:(id)key withCreator:(id(^)(void))block; -@property (nonatomic, readonly, strong) UIImageView *todayImageView; +@property (nonatomic, readonly, strong) UIImageView *selectedDayImageView; @property (nonatomic, readonly, strong) UIImageView *overlayImageView; @property (nonatomic, readonly, strong) UIImageView *markImageView; @property (nonatomic, readonly, strong) UIImageView *dividerImageView; @@ -40,7 +40,7 @@ + (id)fetchObjectForKey:(id)key withCreator:(id(^)(void))block; @implementation RSDFDatePickerDayCell @synthesize dateLabel = _dateLabel; -@synthesize todayImageView = _todayImageView; +@synthesize selectedDayImageView = _selectedDayImageView; @synthesize overlayImageView = _overlayImageView; @synthesize markImageView = _markImageView; @synthesize dividerImageView = _dividerImageView; @@ -69,133 +69,54 @@ - (void)commonInitializer { self.backgroundColor = [self selfBackgroundColor]; - self.todayImageView.hidden = YES; - self.overlayImageView.hidden = YES; - self.markImageView.hidden = YES; - self.dividerImageView.hidden = NO; - self.dateLabel.hidden = NO; - - [self addSubview:self.todayImageView]; + [self addSubview:self.selectedDayImageView]; [self addSubview:self.overlayImageView]; [self addSubview:self.markImageView]; [self addSubview:self.dividerImageView]; [self addSubview:self.dateLabel]; + + [self updateSubviews]; } - (void)layoutSubviews { [super layoutSubviews]; - self.dateLabel.frame = [self todayImageViewFrame]; - self.todayImageView.frame = [self todayImageViewFrame]; - self.overlayImageView.frame = [self todayImageViewFrame]; + self.dateLabel.frame = [self selectedImageViewFrame]; + self.selectedDayImageView.frame = [self selectedImageViewFrame]; + self.overlayImageView.frame = [self selectedImageViewFrame]; self.markImageView.frame = [self markImageViewFrame]; self.dividerImageView.frame = [self dividerImageViewFrame]; self.dividerImageView.image = [self dividerImage]; } -#pragma mark - Custom Accessors - -- (void)setDate:(RSDFDatePickerDate)date -{ - _date = date; -} - -- (void)setNotThisMonth:(BOOL)notThisMonth -{ - _notThisMonth = notThisMonth; - if (_notThisMonth) { - self.dateLabel.textColor = [self notThisMonthLabelTextColor]; - self.dateLabel.font = [self dayLabelFont]; - self.todayImageView.hidden = YES; - self.markImageView.hidden = YES; - self.dividerImageView.hidden = YES; - } else { - if (!self.isDayOff) { - self.dateLabel.textColor = [self dayLabelTextColor]; - } else { - self.dateLabel.textColor = [self dayOffLabelTextColor]; - } - if (!self.isToday) { - self.dateLabel.font = [self dayLabelFont]; - } else { - self.dateLabel.font = [self todayLabelFont]; - } - self.todayImageView.hidden = !self.today; - self.markImageView.hidden = !self.marked; - self.dividerImageView.hidden = NO; - } -} - -- (void)setDayOff:(BOOL)dayOff -{ - _dayOff = dayOff; - if (!_dayOff) { - self.dateLabel.textColor = [self dayLabelTextColor]; - } else { - self.dateLabel.textColor = [self dayOffLabelTextColor]; - } -} - -- (void)setMarked:(BOOL)marked -{ - _marked = marked; - self.markImageView.hidden = !_marked; -} - -- (void)setCompleted:(BOOL)completed -{ - _completed = completed; - if (!_completed) { - self.markImageView.image = [self incompleteMarkImage]; - } else { - self.markImageView.image = [self completeMarkImage]; - } -} - -- (void)setToday:(BOOL)today +- (void)drawRect:(CGRect)rect { - _today = today; - if (!_today) { - self.dateLabel.font = [self dayLabelFont]; - if (!self.dayOff) { - self.dateLabel.textColor = [self dayLabelTextColor]; - } else { - self.dateLabel.textColor = [self dayOffLabelTextColor]; - } - } else { - self.dateLabel.font = [self todayLabelFont]; - self.dateLabel.textColor = [self todayLabelTextColor]; - } - self.todayImageView.hidden = !_today; + [self updateSubviews]; } -- (void)setHighlighted:(BOOL)highlighted -{ - [super setHighlighted:highlighted]; - self.overlayImageView.hidden = !self.highlighted; -} +#pragma mark - Custom Accessors -- (CGRect)todayImageViewFrame +- (CGRect)selectedImageViewFrame { return CGRectMake(CGRectGetWidth(self.frame) / 2 - 17.5f, 5.5f, 35.0f, 35.0f); } -- (UIImageView *)todayImageView +- (UIImageView *)selectedDayImageView { - if (!_todayImageView) { - _todayImageView = [[UIImageView alloc] initWithFrame:[self todayImageViewFrame]]; - _todayImageView.backgroundColor = [UIColor clearColor]; - _todayImageView.contentMode = UIViewContentModeCenter; - _todayImageView.image = [self todayImage]; + if (!_selectedDayImageView) { + _selectedDayImageView = [[UIImageView alloc] initWithFrame:[self selectedImageViewFrame]]; + _selectedDayImageView.backgroundColor = [UIColor clearColor]; + _selectedDayImageView.contentMode = UIViewContentModeCenter; + _selectedDayImageView.image = [self selectedDayImage]; } - return _todayImageView; + return _selectedDayImageView; } - (UILabel *)dateLabel { if (!_dateLabel) { - _dateLabel = [[UILabel alloc] initWithFrame:[self todayImageViewFrame]]; + _dateLabel = [[UILabel alloc] initWithFrame:[self selectedImageViewFrame]]; _dateLabel.backgroundColor = [UIColor clearColor]; _dateLabel.textAlignment = NSTextAlignmentCenter; } @@ -205,7 +126,7 @@ - (UILabel *)dateLabel - (UIImageView *)overlayImageView { if (!_overlayImageView) { - _overlayImageView = [[UIImageView alloc] initWithFrame:[self todayImageViewFrame]]; + _overlayImageView = [[UIImageView alloc] initWithFrame:[self selectedImageViewFrame]]; _overlayImageView.backgroundColor = [UIColor clearColor]; _overlayImageView.opaque = NO; _overlayImageView.alpha = 0.5f; @@ -248,6 +169,49 @@ - (UIImageView *)dividerImageView #pragma mark - Private +- (void)updateSubviews +{ + self.selectedDayImageView.hidden = !self.isSelected || self.isNotThisMonth; + self.overlayImageView.hidden = !self.isHighlighted || self.isNotThisMonth; + self.markImageView.hidden = !self.isMarked || self.isNotThisMonth; + self.dividerImageView.hidden = self.isNotThisMonth; + + if (self.isNotThisMonth) { + self.dateLabel.textColor = [self notThisMonthLabelTextColor]; + self.dateLabel.font = [self dayLabelFont]; + } else { + if (!self.isSelected) { + if (!self.isToday) { + self.dateLabel.font = [self dayLabelFont]; + if (!self.dayOff) { + self.dateLabel.textColor = [self dayLabelTextColor]; + } else { + self.dateLabel.textColor = [self dayOffLabelTextColor]; + } + } else { + self.dateLabel.font = [self todayLabelFont]; + self.dateLabel.textColor = [self todayLabelTextColor]; + } + } else { + if (!self.isToday) { + self.dateLabel.font = [self selectedDayLabelFont]; + self.dateLabel.textColor = [self selectedDayLabelTextColor]; + self.selectedDayImageView.image = [self selectedDayImage]; + } else { + self.dateLabel.font = [self selectedTodayLabelFont]; + self.dateLabel.textColor = [self selectedTodayLabelTextColor]; + self.selectedDayImageView.image = [self selectedTodayImage]; + } + } + + if (!self.isCompleted) { + self.markImageView.image = [self incompleteMarkImage]; + } else { + self.markImageView.image = [self completeMarkImage]; + } + } +} + + (NSCache *)imageCache { static NSCache *cache; @@ -336,33 +300,74 @@ - (UIColor *)notThisMonthLabelTextColor - (UIFont *)todayLabelFont { - return [UIFont fontWithName:@"HelveticaNeue-Bold" size:19.0f]; + return [UIFont fontWithName:@"HelveticaNeue" size:18.0f]; } - (UIColor *)todayLabelTextColor { - return [UIColor whiteColor];; + return [UIColor colorWithRed:0/255.0f green:121/255.0f blue:255/255.0f alpha:1.0f]; +} + +- (UIFont *)selectedTodayLabelFont +{ + return [UIFont fontWithName:@"HelveticaNeue-Bold" size:19.0f]; +} + +- (UIColor *)selectedTodayLabelTextColor +{ + return [UIColor whiteColor]; } -- (UIColor *)todayImageColor +- (UIColor *)selectedTodayImageColor { return [UIColor colorWithRed:0/255.0f green:121/255.0f blue:255/255.0f alpha:1.0f]; } -- (UIImage *)customTodayImage +- (UIImage *)customSelectedTodayImage +{ + return nil; +} + +- (UIImage *)selectedTodayImage +{ + UIImage *selectedTodayImage = [self customSelectedTodayImage]; + if (!selectedTodayImage) { + UIColor *selectedTodayImageColor = [self selectedTodayImageColor]; + NSString *selectedTodayImageKey = [NSString stringWithFormat:@"img_selected_today_%@", [selectedTodayImageColor description]]; + selectedTodayImage = [self ellipseImageWithKey:selectedTodayImageKey frame:self.selectedDayImageView.frame color:selectedTodayImageColor]; + } + return selectedTodayImage; +} + +- (UIFont *)selectedDayLabelFont +{ + return [UIFont fontWithName:@"HelveticaNeue-Bold" size:19.0f]; +} + +- (UIColor *)selectedDayLabelTextColor +{ + return [UIColor whiteColor]; +} + +- (UIColor *)selectedDayImageColor +{ + return [UIColor colorWithRed:255/255.0f green:59/255.0f blue:48/255.0f alpha:1.0f]; +} + +- (UIImage *)customSelectedDayImage { return nil; } -- (UIImage *)todayImage +- (UIImage *)selectedDayImage { - UIImage *todayImage = [self customTodayImage]; - if (!todayImage) { - UIColor *todayImageColor = [self todayImageColor]; - NSString *todayImageKey = [NSString stringWithFormat:@"img_today_%@", [todayImageColor description]]; - todayImage = [self ellipseImageWithKey:todayImageKey frame:self.todayImageView.frame color:todayImageColor]; + UIImage *selectedDayImage = [self customSelectedDayImage]; + if (!selectedDayImage) { + UIColor *selectedDayImageColor = [self selectedDayImageColor]; + NSString *selectedDayImageKey = [NSString stringWithFormat:@"img_selected_day_%@", [selectedDayImageColor description]]; + selectedDayImage = [self ellipseImageWithKey:selectedDayImageKey frame:self.selectedDayImageView.frame color:selectedDayImageColor]; } - return todayImage; + return selectedDayImage; } - (UIColor *)overlayImageColor diff --git a/RSDayFlow/RSDFDatePickerView.h b/RSDayFlow/RSDFDatePickerView.h index 31abc95..ad220b7 100644 --- a/RSDayFlow/RSDFDatePickerView.h +++ b/RSDayFlow/RSDFDatePickerView.h @@ -64,9 +64,9 @@ @property (nonatomic, readwrite, weak) id dataSource; -///----------------------------------- -/// @name Scrolling to date -///----------------------------------- +///---------------------------- +/// @name Scrolling to the Date +///---------------------------- /** Scrolls the date picker view to the current day. @@ -84,6 +84,22 @@ - (void)scrollToDate:(NSDate *)date animated:(BOOL)animated; +/// ------------------------ +/// @name Selecting the Date +/// ------------------------ + +/** + Selects the specified date. + + If there is an existing selection of a different date, calling this method replaces the previous selection. + + This method does not cause any selection-related delegate methods to be called. + + @param date The date to select. Specifying nil for this parameter clears the current selection. + */ + +- (void)selectDate:(NSDate *)date; + ///------------------------- /// @name Reloading the Data ///------------------------- @@ -147,9 +163,40 @@ @optional +/** + Asks the delegate if the date should be highlighted during tracking. + + As touch events arrive, the date picker view highlights dates in anticipation of the user selecting them. + As it processes those touch events, the date picker view calls this method to ask your delegate if a given cell should be highlighted. + + If you do not implement this method, the default return value is YES. + + @param view The date picker view object that is asking about the highlight change. + + @return YES if the date should be highlighted or NO if it should not. + */ +- (BOOL)datePickerView:(RSDFDatePickerView *)view shouldHighlightDate:(NSDate *)date; + +/** + Asks the delegate if the specified date should be selected. + + The date picker view calls this method when the user tries to select a date in the date picker view. + It does not call this method when you programmatically set the selection. + + If you do not implement this method, the default return value is YES. + + @param view The date picker view object that is asking whether the date should select. + + @return YES if the date should be selected or NO if it should not. + */ +- (BOOL)datePickerView:(RSDFDatePickerView *)view shouldSelectDate:(NSDate *)date; + /** Tells the delegate that the user did select a date. + The date picker view calls this method when the user successfully selects a date in the date picker view. + It does not call this method when you programmatically set the selection. + @param view The view whose date was selected. @param date The selected date. */ diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index a16f14d..687c475 100755 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -46,6 +46,7 @@ @interface RSDFDatePickerView () Date: Thu, 23 Oct 2014 09:33:46 +0300 Subject: [PATCH 67/87] Version bump (0.7.0) --- Example/RSDayFlowExample/RSDayFlowExample-Info.plist | 4 ++-- RSDayFlow.podspec | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist index de724ca..8ede370 100644 --- a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist +++ b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.6.1 + 0.7.0 CFBundleSignature ???? CFBundleVersion - 0.6.1 + 0.7.0 LSRequiresIPhoneOS UILaunchStoryboardName diff --git a/RSDayFlow.podspec b/RSDayFlow.podspec index 63ef9c8..c67ae16 100644 --- a/RSDayFlow.podspec +++ b/RSDayFlow.podspec @@ -1,11 +1,11 @@ Pod::Spec.new do |s| s.name = 'RSDayFlow' - s.version = '0.6.1' + s.version = '0.7.0' s.summary = 'iOS 7 Calendar with Infinite Scrolling.' s.homepage = 'https://github.com/ruslanskorb/RSDayFlow' s.license = { :type => 'MIT', :file => 'LICENSE' } s.authors = { 'Evadne Wu' => 'ev@radi.ws', 'Ruslan Skorb' => 'ruslan.skorb@gmail.com' } - s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.6.1' } + s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.7.0' } s.platform = :ios, '7.0' s.source_files = 'RSDayFlow' s.frameworks = 'QuartzCore', 'UIKit' From 96438fbaa775432ef218aa5abb6f9d53864b4cd4 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Thu, 23 Oct 2014 10:08:22 +0300 Subject: [PATCH 68/87] [Update] README. --- README.md | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 763e484..11fc0b4 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,8 @@ iOS 7 Calendar with Infinite Scrolling. Only need 4 lines of code to set up. > [RSDayFlow](https://github.com/ruslanskorb/RSDayFlow) is a slim fork of [DayFlow](https://github.com/evadne/DayFlow) with updates and extensions: -> * Possibility to mark the date +> * Visual feedback of the currently selected cell +* Possibility to mark the date * 2 colors of marks that can be used in the Task Manager (gray color - days with uncompleted tasks, green color - days with completed tasks) * Design like iOS 7 * Some other updates @@ -47,19 +48,31 @@ Just create your date picker view and set a delegate / a data source if needed. ## Delegate (optional) -`RSDFDatePickerView` provides one delegate method `didSelectDate`. It gets called when a user click on a specific date. To use it, implement the delegate in your view controller. +`RSDFDatePickerView` provides three delegate methods. The method `datePickerView:shouldHighlightDate:` asks the delegate if the date should be highlighted during tracking. The method `datePickerView:shouldSelectDate:` asks the delegate if the specified date should be selected. The method `datePickerView:didSelectDate:` called when a user click on a specific date. To use them, implement the delegate in your view controller. ```objective-c @interface ViewController () ``` -Then implement the delegate function. +Then implement the delegate functions. ```objective-c +// Returns YES if the date should be highlighted or NO if it should not. +- (BOOL)datePickerView:(RSDFDatePickerView *)view shouldHighlightDate:(NSDate *)date +{ + return YES; +} + +// Returns YES if the date should be selected or NO if it should not. +- (BOOL)datePickerView:(RSDFDatePickerView *)view shouldSelectDate:(NSDate *)date +{ + return YES; +} + // Prints out the selected date. - (void)datePickerView:(RSDFDatePickerView *)view didSelectDate:(NSDate *)date { - NSLog(@"%@", [date description]); + NSLog(@"%@", [date description]); } ``` From 9893a89f1521d2df5d28e898856e0f6955d50ea3 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Thu, 23 Oct 2014 10:11:16 +0300 Subject: [PATCH 69/87] [Fix] README. Remove extra space. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 11fc0b4..52c4bdd 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ iOS 7 Calendar with Infinite Scrolling. Only need 4 lines of code to set up. > [RSDayFlow](https://github.com/ruslanskorb/RSDayFlow) is a slim fork of [DayFlow](https://github.com/evadne/DayFlow) with updates and extensions: -> * Visual feedback of the currently selected cell +> * Visual feedback of the currently selected cell * Possibility to mark the date * 2 colors of marks that can be used in the Task Manager (gray color - days with uncompleted tasks, green color - days with completed tasks) * Design like iOS 7 From 7e229dfe2db136221268a69dbe94e01b8a1d49b5 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Thu, 23 Oct 2014 20:54:38 +0300 Subject: [PATCH 70/87] [Fix] Initial scroll position for landscape orientation. --- RSDayFlow/RSDFDatePickerView.m | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index 687c475..ef38a60 100755 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -109,6 +109,7 @@ - (void)layoutSubviews self.collectionView.frame = [self collectionViewFrame]; if (!self.collectionView.superview) { [self addSubview:self.collectionView]; + [self scrollToToday:NO]; } else { [self.collectionViewLayout invalidateLayout]; [self.collectionViewLayout prepareLayout]; @@ -185,8 +186,6 @@ - (RSDFDatePickerCollectionView *)collectionView [_collectionView registerClass:[self dayCellClass] forCellWithReuseIdentifier:RSDFDatePickerViewDayCellIdentifier]; [_collectionView reloadData]; [_collectionView layoutIfNeeded]; - - [self scrollToToday:YES]; } return _collectionView; } @@ -282,7 +281,7 @@ - (void)scrollToDate:(NSDate *)date animated:(BOOL)animated if (delta <= actualViewHeight) { [self scrollToTopOfSection:monthSection animated:animated]; } else { - [self scrollToBottomOfItemAtIndexPath:dateItemIndexPath animated:animated]; + [cv scrollToItemAtIndexPath:dateItemIndexPath atScrollPosition:UICollectionViewScrollPositionBottom animated:animated]; } } @@ -577,11 +576,6 @@ - (CGRect)frameForItemAtIndexPath:(NSIndexPath *)indexPath return attributes.frame; } -- (void)scrollToBottomOfItemAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated -{ - [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionBottom animated:animated]; -} - - (void)restoreSelection { if (self.selectedDate) { From 95eb9144bf928af7ae6405f7560c98e4fc6f0fb4 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Thu, 23 Oct 2014 20:56:36 +0300 Subject: [PATCH 71/87] Version bump (0.7.1) --- Example/RSDayFlowExample/RSDayFlowExample-Info.plist | 4 ++-- RSDayFlow.podspec | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist index 8ede370..b7ed40d 100644 --- a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist +++ b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.7.0 + 0.7.1 CFBundleSignature ???? CFBundleVersion - 0.7.0 + 0.7.1 LSRequiresIPhoneOS UILaunchStoryboardName diff --git a/RSDayFlow.podspec b/RSDayFlow.podspec index c67ae16..37221b0 100644 --- a/RSDayFlow.podspec +++ b/RSDayFlow.podspec @@ -1,11 +1,11 @@ Pod::Spec.new do |s| s.name = 'RSDayFlow' - s.version = '0.7.0' + s.version = '0.7.1' s.summary = 'iOS 7 Calendar with Infinite Scrolling.' s.homepage = 'https://github.com/ruslanskorb/RSDayFlow' s.license = { :type => 'MIT', :file => 'LICENSE' } s.authors = { 'Evadne Wu' => 'ev@radi.ws', 'Ruslan Skorb' => 'ruslan.skorb@gmail.com' } - s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.7.0' } + s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.7.1' } s.platform = :ios, '7.0' s.source_files = 'RSDayFlow' s.frameworks = 'QuartzCore', 'UIKit' From 7dccb8ea396ec47585d6a6cfcd004ccd5a614cd4 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Sat, 8 Nov 2014 21:41:02 +0300 Subject: [PATCH 72/87] [Fix] Crash app when the selected date is out of the range of loaded dates. --- RSDayFlow/RSDFDatePickerView.m | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index ef38a60..459a6e3 100755 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -288,7 +288,9 @@ - (void)scrollToDate:(NSDate *)date animated:(BOOL)animated - (void)selectDate:(NSDate *)date { if (![self.selectedDate isEqual:date]) { - if (self.selectedDate) { + if (self.selectedDate && + [self.selectedDate compare:[self dateFromPickerDate:self.fromDate]] != NSOrderedAscending && + [self.selectedDate compare:[self dateFromPickerDate:self.toDate]] != NSOrderedDescending) { NSIndexPath *previousSelectedCellIndexPath = [self indexPathForDate:self.selectedDate]; [self.collectionView deselectItemAtIndexPath:previousSelectedCellIndexPath animated:NO]; UICollectionViewCell *previousSelectedCell = [self.collectionView cellForItemAtIndexPath:previousSelectedCellIndexPath]; @@ -299,7 +301,9 @@ - (void)selectDate:(NSDate *)date _selectedDate = date; - if (self.selectedDate) { + if (self.selectedDate && + [self.selectedDate compare:[self dateFromPickerDate:self.fromDate]] != NSOrderedAscending && + [self.selectedDate compare:[self dateFromPickerDate:self.toDate]] != NSOrderedDescending) { NSIndexPath *indexPathForSelectedDate = [self indexPathForDate:self.selectedDate]; [self.collectionView selectItemAtIndexPath:indexPathForSelectedDate animated:NO scrollPosition:UICollectionViewScrollPositionNone]; UICollectionViewCell *selectedCell = [self.collectionView cellForItemAtIndexPath:indexPathForSelectedDate]; @@ -578,7 +582,9 @@ - (CGRect)frameForItemAtIndexPath:(NSIndexPath *)indexPath - (void)restoreSelection { - if (self.selectedDate) { + if (self.selectedDate && + [self.selectedDate compare:[self dateFromPickerDate:self.fromDate]] != NSOrderedAscending && + [self.selectedDate compare:[self dateFromPickerDate:self.toDate]] != NSOrderedDescending) { NSIndexPath *indexPathForSelectedDate = [self indexPathForDate:self.selectedDate]; [self.collectionView selectItemAtIndexPath:indexPathForSelectedDate animated:NO scrollPosition:UICollectionViewScrollPositionNone]; UICollectionViewCell *selectedCell = [self.collectionView cellForItemAtIndexPath:indexPathForSelectedDate]; From 3c0016e411c173992e21950594dda629903cea22 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Sat, 8 Nov 2014 22:28:48 +0300 Subject: [PATCH 73/87] Version bump (0.7.2) --- Example/RSDayFlowExample/RSDayFlowExample-Info.plist | 4 ++-- RSDayFlow.podspec | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist index b7ed40d..c5f1a76 100644 --- a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist +++ b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.7.1 + 0.7.2 CFBundleSignature ???? CFBundleVersion - 0.7.1 + 0.7.2 LSRequiresIPhoneOS UILaunchStoryboardName diff --git a/RSDayFlow.podspec b/RSDayFlow.podspec index 37221b0..5fe64d4 100644 --- a/RSDayFlow.podspec +++ b/RSDayFlow.podspec @@ -1,11 +1,11 @@ Pod::Spec.new do |s| s.name = 'RSDayFlow' - s.version = '0.7.1' + s.version = '0.7.2' s.summary = 'iOS 7 Calendar with Infinite Scrolling.' s.homepage = 'https://github.com/ruslanskorb/RSDayFlow' s.license = { :type => 'MIT', :file => 'LICENSE' } s.authors = { 'Evadne Wu' => 'ev@radi.ws', 'Ruslan Skorb' => 'ruslan.skorb@gmail.com' } - s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => '0.7.1' } + s.source = { :git => 'https://github.com/ruslanskorb/RSDayFlow.git', :tag => s.version.to_s } s.platform = :ios, '7.0' s.source_files = 'RSDayFlow' s.frameworks = 'QuartzCore', 'UIKit' From e890b57d324288013d0c084aea33068412dc44e0 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Wed, 12 Nov 2014 21:39:50 +0300 Subject: [PATCH 74/87] [Fix] Wrong index-path for date in NSLocale that has first weekday on Monday. The method "indexPathForDate:". Fixed #44. --- RSDayFlow/RSDFDatePickerView.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index 459a6e3..af25f75 100755 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -551,8 +551,8 @@ - (NSIndexPath *)indexPathForDate:(NSDate *)date { NSInteger monthSection = [self sectionForDate:date]; NSDate *firstDayInMonth = [self dateForFirstDayInSection:monthSection]; - NSUInteger weekday = [self.calendar components:NSCalendarUnitWeekday fromDate:firstDayInMonth].weekday; - NSInteger dateItem = [self.calendar components:NSCalendarUnitDay fromDate:firstDayInMonth toDate:date options:0].day + (weekday - self.calendar.firstWeekday); + NSUInteger weekday = [self reorderedWeekday:[self.calendar components:NSCalendarUnitWeekday fromDate:firstDayInMonth].weekday]; + NSInteger dateItem = [self.calendar components:NSCalendarUnitDay fromDate:firstDayInMonth toDate:date options:0].day + weekday; NSIndexPath *indexPath = [NSIndexPath indexPathForItem:dateItem inSection:monthSection]; return indexPath; From 5f005ed03cec56f8f3a6ea638adcd1338a166d7f Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Wed, 12 Nov 2014 21:41:10 +0300 Subject: [PATCH 75/87] Version bump (0.7.3) --- Example/RSDayFlowExample/RSDayFlowExample-Info.plist | 4 ++-- RSDayFlow.podspec | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist index c5f1a76..b51aa7c 100644 --- a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist +++ b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.7.2 + 0.7.3 CFBundleSignature ???? CFBundleVersion - 0.7.2 + 0.7.3 LSRequiresIPhoneOS UILaunchStoryboardName diff --git a/RSDayFlow.podspec b/RSDayFlow.podspec index 5fe64d4..d3e883b 100644 --- a/RSDayFlow.podspec +++ b/RSDayFlow.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'RSDayFlow' - s.version = '0.7.2' + s.version = '0.7.3' s.summary = 'iOS 7 Calendar with Infinite Scrolling.' s.homepage = 'https://github.com/ruslanskorb/RSDayFlow' s.license = { :type => 'MIT', :file => 'LICENSE' } From 0a3734a1b856db28f5b440882e240b281c31de6a Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 24 Feb 2015 23:50:41 +0300 Subject: [PATCH 76/87] [Add] Support for RTL languages. Resolve #57. --- .../RSDFDatePickerCollectionViewLayout.h | 15 +++++++++ .../RSDFDatePickerCollectionViewLayout.m | 33 +++++++++++++++++++ RSDayFlow/RSDFDatePickerDaysOfWeekView.m | 23 +++++++++---- RSDayFlow/RSDFDatePickerView.m | 9 ++++- 4 files changed, 73 insertions(+), 7 deletions(-) diff --git a/RSDayFlow/RSDFDatePickerCollectionViewLayout.h b/RSDayFlow/RSDFDatePickerCollectionViewLayout.h index 7a9690b..c52bdac 100644 --- a/RSDayFlow/RSDFDatePickerCollectionViewLayout.h +++ b/RSDayFlow/RSDFDatePickerCollectionViewLayout.h @@ -25,11 +25,26 @@ #import +/** + Types of supported directions of the layout of the collection view. + */ +typedef NS_ENUM(NSUInteger, RSDFDatePickerCollectionViewLayoutDirection) { + RSDFDatePickerCollectionViewLayoutDirectionLeftToRight, + RSDFDatePickerCollectionViewLayoutDirectionRightToLeft +}; + /** The `RSDFDatePickerCollectionViewLayout` is a layout of the collection view which used the date picker. */ @interface RSDFDatePickerCollectionViewLayout : UICollectionViewFlowLayout +/** + Designated initializer. Initializes and returns a newly allocated layout object with the specified direction. + + @param frame The direction of the layout. + */ +- (instancetype)initWithDirection:(RSDFDatePickerCollectionViewLayoutDirection)direction; + ///----------------------------------------- /// @name Accessing Attributes of the Layout ///----------------------------------------- diff --git a/RSDayFlow/RSDFDatePickerCollectionViewLayout.m b/RSDayFlow/RSDFDatePickerCollectionViewLayout.m index 080a60b..cf03baf 100644 --- a/RSDayFlow/RSDFDatePickerCollectionViewLayout.m +++ b/RSDayFlow/RSDFDatePickerCollectionViewLayout.m @@ -25,6 +25,12 @@ #import "RSDFDatePickerCollectionViewLayout.h" +@interface RSDFDatePickerCollectionViewLayout () + +@property (assign, nonatomic) RSDFDatePickerCollectionViewLayoutDirection direction; + +@end + @implementation RSDFDatePickerCollectionViewLayout #pragma mark - Lifecycle @@ -34,6 +40,7 @@ - (instancetype)init self = [super init]; if (self) { [self commonInitializer]; + _direction = RSDFDatePickerCollectionViewLayoutDirectionLeftToRight; } return self; } @@ -43,6 +50,17 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder self = [super initWithCoder:aDecoder]; if (self) { [self commonInitializer]; + _direction = RSDFDatePickerCollectionViewLayoutDirectionLeftToRight; + } + return self; +} + +- (instancetype)initWithDirection:(RSDFDatePickerCollectionViewLayoutDirection)direction +{ + self = [super init]; + if (self) { + [self commonInitializer]; + _direction = direction; } return self; } @@ -55,6 +73,21 @@ - (void)commonInitializer #pragma mark - Atrributes of the Layout +- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect +{ + NSArray *supersAttributes = [super layoutAttributesForElementsInRect:rect]; + + if (self.direction == RSDFDatePickerCollectionViewLayoutDirectionRightToLeft) { + for (UICollectionViewLayoutAttributes *attributes in supersAttributes) { + CGRect frame = attributes.frame; + frame.origin.x = CGRectGetWidth(rect) - CGRectGetWidth(attributes.frame) - CGRectGetMinX(attributes.frame); + attributes.frame = frame; + } + } + + return supersAttributes; +} + - (CGSize)selfHeaderReferenceSize { CGFloat selfHeaderReferenceWidth = CGRectGetWidth(self.collectionView.frame); diff --git a/RSDayFlow/RSDFDatePickerDaysOfWeekView.m b/RSDayFlow/RSDFDatePickerDaysOfWeekView.m index c49fa4c..ab6646a 100644 --- a/RSDayFlow/RSDFDatePickerDaysOfWeekView.m +++ b/RSDayFlow/RSDFDatePickerDaysOfWeekView.m @@ -189,13 +189,24 @@ - (void)layoutWeekdayLabels CGFloat interitemSpacing = [self selfInteritemSpacing]; CGFloat y = 0; - __block CGFloat x = 0; + __block CGFloat x; - [self.weekdayLabels enumerateObjectsUsingBlock:^(UILabel *weekdayLabel, NSUInteger idx, BOOL *stop) { - CGRect weekdayLabelFrame = CGRectMake(x, y, itemSize.width, itemSize.height); - weekdayLabel.frame = weekdayLabelFrame; - x += (itemSize.width + interitemSpacing); - }]; + NSLocaleLanguageDirection characterDirection = [NSLocale characterDirectionForLanguage:self.calendar.locale.localeIdentifier]; + if (characterDirection == NSLocaleLanguageDirectionRightToLeft) { + x = CGRectGetWidth(self.frame) - itemSize.width; + [self.weekdayLabels enumerateObjectsUsingBlock:^(UILabel *weekdayLabel, NSUInteger idx, BOOL *stop) { + CGRect weekdayLabelFrame = CGRectMake(x, y, itemSize.width, itemSize.height); + weekdayLabel.frame = weekdayLabelFrame; + x -= (itemSize.width + interitemSpacing); + }]; + } else { + x = 0; + [self.weekdayLabels enumerateObjectsUsingBlock:^(UILabel *weekdayLabel, NSUInteger idx, BOOL *stop) { + CGRect weekdayLabelFrame = CGRectMake(x, y, itemSize.width, itemSize.height); + weekdayLabel.frame = weekdayLabelFrame; + x += (itemSize.width + interitemSpacing); + }]; + } } - (void)updateWeekdayLabels diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index af25f75..4111768 100755 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -198,7 +198,14 @@ - (Class)collectionViewLayoutClass - (RSDFDatePickerCollectionViewLayout *)collectionViewLayout { if (!_collectionViewLayout) { - _collectionViewLayout = [[[self collectionViewLayoutClass] alloc] init]; + NSLocaleLanguageDirection characterDirection = [NSLocale characterDirectionForLanguage:self.calendar.locale.localeIdentifier]; + RSDFDatePickerCollectionViewLayoutDirection layoutDirection; + if (characterDirection == NSLocaleLanguageDirectionRightToLeft) { + layoutDirection = RSDFDatePickerCollectionViewLayoutDirectionRightToLeft; + } else { + layoutDirection = RSDFDatePickerCollectionViewLayoutDirectionLeftToRight; + } + _collectionViewLayout = [[[self collectionViewLayoutClass] alloc] initWithDirection:layoutDirection]; } return _collectionViewLayout; } From f5c2149bc7a9f58ed81433aa08d65ff35222ba3c Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Wed, 25 Feb 2015 00:42:40 +0300 Subject: [PATCH 77/87] [LICENSE] Update Copyright. --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 5cad24d..c4f5501 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ Copyright (c) 2013 Evadne Wu, http://radi.ws/ -Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From f080e1541d717269b11e0f045320f83a91ba38b0 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Wed, 25 Feb 2015 00:43:05 +0300 Subject: [PATCH 78/87] Version bump (0.8.0) --- Example/RSDayFlowExample/RSDayFlowExample-Info.plist | 4 ++-- RSDayFlow.podspec | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist index b51aa7c..320d3f7 100644 --- a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist +++ b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.7.3 + 0.8.0 CFBundleSignature ???? CFBundleVersion - 0.7.3 + 1 LSRequiresIPhoneOS UILaunchStoryboardName diff --git a/RSDayFlow.podspec b/RSDayFlow.podspec index d3e883b..f66fcea 100644 --- a/RSDayFlow.podspec +++ b/RSDayFlow.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'RSDayFlow' - s.version = '0.7.3' + s.version = '0.8.0' s.summary = 'iOS 7 Calendar with Infinite Scrolling.' s.homepage = 'https://github.com/ruslanskorb/RSDayFlow' s.license = { :type => 'MIT', :file => 'LICENSE' } From a48eba7bddabb19e168483950ae9a175ea92d6c9 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Sun, 31 May 2015 22:57:53 +0300 Subject: [PATCH 79/87] [Update] Make mark images more customizable. Resolves #61. Close #62. --- .../RSDFDatePickerViewController.m | 26 ++- RSDayFlow/RSDFDatePickerDayCell.h | 39 ++--- RSDayFlow/RSDFDatePickerDayCell.m | 152 +++++++++--------- RSDayFlow/RSDFDatePickerView.h | 19 ++- RSDayFlow/RSDFDatePickerView.m | 8 +- 5 files changed, 128 insertions(+), 116 deletions(-) diff --git a/Example/RSDayFlowExample/RSDFDatePickerViewController.m b/Example/RSDayFlowExample/RSDFDatePickerViewController.m index 79f289d..1ae7cf7 100755 --- a/Example/RSDayFlowExample/RSDFDatePickerViewController.m +++ b/Example/RSDayFlowExample/RSDFDatePickerViewController.m @@ -34,6 +34,8 @@ @interface RSDFDatePickerViewController() Date: Sun, 31 May 2015 22:58:41 +0300 Subject: [PATCH 80/87] [README] Update 'DataSource'. --- README.md | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 52c4bdd..b526d38 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ Then implement the delegate functions. ## DataSource (optional) -`RSDFDatePickerView` provides two data source methods. The method `datePickerView:shouldMarkDate:` asks the data source if the date should be marked. The method `datePickerView:isCompletedAllTasksOnDate:` asks the data source if all tasks on the date are completed. To use them, implement the data source in your view controller. +`RSDFDatePickerView` provides three data source methods. The method `datePickerView:shouldMarkDate:` asks the data source if the date should be marked. The method `datePickerView:markImageColorForDate:` asks the data source about the color of the default mark image for the specified date. The method `datePickerView:markImageForDate:` asks the data source about the mark image for the specified date. The method `datePickerView:markImageColorForDate:` will be ignored if the method `datePickerView:markImageForDate:` is implemented. To use these methods, implement the data source in your view controller. ```objective-c @interface ViewController () @@ -101,10 +101,24 @@ Then implement the data source functions. return [date isEqual:today]; } -// Returns YES if all tasks on the date are completed or NO if they are not completed. -- (BOOL)datePickerView:(RSDFDatePickerView *)view isCompletedAllTasksOnDate:(NSDate *)date +// Returns the color of the default mark image for the specified date. +- (UIColor *)datePickerView:(RSDFDatePickerView *)view markImageColorForDate:(NSDate *)date { - return YES; + if (arc4random() % 2 == 0) { + return [UIColor grayColor]; + } else { + return [UIColor greenColor]; + } +} + +// Returns the mark image for the specified date. +- (UIImage *)datePickerView:(RSDFDatePickerView *)view markImageForDate:(NSDate *)date +{ + if (arc4random() % 2 == 0) { + return [UIImage imageNamed:@"img_gray_mark"]; + } else { + return [UIImage imageNamed:@"img_green_mark"]; + } } ``` @@ -115,7 +129,6 @@ Create a subclass of the desired view and override the default values. ## Coming Soon -- Add more customization points. - If you would like to request a new feature, feel free to raise as an issue. ## Demo From 231d4c318ed001ac1b36fe4ef99128280fec77a7 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Mon, 1 Jun 2015 20:32:41 +0300 Subject: [PATCH 81/87] [Date Picker View] Declare the adoption of `UICollectionViewDataSource` and` UICollectionViewDelegateFlowLayout` protocols in the .h file. Resolves #46. --- RSDayFlow/RSDFDatePickerView.h | 2 +- RSDayFlow/RSDFDatePickerView.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/RSDayFlow/RSDFDatePickerView.h b/RSDayFlow/RSDFDatePickerView.h index b11bbf2..1bba2ca 100644 --- a/RSDayFlow/RSDFDatePickerView.h +++ b/RSDayFlow/RSDFDatePickerView.h @@ -31,7 +31,7 @@ /** The `RSDFDatePickerView` is a calendar view with infinity scrolling. */ -@interface RSDFDatePickerView : UIView +@interface RSDFDatePickerView : UIView /** Designated initializer. Initializes and returns a newly allocated view object with the specified frame rectangle and the specified calendar. diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index bdffd25..6b30972 100755 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -36,7 +36,7 @@ static NSString * const RSDFDatePickerViewMonthHeaderIdentifier = @"RSDFDatePickerViewMonthHeaderIdentifier"; static NSString * const RSDFDatePickerViewDayCellIdentifier = @"RSDFDatePickerViewDayCellIdentifier"; -@interface RSDFDatePickerView () +@interface RSDFDatePickerView () @property (nonatomic, readonly, strong) NSCalendar *calendar; @property (nonatomic, readonly, assign) RSDFDatePickerDate fromDate; From 60f7b4d1c46f55373fe3d8724d333a8231a48850 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 2 Jun 2015 21:59:48 +0300 Subject: [PATCH 82/87] [Date Picker View] Add paging mode. Resolves #47. --- RSDayFlow/RSDFDatePickerView.h | 11 +++++++++ RSDayFlow/RSDFDatePickerView.m | 44 ++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/RSDayFlow/RSDFDatePickerView.h b/RSDayFlow/RSDFDatePickerView.h index 1bba2ca..7ef8311 100644 --- a/RSDayFlow/RSDFDatePickerView.h +++ b/RSDayFlow/RSDFDatePickerView.h @@ -64,6 +64,17 @@ @property (nonatomic, readwrite, weak) id dataSource; +///------------------ +/// @name Paging Mode +/// ----------------- + +/** + A Boolean value that determines whether paging is enabled for the date picker view. Default value is `NO`. + + @discussion If `YES`, stop on the top of the month. + */ +@property (nonatomic, getter = isPagingEnabled) BOOL pagingEnabled; + ///---------------------------- /// @name Scrolling to the Date ///---------------------------- diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index 6b30972..bc95a7a 100755 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -794,4 +794,48 @@ - (void)pickerCollectionViewWillLayoutSubviews:(RSDFDatePickerCollectionView *)p } } +#pragma mark - UIScrollView + +- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView +{ + if (self.isPagingEnabled) { + if (scrollView.contentOffset.y < CGRectGetHeight(scrollView.bounds)) { + [self appendPastDates]; + } + + if (scrollView.contentOffset.y + CGRectGetHeight(scrollView.bounds) * 2 > scrollView.contentSize.height) { + [self appendFutureDates]; + } + } +} + +- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset +{ + if (self.isPagingEnabled) { + NSArray *sortedIndexPathsForVisibleItems = [[self.collectionView indexPathsForVisibleItems] sortedArrayUsingComparator:^NSComparisonResult(NSIndexPath *obj1, NSIndexPath * obj2) { + return obj1.section > obj2.section; + }]; + + NSUInteger visibleSection; + NSUInteger nextSection; + if (velocity.y > 0.0) { + visibleSection = [[sortedIndexPathsForVisibleItems firstObject] section]; + nextSection = visibleSection + 1; + } else if (velocity.y < 0.0) { + visibleSection = [[sortedIndexPathsForVisibleItems lastObject] section]; + nextSection = visibleSection - 1; + } else { + visibleSection = [sortedIndexPathsForVisibleItems[sortedIndexPathsForVisibleItems.count / 2] section]; + nextSection = visibleSection; + } + + CGRect headerRect = [self frameForHeaderForSection:nextSection]; + CGPoint topOfHeader = CGPointMake(0, headerRect.origin.y - self.collectionView.contentInset.top); + + *targetContentOffset = topOfHeader; + + scrollView.decelerationRate = UIScrollViewDecelerationRateFast; + } +} + @end From 858ad9e2f58234657dbab71855666aa4e8f6b0f9 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 2 Jun 2015 22:05:39 +0300 Subject: [PATCH 83/87] [Example] Enable paging mode for the custom date picker view. --- Example/RSDayFlowExample/RSDFDatePickerViewController.m | 1 + 1 file changed, 1 insertion(+) diff --git a/Example/RSDayFlowExample/RSDFDatePickerViewController.m b/Example/RSDayFlowExample/RSDFDatePickerViewController.m index 1ae7cf7..8a1d4a4 100755 --- a/Example/RSDayFlowExample/RSDFDatePickerViewController.m +++ b/Example/RSDayFlowExample/RSDFDatePickerViewController.m @@ -174,6 +174,7 @@ - (RSDFCustomDatePickerView *)customDatePickerView _customDatePickerView.delegate = self; _customDatePickerView.dataSource = self; _customDatePickerView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + _customDatePickerView.pagingEnabled = YES; } return _customDatePickerView; } From 2469f31cb80acad1d02a496def0976a61c84943f Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Fri, 5 Jun 2015 21:03:22 +0300 Subject: [PATCH 84/87] [Copyright] Update the duration of copyright and author's website. --- Example/RSDayFlowExample/RSDFAppDelegate.h | 2 +- Example/RSDayFlowExample/RSDFAppDelegate.m | 2 +- Example/RSDayFlowExample/RSDFCustomDatePickerCollectionView.h | 2 +- Example/RSDayFlowExample/RSDFCustomDatePickerCollectionView.m | 2 +- .../RSDFCustomDatePickerCollectionViewLayout.h | 2 +- .../RSDFCustomDatePickerCollectionViewLayout.m | 2 +- Example/RSDayFlowExample/RSDFCustomDatePickerDayCell.h | 2 +- Example/RSDayFlowExample/RSDFCustomDatePickerDayCell.m | 2 +- Example/RSDayFlowExample/RSDFCustomDatePickerDaysOfWeekView.h | 2 +- Example/RSDayFlowExample/RSDFCustomDatePickerDaysOfWeekView.m | 2 +- Example/RSDayFlowExample/RSDFCustomDatePickerMonthHeader.h | 2 +- Example/RSDayFlowExample/RSDFCustomDatePickerMonthHeader.m | 2 +- Example/RSDayFlowExample/RSDFCustomDatePickerView.h | 2 +- Example/RSDayFlowExample/RSDFCustomDatePickerView.m | 2 +- Example/RSDayFlowExample/RSDFDatePickerViewController.h | 2 +- Example/RSDayFlowExample/RSDFDatePickerViewController.m | 2 +- Example/RSDayFlowExample/main.m | 2 +- Example/RSDayFlowExampleTests/RSDayFlowExampleTests.m | 2 +- README.md | 3 +-- RSDayFlow/NSCalendar+RSDFAdditions.h | 2 +- RSDayFlow/NSCalendar+RSDFAdditions.m | 2 +- RSDayFlow/RSDFDatePickerCollectionView.h | 2 +- RSDayFlow/RSDFDatePickerCollectionView.m | 2 +- RSDayFlow/RSDFDatePickerCollectionViewLayout.h | 2 +- RSDayFlow/RSDFDatePickerCollectionViewLayout.m | 2 +- RSDayFlow/RSDFDatePickerDayCell.h | 2 +- RSDayFlow/RSDFDatePickerDayCell.m | 2 +- RSDayFlow/RSDFDatePickerDaysOfWeekView.h | 2 +- RSDayFlow/RSDFDatePickerDaysOfWeekView.m | 2 +- RSDayFlow/RSDFDatePickerMonthHeader.h | 2 +- RSDayFlow/RSDFDatePickerMonthHeader.m | 2 +- RSDayFlow/RSDFDatePickerView.h | 2 +- RSDayFlow/RSDFDatePickerView.m | 2 +- RSDayFlow/RSDayFlow.h | 2 +- 34 files changed, 34 insertions(+), 35 deletions(-) diff --git a/Example/RSDayFlowExample/RSDFAppDelegate.h b/Example/RSDayFlowExample/RSDFAppDelegate.h index 9a63b7e..87486a3 100644 --- a/Example/RSDayFlowExample/RSDFAppDelegate.h +++ b/Example/RSDayFlowExample/RSDFAppDelegate.h @@ -2,7 +2,7 @@ // RSDFAppDelegate.h // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Example/RSDayFlowExample/RSDFAppDelegate.m b/Example/RSDayFlowExample/RSDFAppDelegate.m index 1d12bb7..922000c 100644 --- a/Example/RSDayFlowExample/RSDFAppDelegate.m +++ b/Example/RSDayFlowExample/RSDFAppDelegate.m @@ -2,7 +2,7 @@ // RSDFAppDelegate.m // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionView.h b/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionView.h index 8a49588..d770e67 100644 --- a/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionView.h +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionView.h @@ -2,7 +2,7 @@ // RSDFCustomDatePickerCollectionView.h // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionView.m b/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionView.m index f37832f..468083d 100644 --- a/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionView.m +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionView.m @@ -2,7 +2,7 @@ // RSDFCustomDatePickerCollectionView.m // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionViewLayout.h b/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionViewLayout.h index 2c3d7c9..b523e60 100644 --- a/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionViewLayout.h +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionViewLayout.h @@ -2,7 +2,7 @@ // RSDFCustomDatePickerCollectionViewLayout.h // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionViewLayout.m b/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionViewLayout.m index d1ae635..2dfe121 100644 --- a/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionViewLayout.m +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerCollectionViewLayout.m @@ -2,7 +2,7 @@ // RSDFCustomDatePickerCollectionViewLayout.m // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerDayCell.h b/Example/RSDayFlowExample/RSDFCustomDatePickerDayCell.h index 55b9d69..c2ee024 100644 --- a/Example/RSDayFlowExample/RSDFCustomDatePickerDayCell.h +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerDayCell.h @@ -2,7 +2,7 @@ // RSDFCustomDatePickerDayCell.h // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerDayCell.m b/Example/RSDayFlowExample/RSDFCustomDatePickerDayCell.m index 1eff969..dbc895b 100644 --- a/Example/RSDayFlowExample/RSDFCustomDatePickerDayCell.m +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerDayCell.m @@ -2,7 +2,7 @@ // RSDFCustomDatePickerDayCell.m // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerDaysOfWeekView.h b/Example/RSDayFlowExample/RSDFCustomDatePickerDaysOfWeekView.h index 33a6bef..77e3b9b 100644 --- a/Example/RSDayFlowExample/RSDFCustomDatePickerDaysOfWeekView.h +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerDaysOfWeekView.h @@ -2,7 +2,7 @@ // RSDFCustomDatePickerDaysOfWeekView.h // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerDaysOfWeekView.m b/Example/RSDayFlowExample/RSDFCustomDatePickerDaysOfWeekView.m index 424e3bf..1ea5227 100644 --- a/Example/RSDayFlowExample/RSDFCustomDatePickerDaysOfWeekView.m +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerDaysOfWeekView.m @@ -2,7 +2,7 @@ // RSDFCustomDatePickerDaysOfWeekView.m // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerMonthHeader.h b/Example/RSDayFlowExample/RSDFCustomDatePickerMonthHeader.h index 5e95ad5..4e42d66 100644 --- a/Example/RSDayFlowExample/RSDFCustomDatePickerMonthHeader.h +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerMonthHeader.h @@ -2,7 +2,7 @@ // RSDFCustomDatePickerMonthHeader.h // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerMonthHeader.m b/Example/RSDayFlowExample/RSDFCustomDatePickerMonthHeader.m index 0ea987f..d093798 100644 --- a/Example/RSDayFlowExample/RSDFCustomDatePickerMonthHeader.m +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerMonthHeader.m @@ -2,7 +2,7 @@ // RSDFCustomDatePickerMonthHeader.m // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerView.h b/Example/RSDayFlowExample/RSDFCustomDatePickerView.h index 0216e10..51217ca 100644 --- a/Example/RSDayFlowExample/RSDFCustomDatePickerView.h +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerView.h @@ -2,7 +2,7 @@ // RSDFCustomDatePickerView.h // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Example/RSDayFlowExample/RSDFCustomDatePickerView.m b/Example/RSDayFlowExample/RSDFCustomDatePickerView.m index 72d8e1d..5e72f42 100644 --- a/Example/RSDayFlowExample/RSDFCustomDatePickerView.m +++ b/Example/RSDayFlowExample/RSDFCustomDatePickerView.m @@ -2,7 +2,7 @@ // RSDFCustomDatePickerView.m // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Example/RSDayFlowExample/RSDFDatePickerViewController.h b/Example/RSDayFlowExample/RSDFDatePickerViewController.h index 6efcbfa..153f301 100755 --- a/Example/RSDayFlowExample/RSDFDatePickerViewController.h +++ b/Example/RSDayFlowExample/RSDFDatePickerViewController.h @@ -2,7 +2,7 @@ // RSDFDatePickerViewController.h // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Example/RSDayFlowExample/RSDFDatePickerViewController.m b/Example/RSDayFlowExample/RSDFDatePickerViewController.m index 8a1d4a4..854fd61 100755 --- a/Example/RSDayFlowExample/RSDFDatePickerViewController.m +++ b/Example/RSDayFlowExample/RSDFDatePickerViewController.m @@ -2,7 +2,7 @@ // RSDFDatePickerViewController.m // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Example/RSDayFlowExample/main.m b/Example/RSDayFlowExample/main.m index ccb9e91..3ba6626 100644 --- a/Example/RSDayFlowExample/main.m +++ b/Example/RSDayFlowExample/main.m @@ -2,7 +2,7 @@ // main.m // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Example/RSDayFlowExampleTests/RSDayFlowExampleTests.m b/Example/RSDayFlowExampleTests/RSDayFlowExampleTests.m index 2d26631..a726477 100644 --- a/Example/RSDayFlowExampleTests/RSDayFlowExampleTests.m +++ b/Example/RSDayFlowExampleTests/RSDayFlowExampleTests.m @@ -2,7 +2,7 @@ // RSDayFlowExampleTests.m // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index b526d38..9f470d8 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,8 @@ iOS 7 Calendar with Infinite Scrolling. Only need 4 lines of code to set up. > * Visual feedback of the currently selected cell * Possibility to mark the date -* 2 colors of marks that can be used in the Task Manager (gray color - days with uncompleted tasks, green color - days with completed tasks) * Design like iOS 7 -* Some other updates +* Much more updates ## Installation diff --git a/RSDayFlow/NSCalendar+RSDFAdditions.h b/RSDayFlow/NSCalendar+RSDFAdditions.h index 7b9e0c4..78c34d8 100644 --- a/RSDayFlow/NSCalendar+RSDFAdditions.h +++ b/RSDayFlow/NSCalendar+RSDFAdditions.h @@ -2,7 +2,7 @@ // NSCalendar+RSDFAdditions.h // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/RSDayFlow/NSCalendar+RSDFAdditions.m b/RSDayFlow/NSCalendar+RSDFAdditions.m index 9d0b55e..347cb6c 100644 --- a/RSDayFlow/NSCalendar+RSDFAdditions.m +++ b/RSDayFlow/NSCalendar+RSDFAdditions.m @@ -2,7 +2,7 @@ // NSCalendar+RSDFAdditions.m // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/RSDayFlow/RSDFDatePickerCollectionView.h b/RSDayFlow/RSDFDatePickerCollectionView.h index 218ed95..4670b58 100644 --- a/RSDayFlow/RSDFDatePickerCollectionView.h +++ b/RSDayFlow/RSDFDatePickerCollectionView.h @@ -2,7 +2,7 @@ // RSDFDatePickerCollectionView.h // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/RSDayFlow/RSDFDatePickerCollectionView.m b/RSDayFlow/RSDFDatePickerCollectionView.m index 7ec5e0c..143028f 100644 --- a/RSDayFlow/RSDFDatePickerCollectionView.m +++ b/RSDayFlow/RSDFDatePickerCollectionView.m @@ -2,7 +2,7 @@ // RSDFDatePickerCollectionView.m // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/RSDayFlow/RSDFDatePickerCollectionViewLayout.h b/RSDayFlow/RSDFDatePickerCollectionViewLayout.h index c52bdac..d9b38f3 100644 --- a/RSDayFlow/RSDFDatePickerCollectionViewLayout.h +++ b/RSDayFlow/RSDFDatePickerCollectionViewLayout.h @@ -2,7 +2,7 @@ // RSDFDatePickerCollectionViewLayout.h // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/RSDayFlow/RSDFDatePickerCollectionViewLayout.m b/RSDayFlow/RSDFDatePickerCollectionViewLayout.m index cf03baf..87a92a5 100644 --- a/RSDayFlow/RSDFDatePickerCollectionViewLayout.m +++ b/RSDayFlow/RSDFDatePickerCollectionViewLayout.m @@ -2,7 +2,7 @@ // RSDFDatePickerCollectionViewLayout.m // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/RSDayFlow/RSDFDatePickerDayCell.h b/RSDayFlow/RSDFDatePickerDayCell.h index abc5094..e58390d 100644 --- a/RSDayFlow/RSDFDatePickerDayCell.h +++ b/RSDayFlow/RSDFDatePickerDayCell.h @@ -2,7 +2,7 @@ // RSDFDatePickerDayCell.h // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/RSDayFlow/RSDFDatePickerDayCell.m b/RSDayFlow/RSDFDatePickerDayCell.m index 80e7a3f..a198887 100644 --- a/RSDayFlow/RSDFDatePickerDayCell.m +++ b/RSDayFlow/RSDFDatePickerDayCell.m @@ -2,7 +2,7 @@ // RSDFDatePickerDayCell.m // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/RSDayFlow/RSDFDatePickerDaysOfWeekView.h b/RSDayFlow/RSDFDatePickerDaysOfWeekView.h index d7d18fd..f618a7f 100644 --- a/RSDayFlow/RSDFDatePickerDaysOfWeekView.h +++ b/RSDayFlow/RSDFDatePickerDaysOfWeekView.h @@ -2,7 +2,7 @@ // RSDFDatePickerDaysOfWeekView.h // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/RSDayFlow/RSDFDatePickerDaysOfWeekView.m b/RSDayFlow/RSDFDatePickerDaysOfWeekView.m index ab6646a..18052ba 100644 --- a/RSDayFlow/RSDFDatePickerDaysOfWeekView.m +++ b/RSDayFlow/RSDFDatePickerDaysOfWeekView.m @@ -2,7 +2,7 @@ // RSDFDatePickerDaysOfWeekView.m // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/RSDayFlow/RSDFDatePickerMonthHeader.h b/RSDayFlow/RSDFDatePickerMonthHeader.h index 9ef3a06..eb5bbdf 100644 --- a/RSDayFlow/RSDFDatePickerMonthHeader.h +++ b/RSDayFlow/RSDFDatePickerMonthHeader.h @@ -2,7 +2,7 @@ // RSDFDatePickerMonthHeader.h // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/RSDayFlow/RSDFDatePickerMonthHeader.m b/RSDayFlow/RSDFDatePickerMonthHeader.m index 6fe9e63..bc2ff6c 100644 --- a/RSDayFlow/RSDFDatePickerMonthHeader.m +++ b/RSDayFlow/RSDFDatePickerMonthHeader.m @@ -2,7 +2,7 @@ // RSDFDatePickerMonthHeader.m // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/RSDayFlow/RSDFDatePickerView.h b/RSDayFlow/RSDFDatePickerView.h index 7ef8311..f802da2 100644 --- a/RSDayFlow/RSDFDatePickerView.h +++ b/RSDayFlow/RSDFDatePickerView.h @@ -2,7 +2,7 @@ // RSDFDatePickerView.h // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index bc95a7a..e311dbc 100755 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -2,7 +2,7 @@ // RSDFDatePickerView.m // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/RSDayFlow/RSDayFlow.h b/RSDayFlow/RSDayFlow.h index 249ccc9..b36bd27 100644 --- a/RSDayFlow/RSDayFlow.h +++ b/RSDayFlow/RSDayFlow.h @@ -2,7 +2,7 @@ // RSDayFlow.h // // Copyright (c) 2013 Evadne Wu, http://radi.ws/ -// Copyright (c) 2013-2014 Ruslan Skorb, http://lnkd.in/gsBbvb +// Copyright (c) 2013-2015 Ruslan Skorb, http://ruslanskorb.com // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal From 757f250062df6c42cd5bb4e34446ce52aaf3c1da Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Fri, 5 Jun 2015 21:35:26 +0300 Subject: [PATCH 85/87] [Date Picker View] Scroll to the date, even if there are no visible cells. Resolves #66. --- RSDayFlow/RSDFDatePickerView.m | 4 ---- 1 file changed, 4 deletions(-) diff --git a/RSDayFlow/RSDFDatePickerView.m b/RSDayFlow/RSDFDatePickerView.m index e311dbc..8644b10 100755 --- a/RSDayFlow/RSDFDatePickerView.m +++ b/RSDayFlow/RSDFDatePickerView.m @@ -251,10 +251,6 @@ - (void)scrollToDate:(NSDate *)date animated:(BOOL)animated RSDFDatePickerCollectionView *cv = self.collectionView; RSDFDatePickerCollectionViewLayout *cvLayout = (RSDFDatePickerCollectionViewLayout *)self.collectionView.collectionViewLayout; - NSArray *visibleCells = [cv visibleCells]; - if (![visibleCells count]) - return; - NSDateComponents *dateYearMonthComponents = [self.calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth) fromDate:date]; NSDate *month = [self.calendar dateFromComponents:dateYearMonthComponents]; From 9d602eb2a20412ddd49f769e04aacfc8d283e19f Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Sat, 6 Jun 2015 22:01:22 +0300 Subject: [PATCH 86/87] Version bump (0.9.0) --- Example/RSDayFlowExample/RSDayFlowExample-Info.plist | 2 +- RSDayFlow.podspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist index 320d3f7..069d53b 100644 --- a/Example/RSDayFlowExample/RSDayFlowExample-Info.plist +++ b/Example/RSDayFlowExample/RSDayFlowExample-Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.8.0 + 0.9.0 CFBundleSignature ???? CFBundleVersion diff --git a/RSDayFlow.podspec b/RSDayFlow.podspec index f66fcea..6b3fb7c 100644 --- a/RSDayFlow.podspec +++ b/RSDayFlow.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'RSDayFlow' - s.version = '0.8.0' + s.version = '0.9.0' s.summary = 'iOS 7 Calendar with Infinite Scrolling.' s.homepage = 'https://github.com/ruslanskorb/RSDayFlow' s.license = { :type => 'MIT', :file => 'LICENSE' } From 3a7e2a0eaa5d47565dfcf40037dcd08d97c0f294 Mon Sep 17 00:00:00 2001 From: Abdullah Date: Tue, 23 Jun 2015 18:43:28 +0300 Subject: [PATCH 87/87] Use NSCalendarIdentifierIslamicUmmAlQura NSCalendarIdentifierIslamic is not predictable, so I suggest to use NSCalendarIdentifierIslamicUmmAlQura instead. For more about it check this issue: https://github.com/evadne/DayFlow/issues/11 --- Example/RSDayFlowExample/RSDFAppDelegate.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Example/RSDayFlowExample/RSDFAppDelegate.m b/Example/RSDayFlowExample/RSDFAppDelegate.m index 922000c..c187e58 100644 --- a/Example/RSDayFlowExample/RSDFAppDelegate.m +++ b/Example/RSDayFlowExample/RSDFAppDelegate.m @@ -52,11 +52,11 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( UINavigationController *hebrewNC = [[UINavigationController alloc] initWithRootViewController:hebrewVC]; // ---------------- - // Islamic calendar + // Islamic UmmAlQura calendar // ---------------- RSDFDatePickerViewController *islamicVC = [[RSDFDatePickerViewController alloc] init]; - islamicVC.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierIslamic]; + islamicVC.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierIslamicUmmAlQura]; islamicVC.calendar.locale = [NSLocale currentLocale]; UINavigationController *islamicNC = [[UINavigationController alloc] initWithRootViewController:islamicVC];