From 4a4279af9ced2fd9386698da1ddfd284391c682d Mon Sep 17 00:00:00 2001 From: Ryan Holmes Date: Fri, 23 Aug 2013 19:15:21 -0700 Subject: [PATCH 01/92] Use real UITableView section headers for months --- TimesSquare/TSQCalendarView.m | 77 +++++++++++++++++------------------ 1 file changed, 37 insertions(+), 40 deletions(-) diff --git a/TimesSquare/TSQCalendarView.m b/TimesSquare/TSQCalendarView.m index 4b73585..ef7add4 100644 --- a/TimesSquare/TSQCalendarView.m +++ b/TimesSquare/TSQCalendarView.m @@ -85,15 +85,6 @@ - (Class)rowCellClass; return _rowCellClass; } -- (Class)cellClassForRowAtIndexPath:(NSIndexPath *)indexPath; -{ - if (indexPath.row == 0 && !self.pinsHeaderToTop) { - return [self headerCellClass]; - } else { - return [self rowCellClass]; - } -} - - (void)setBackgroundColor:(UIColor *)backgroundColor; { [super setBackgroundColor:backgroundColor]; @@ -201,7 +192,7 @@ - (NSIndexPath *)indexPathForRowAtDate:(NSDate *)date; NSInteger firstWeek = [self.calendar components:NSWeekOfMonthCalendarUnit fromDate:firstOfMonth].weekOfMonth; NSInteger targetWeek = [self.calendar components:NSWeekOfMonthCalendarUnit fromDate:date].weekOfMonth; - return [NSIndexPath indexPathForRow:(self.pinsHeaderToTop ? 0 : 1) + targetWeek - firstWeek inSection:section]; + return [NSIndexPath indexPathForRow:targetWeek - firstWeek inSection:section]; } #pragma mark UIView @@ -244,29 +235,19 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger { NSDate *firstOfMonth = [self firstOfMonthForSection:section]; NSRange rangeOfWeeks = [self.calendar rangeOfUnit:NSWeekCalendarUnit inUnit:NSMonthCalendarUnit forDate:firstOfMonth]; - return (self.pinsHeaderToTop ? 0 : 1) + rangeOfWeeks.length; + return rangeOfWeeks.length; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; { - if (indexPath.row == 0 && !self.pinsHeaderToTop) { - // month header - static NSString *identifier = @"header"; - TSQCalendarMonthHeaderCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier]; - if (!cell) { - cell = [self makeHeaderCellWithIdentifier:identifier]; - } - return cell; - } else { - static NSString *identifier = @"row"; - TSQCalendarRowCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier]; - if (!cell) { - cell = [[[self rowCellClass] alloc] initWithCalendar:self.calendar reuseIdentifier:identifier]; - cell.backgroundColor = self.backgroundColor; - cell.calendarView = self; - } - return cell; + static NSString *identifier = @"row"; + TSQCalendarRowCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier]; + if (!cell) { + cell = [[[self rowCellClass] alloc] initWithCalendar:self.calendar reuseIdentifier:identifier]; + cell.backgroundColor = self.backgroundColor; + cell.calendarView = self; } + return cell; } #pragma mark UITableViewDelegate @@ -275,24 +256,40 @@ - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)ce { NSDate *firstOfMonth = [self firstOfMonthForSection:indexPath.section]; [(TSQCalendarCell *)cell setFirstOfMonth:firstOfMonth]; - if (indexPath.row > 0 || self.pinsHeaderToTop) { - NSInteger ordinalityOfFirstDay = [self.calendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSWeekCalendarUnit forDate:firstOfMonth]; - NSDateComponents *dateComponents = [NSDateComponents new]; - dateComponents.day = 1 - ordinalityOfFirstDay; - dateComponents.week = indexPath.row - (self.pinsHeaderToTop ? 0 : 1); - [(TSQCalendarRowCell *)cell setBeginningDate:[self.calendar dateByAddingComponents:dateComponents toDate:firstOfMonth options:0]]; - [(TSQCalendarRowCell *)cell selectColumnForDate:self.selectedDate]; - - BOOL isBottomRow = (indexPath.row == [self tableView:tableView numberOfRowsInSection:indexPath.section] - (self.pinsHeaderToTop ? 0 : 1)); - [(TSQCalendarRowCell *)cell setBottomRow:isBottomRow]; - } + NSInteger ordinalityOfFirstDay = [self.calendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSWeekCalendarUnit forDate:firstOfMonth]; + NSDateComponents *dateComponents = [NSDateComponents new]; + dateComponents.day = 1 - ordinalityOfFirstDay; + dateComponents.week = indexPath.row; + [(TSQCalendarRowCell *)cell setBeginningDate:[self.calendar dateByAddingComponents:dateComponents toDate:firstOfMonth options:0]]; + [(TSQCalendarRowCell *)cell selectColumnForDate:self.selectedDate]; + + BOOL isBottomRow = indexPath.row == [self tableView:tableView numberOfRowsInSection:indexPath.section]; + [(TSQCalendarRowCell *)cell setBottomRow:isBottomRow]; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath; { - return [[self cellClassForRowAtIndexPath:indexPath] cellHeight]; + return [[self rowCellClass] cellHeight]; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section +{ + return 65.0f; +} + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section +{ + // month header + static NSString *identifier = @"header"; + TSQCalendarMonthHeaderCell *cell = [tableView dequeueReusableHeaderFooterViewWithIdentifier:identifier]; + if (!cell) { + cell = [self makeHeaderCellWithIdentifier:identifier]; + cell.firstOfMonth = [self firstOfMonthForSection:section]; + } + return cell; } + #pragma mark UIScrollViewDelegate - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset; From a328eafc6157dbd2aab60996097db84cd1ddce99 Mon Sep 17 00:00:00 2001 From: Ryan Holmes Date: Sat, 24 Aug 2013 20:44:35 -0700 Subject: [PATCH 02/92] Fix bottom row calculation --- TimesSquare/TSQCalendarView.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TimesSquare/TSQCalendarView.m b/TimesSquare/TSQCalendarView.m index ef7add4..d1c5dff 100644 --- a/TimesSquare/TSQCalendarView.m +++ b/TimesSquare/TSQCalendarView.m @@ -263,7 +263,7 @@ - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)ce [(TSQCalendarRowCell *)cell setBeginningDate:[self.calendar dateByAddingComponents:dateComponents toDate:firstOfMonth options:0]]; [(TSQCalendarRowCell *)cell selectColumnForDate:self.selectedDate]; - BOOL isBottomRow = indexPath.row == [self tableView:tableView numberOfRowsInSection:indexPath.section]; + BOOL isBottomRow = indexPath.row == [self tableView:tableView numberOfRowsInSection:indexPath.section] - 1; [(TSQCalendarRowCell *)cell setBottomRow:isBottomRow]; } From 4444599bbd5a221e7910562c5ca35e0ac5658158 Mon Sep 17 00:00:00 2001 From: Ryan Holmes Date: Sat, 24 Aug 2013 20:45:46 -0700 Subject: [PATCH 03/92] Remove extra semicolon from init methods --- TimesSquare/TSQCalendarMonthHeaderCell.m | 2 +- TimesSquare/TSQCalendarRowCell.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/TimesSquare/TSQCalendarMonthHeaderCell.m b/TimesSquare/TSQCalendarMonthHeaderCell.m index 776f692..8531cd1 100644 --- a/TimesSquare/TSQCalendarMonthHeaderCell.m +++ b/TimesSquare/TSQCalendarMonthHeaderCell.m @@ -22,7 +22,7 @@ @interface TSQCalendarMonthHeaderCell () @implementation TSQCalendarMonthHeaderCell -- (id)initWithCalendar:(NSCalendar *)calendar reuseIdentifier:(NSString *)reuseIdentifier; +- (id)initWithCalendar:(NSCalendar *)calendar reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithCalendar:calendar reuseIdentifier:reuseIdentifier]; if (!self) { diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 950b989..0b12d28 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -32,7 +32,7 @@ @interface TSQCalendarRowCell () @implementation TSQCalendarRowCell -- (id)initWithCalendar:(NSCalendar *)calendar reuseIdentifier:(NSString *)reuseIdentifier; +- (id)initWithCalendar:(NSCalendar *)calendar reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithCalendar:calendar reuseIdentifier:reuseIdentifier]; if (!self) { From d97ac9f690d295ca9dee694226c4376c0a631678 Mon Sep 17 00:00:00 2001 From: Ryan Holmes Date: Sat, 24 Aug 2013 20:48:51 -0700 Subject: [PATCH 04/92] Make "not this month" button labels transparent to support non-opaque backgrounds --- TimesSquare/TSQCalendarRowCell.m | 1 - 1 file changed, 1 deletion(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 0b12d28..ed3658b 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -77,7 +77,6 @@ - (void)createNotThisMonthButtons; button.enabled = NO; UIColor *backgroundPattern = [UIColor colorWithPatternImage:[self notThisMonthBackgroundImage]]; button.backgroundColor = backgroundPattern; - button.titleLabel.backgroundColor = backgroundPattern; } self.notThisMonthButtons = notThisMonthButtons; } From 043d0df713815457df624656d429a799d0403259 Mon Sep 17 00:00:00 2001 From: Ryan Holmes Date: Sat, 24 Aug 2013 20:49:57 -0700 Subject: [PATCH 05/92] Bump version to 2.0.0 --- TimesSquare.podspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TimesSquare.podspec b/TimesSquare.podspec index 5a7d94f..fcbbbb3 100644 --- a/TimesSquare.podspec +++ b/TimesSquare.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "TimesSquare" - s.version = "1.0.1" + s.version = "2.0.0" s.summary = "TimesSquare is an Objective-C calendar view for your apps." s.homepage = "https://github.com/square/objc-TimesSquare" s.license = 'Apache License, Version 2.0' @@ -9,4 +9,4 @@ Pod::Spec.new do |s| s.platform = :ios, '5.0' s.source_files = 'TimesSquare/*.{h,m}' s.requires_arc = true -end \ No newline at end of file +end From 05fa303d1b286e2e7f6f07ff6ce73a375d890547 Mon Sep 17 00:00:00 2001 From: Ryan Holmes Date: Sat, 24 Aug 2013 21:05:11 -0700 Subject: [PATCH 06/92] Replace deprecated UITextAlignmentCenter with NSTextAlignmentCenter --- TimesSquare/TSQCalendarMonthHeaderCell.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TimesSquare/TSQCalendarMonthHeaderCell.m b/TimesSquare/TSQCalendarMonthHeaderCell.m index 8531cd1..46824ca 100644 --- a/TimesSquare/TSQCalendarMonthHeaderCell.m +++ b/TimesSquare/TSQCalendarMonthHeaderCell.m @@ -70,7 +70,7 @@ - (void)createHeaderLabels; for (NSUInteger index = 0; index < self.daysInWeek; index++) { NSInteger ordinality = [self.calendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSWeekCalendarUnit forDate:referenceDate]; UILabel *label = [[UILabel alloc] initWithFrame:self.frame]; - label.textAlignment = UITextAlignmentCenter; + label.textAlignment = NSTextAlignmentCenter; label.text = [dayFormatter stringFromDate:referenceDate]; label.font = [UIFont boldSystemFontOfSize:12.f]; label.backgroundColor = self.backgroundColor; @@ -85,7 +85,7 @@ - (void)createHeaderLabels; } self.headerLabels = headerLabels; - self.textLabel.textAlignment = UITextAlignmentCenter; + self.textLabel.textAlignment = NSTextAlignmentCenter; self.textLabel.textColor = self.textColor; self.textLabel.shadowColor = [UIColor whiteColor]; self.textLabel.shadowOffset = self.shadowOffset; From 0f38df25b6065eeec050d2b67971b3346e02511d Mon Sep 17 00:00:00 2001 From: Ryan Holmes Date: Sat, 24 Aug 2013 21:05:37 -0700 Subject: [PATCH 07/92] Fix support for pinsHeaderToTop --- TimesSquare/TSQCalendarView.m | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/TimesSquare/TSQCalendarView.m b/TimesSquare/TSQCalendarView.m index d1c5dff..96a4041 100644 --- a/TimesSquare/TSQCalendarView.m +++ b/TimesSquare/TSQCalendarView.m @@ -274,12 +274,18 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { - return 65.0f; + if (self.pinsHeaderToTop) { + return 0; + } + return [[self headerCellClass] cellHeight]; } - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { - // month header + if (self.pinsHeaderToTop) { + return nil; + } + static NSString *identifier = @"header"; TSQCalendarMonthHeaderCell *cell = [tableView dequeueReusableHeaderFooterViewWithIdentifier:identifier]; if (!cell) { From 213d8bbbc9ed12ae905efe854896214d4b747473 Mon Sep 17 00:00:00 2001 From: Ryan Holmes Date: Sat, 31 Aug 2013 10:35:50 -0700 Subject: [PATCH 08/92] Day buttons should respond to TouchUpInside instead of TouchDown --- TimesSquare/TSQCalendarRowCell.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index ed3658b..ddf1273 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -56,7 +56,7 @@ - (void)createDayButtons; NSMutableArray *dayButtons = [NSMutableArray arrayWithCapacity:self.daysInWeek]; for (NSUInteger index = 0; index < self.daysInWeek; index++) { UIButton *button = [[UIButton alloc] initWithFrame:self.contentView.bounds]; - [button addTarget:self action:@selector(dateButtonPressed:) forControlEvents:UIControlEventTouchDown]; + [button addTarget:self action:@selector(dateButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; [dayButtons addObject:button]; [self.contentView addSubview:button]; [self configureButton:button]; @@ -86,7 +86,7 @@ - (void)createTodayButton; self.todayButton = [[UIButton alloc] initWithFrame:self.contentView.bounds]; [self.contentView addSubview:self.todayButton]; [self configureButton:self.todayButton]; - [self.todayButton addTarget:self action:@selector(todayButtonPressed:) forControlEvents:UIControlEventTouchDown]; + [self.todayButton addTarget:self action:@selector(todayButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; [self.todayButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; [self.todayButton setBackgroundImage:[self todayBackgroundImage] forState:UIControlStateNormal]; From 1100fed763dd38f7d7d93ed146da92505ed9676d Mon Sep 17 00:00:00 2001 From: Ryan Holmes Date: Wed, 30 Oct 2013 15:07:46 -0700 Subject: [PATCH 09/92] Exposed "day of month" font and text color for today's date --- TimesSquare/TSQCalendarRowCell.h | 16 ++++++++++++++++ TimesSquare/TSQCalendarRowCell.m | 16 +++++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.h b/TimesSquare/TSQCalendarRowCell.h index 0fad589..8c1a055 100644 --- a/TimesSquare/TSQCalendarRowCell.h +++ b/TimesSquare/TSQCalendarRowCell.h @@ -15,6 +15,22 @@ */ @interface TSQCalendarRowCell : TSQCalendarCell +/** @name Text */ + +/** The font used to display each day of the month. + + This is the 19 point bold system font by default. + */ +@property (nonatomic, weak, readonly) UIFont *dayOfMonthFont; + + +/** The text color for a day that's "today". + +This is white by default. +*/ +@property (nonatomic, weak, readonly) UIColor *todayTextColor; + + /** @name Images */ /** The background image for the entire row. diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index ddf1273..0687298 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -42,9 +42,19 @@ - (id)initWithCalendar:(NSCalendar *)calendar reuseIdentifier:(NSString *)reuseI return self; } +- (UIFont *)dayOfMonthFont +{ + return [UIFont boldSystemFontOfSize:19.0f]; +} + +- (UIColor *)todayTextColor +{ + return [UIColor whiteColor]; +} + - (void)configureButton:(UIButton *)button; { - button.titleLabel.font = [UIFont boldSystemFontOfSize:19.f]; + button.titleLabel.font = [self dayOfMonthFont]; button.titleLabel.shadowOffset = self.shadowOffset; button.adjustsImageWhenDisabled = NO; [button setTitleColor:self.textColor forState:UIControlStateNormal]; @@ -73,7 +83,7 @@ - (void)createNotThisMonthButtons; [notThisMonthButtons addObject:button]; [self.contentView addSubview:button]; [self configureButton:button]; - + [button setTitleColor:[self.textColor colorWithAlphaComponent:0.5f] forState:UIControlStateDisabled]; button.enabled = NO; UIColor *backgroundPattern = [UIColor colorWithPatternImage:[self notThisMonthBackgroundImage]]; button.backgroundColor = backgroundPattern; @@ -88,7 +98,7 @@ - (void)createTodayButton; [self configureButton:self.todayButton]; [self.todayButton addTarget:self action:@selector(todayButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; - [self.todayButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [self.todayButton setTitleColor:[self todayTextColor] forState:UIControlStateNormal]; [self.todayButton setBackgroundImage:[self todayBackgroundImage] forState:UIControlStateNormal]; [self.todayButton setTitleShadowColor:[UIColor colorWithWhite:0.0f alpha:0.75f] forState:UIControlStateNormal]; From c54bca1a3d78da8ade192f05c500fb49d1cc7c98 Mon Sep 17 00:00:00 2001 From: Ryan Holmes Date: Wed, 30 Oct 2013 15:09:43 -0700 Subject: [PATCH 10/92] Bumped version number in pod spec --- TimesSquare.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TimesSquare.podspec b/TimesSquare.podspec index fcbbbb3..79c70a5 100644 --- a/TimesSquare.podspec +++ b/TimesSquare.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "TimesSquare" - s.version = "2.0.0" + s.version = "2.0.1" s.summary = "TimesSquare is an Objective-C calendar view for your apps." s.homepage = "https://github.com/square/objc-TimesSquare" s.license = 'Apache License, Version 2.0' From fa5a629f751510dbdc6da524d2ed08b51ca2ede7 Mon Sep 17 00:00:00 2001 From: Ryan Holmes Date: Sun, 3 Nov 2013 12:29:04 -0800 Subject: [PATCH 11/92] Apply content inset when calculating the size of the background view --- TimesSquare.podspec | 2 +- TimesSquare/TSQCalendarRowCell.m | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/TimesSquare.podspec b/TimesSquare.podspec index 79c70a5..2bc19d2 100644 --- a/TimesSquare.podspec +++ b/TimesSquare.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "TimesSquare" - s.version = "2.0.1" + s.version = "2.0.2" s.summary = "TimesSquare is an Objective-C calendar view for your apps." s.homepage = "https://github.com/square/objc-TimesSquare" s.license = 'Apache License, Version 2.0' diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 0687298..688d12d 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -213,7 +213,13 @@ - (void)layoutSubviews; [super layoutSubviews]; - self.backgroundView.frame = self.bounds; + // Size the background view with horizontal insets + CGRect bounds = self.bounds; + UIEdgeInsets insets = self.calendarView.contentInset; + CGRect insetRect = UIEdgeInsetsInsetRect(bounds, insets); + insetRect.origin.y = bounds.origin.y; + insetRect.size.height = bounds.size.height; + self.backgroundView.frame = insetRect; } - (void)layoutViewsForColumnAtIndex:(NSUInteger)index inRect:(CGRect)rect; From 82afbdaab1b37fa7493b822948ff55b118ef8953 Mon Sep 17 00:00:00 2001 From: Ryan Holmes Date: Thu, 13 Mar 2014 15:08:02 -0700 Subject: [PATCH 12/92] iOS 7.1 changed the behavior for setting the title on disabled buttons. --- TimesSquare/TSQCalendarRowCell.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 688d12d..328c485 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -259,7 +259,9 @@ - (void)selectColumnForDate:(NSDate *)date; if (newIndexOfSelectedButton >= 0) { self.selectedButton.hidden = NO; - [self.selectedButton setTitle:[self.dayButtons[newIndexOfSelectedButton] currentTitle] forState:UIControlStateNormal]; + NSString *newTitle = [self.dayButtons[newIndexOfSelectedButton] currentTitle]; + [self.selectedButton setTitle:newTitle forState:UIControlStateNormal]; + [self.selectedButton setTitle:newTitle forState:UIControlStateDisabled]; [self.selectedButton setAccessibilityLabel:[self.dayButtons[newIndexOfSelectedButton] accessibilityLabel]]; } else { self.selectedButton.hidden = YES; From 250d6c78999d3c3abf4f32f7f755df0c276843d6 Mon Sep 17 00:00:00 2001 From: Ryan Holmes Date: Thu, 10 Apr 2014 16:18:09 -0700 Subject: [PATCH 13/92] Fix not-this-month buttons on iOS 7. --- TimesSquare/TSQCalendarRowCell.m | 1 + 1 file changed, 1 insertion(+) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 328c485..a1bdde6 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -147,6 +147,7 @@ - (void)setBeginningDate:(NSDate *)date; [self.dayButtons[index] setTitle:title forState:UIControlStateNormal]; [self.dayButtons[index] setAccessibilityLabel:accessibilityLabel]; [self.notThisMonthButtons[index] setTitle:title forState:UIControlStateNormal]; + [self.notThisMonthButtons[index] setTitle:title forState:UIControlStateDisabled]; [self.notThisMonthButtons[index] setAccessibilityLabel:accessibilityLabel]; NSDateComponents *thisDateComponents = [self.calendar components:NSDayCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit fromDate:date]; From a4caf744002aba2185661e6b48a73d08f48769ac Mon Sep 17 00:00:00 2001 From: Simone Manganelli Date: Thu, 10 Apr 2014 16:26:55 -0700 Subject: [PATCH 14/92] expose the monthDateFormatter so we can override it in subclasses --- TimesSquare/TSQCalendarMonthHeaderCell.h | 2 ++ TimesSquare/TSQCalendarMonthHeaderCell.m | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/TimesSquare/TSQCalendarMonthHeaderCell.h b/TimesSquare/TSQCalendarMonthHeaderCell.h index d51838b..7a7e3f3 100644 --- a/TimesSquare/TSQCalendarMonthHeaderCell.h +++ b/TimesSquare/TSQCalendarMonthHeaderCell.h @@ -15,6 +15,8 @@ */ @interface TSQCalendarMonthHeaderCell : TSQCalendarCell +@property (nonatomic, strong) NSDateFormatter *monthDateFormatter; + /** @name Day Labels */ /** The day header labels. diff --git a/TimesSquare/TSQCalendarMonthHeaderCell.m b/TimesSquare/TSQCalendarMonthHeaderCell.m index 46824ca..8fac8b4 100644 --- a/TimesSquare/TSQCalendarMonthHeaderCell.m +++ b/TimesSquare/TSQCalendarMonthHeaderCell.m @@ -15,7 +15,7 @@ @interface TSQCalendarMonthHeaderCell () -@property (nonatomic, strong) NSDateFormatter *monthDateFormatter; + @end From fdf7c1c335345521d502cc6f0ed4a68fc94cd9b6 Mon Sep 17 00:00:00 2001 From: Simone Manganelli Date: Mon, 28 Apr 2014 12:31:40 -0700 Subject: [PATCH 15/92] fix calendar day buttons disabled by the delegate (but which are still in the current month) from displaynig random day numbers --- TimesSquare/TSQCalendarRowCell.m | 1 + 1 file changed, 1 insertion(+) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index a1bdde6..c4f05db 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -145,6 +145,7 @@ - (void)setBeginningDate:(NSDate *)date; NSString *title = [self.dayFormatter stringFromDate:date]; NSString *accessibilityLabel = [self.accessibilityFormatter stringFromDate:date]; [self.dayButtons[index] setTitle:title forState:UIControlStateNormal]; + [self.dayButtons[index] setTitle:title forState:UIControlStateDisabled]; [self.dayButtons[index] setAccessibilityLabel:accessibilityLabel]; [self.notThisMonthButtons[index] setTitle:title forState:UIControlStateNormal]; [self.notThisMonthButtons[index] setTitle:title forState:UIControlStateDisabled]; From 00d2fc2f7233f51866bb07a06804ed8565a3dd8e Mon Sep 17 00:00:00 2001 From: Fidel Sosa Date: Thu, 11 Sep 2014 17:05:16 -0700 Subject: [PATCH 16/92] Fix iOS8 scrolling issue for resized calendar view --- TimesSquare/TSQCalendarView.m | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/TimesSquare/TSQCalendarView.m b/TimesSquare/TSQCalendarView.m index 96a4041..1ca2d55 100644 --- a/TimesSquare/TSQCalendarView.m +++ b/TimesSquare/TSQCalendarView.m @@ -52,7 +52,12 @@ - (void)_TSQCalendarView_commonInit; _tableView.delegate = self; _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; _tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth; - [self addSubview:_tableView]; + + // WORKAROUND: In iOS8, scrolling randomly doesn't work in the calendar view when dragging on enabled buttons. + // The correct solution is to enable delaysContentTouches but this has been broken since iOS7: ( https://devforums.apple.com/thread/199755?start=0&tstart=0 ). + // The workaround here is to set delaysTouchesBegan on the panGestureRecognizer of the table itself. + _tableView.panGestureRecognizer.delaysTouchesBegan = YES; + [self addSubview:_tableView]; } - (void)dealloc; From 670f66d24ec9264dfed742c03312b5b626922971 Mon Sep 17 00:00:00 2001 From: Simone Manganelli Date: Wed, 17 Sep 2014 22:04:09 -0700 Subject: [PATCH 17/92] fix warning about iOS 7 deprecation --- TimesSquare/TSQCalendarView.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TimesSquare/TSQCalendarView.m b/TimesSquare/TSQCalendarView.m index 1ca2d55..9f0e103 100644 --- a/TimesSquare/TSQCalendarView.m +++ b/TimesSquare/TSQCalendarView.m @@ -264,7 +264,7 @@ - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)ce NSInteger ordinalityOfFirstDay = [self.calendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSWeekCalendarUnit forDate:firstOfMonth]; NSDateComponents *dateComponents = [NSDateComponents new]; dateComponents.day = 1 - ordinalityOfFirstDay; - dateComponents.week = indexPath.row; + dateComponents.weekOfMonth = indexPath.row; [(TSQCalendarRowCell *)cell setBeginningDate:[self.calendar dateByAddingComponents:dateComponents toDate:firstOfMonth options:0]]; [(TSQCalendarRowCell *)cell selectColumnForDate:self.selectedDate]; From d534c7d8add3bee005d3e2d3373ce89617321280 Mon Sep 17 00:00:00 2001 From: Simone Manganelli Date: Wed, 25 Mar 2015 14:17:53 -0700 Subject: [PATCH 18/92] add framework target/scheme for carthage, use new calendar units instead of ones that are unavailable in iOS 8.0 --- TimesSquare-iOS/Info.plist | 26 +++ TimesSquare-iOS/TimesSquare-iOS.h | 19 ++ TimesSquare.xcodeproj/project.pbxproj | 190 ++++++++++++++++++ .../xcschemes/TimesSquare-iOS.xcscheme | 110 ++++++++++ TimesSquare/TSQCalendarCell.m | 2 +- TimesSquare/TSQCalendarMonthHeaderCell.m | 2 +- TimesSquare/TSQCalendarRowCell.m | 10 +- TimesSquare/TSQCalendarView.m | 18 +- 8 files changed, 361 insertions(+), 16 deletions(-) create mode 100644 TimesSquare-iOS/Info.plist create mode 100644 TimesSquare-iOS/TimesSquare-iOS.h create mode 100644 TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare-iOS.xcscheme diff --git a/TimesSquare-iOS/Info.plist b/TimesSquare-iOS/Info.plist new file mode 100644 index 0000000..f55e246 --- /dev/null +++ b/TimesSquare-iOS/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + com.square.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/TimesSquare-iOS/TimesSquare-iOS.h b/TimesSquare-iOS/TimesSquare-iOS.h new file mode 100644 index 0000000..eca88a8 --- /dev/null +++ b/TimesSquare-iOS/TimesSquare-iOS.h @@ -0,0 +1,19 @@ +// +// TimesSquare-iOS.h +// TimesSquare-iOS +// +// Created by Simone Manganelli on 25/03/15. +// Copyright (c) 2015 Square. All rights reserved. +// + +#import + +//! Project version number for TimesSquare-iOS. +FOUNDATION_EXPORT double TimesSquare_iOSVersionNumber; + +//! Project version string for TimesSquare-iOS. +FOUNDATION_EXPORT const unsigned char TimesSquare_iOSVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/TimesSquare.xcodeproj/project.pbxproj b/TimesSquare.xcodeproj/project.pbxproj index ad6ab3e..dca1fdc 100644 --- a/TimesSquare.xcodeproj/project.pbxproj +++ b/TimesSquare.xcodeproj/project.pbxproj @@ -7,6 +7,18 @@ objects = { /* Begin PBXBuildFile section */ + 5C47339E1AC3575C00269A66 /* TimesSquare-iOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C47339D1AC3575C00269A66 /* TimesSquare-iOS.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5C4733B21AC357A700269A66 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A806809E167012980071C71E /* CoreGraphics.framework */; }; + 5C4733B31AC357AB00269A66 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A806805E16700FD70071C71E /* Foundation.framework */; }; + 5C4733B41AC357B200269A66 /* TimesSquare.h in Headers */ = {isa = PBXBuildFile; fileRef = A806806316700FD70071C71E /* TimesSquare.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5C4733B51AC357B200269A66 /* TSQCalendarCell.h in Headers */ = {isa = PBXBuildFile; fileRef = A8068086167010030071C71E /* TSQCalendarCell.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5C4733B61AC357B200269A66 /* TSQCalendarMonthHeaderCell.h in Headers */ = {isa = PBXBuildFile; fileRef = A8068088167010030071C71E /* TSQCalendarMonthHeaderCell.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5C4733B71AC357B200269A66 /* TSQCalendarRowCell.h in Headers */ = {isa = PBXBuildFile; fileRef = A806808A167010030071C71E /* TSQCalendarRowCell.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5C4733B81AC357B200269A66 /* TSQCalendarView.h in Headers */ = {isa = PBXBuildFile; fileRef = A806808C167010030071C71E /* TSQCalendarView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5C4733B91AC357C000269A66 /* TSQCalendarCell.m in Sources */ = {isa = PBXBuildFile; fileRef = A8068087167010030071C71E /* TSQCalendarCell.m */; }; + 5C4733BA1AC357C000269A66 /* TSQCalendarMonthHeaderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = A8068089167010030071C71E /* TSQCalendarMonthHeaderCell.m */; }; + 5C4733BB1AC357C000269A66 /* TSQCalendarRowCell.m in Sources */ = {isa = PBXBuildFile; fileRef = A806808B167010030071C71E /* TSQCalendarRowCell.m */; }; + 5C4733BC1AC357C000269A66 /* TSQCalendarView.m in Sources */ = {isa = PBXBuildFile; fileRef = A806808D167010030071C71E /* TSQCalendarView.m */; }; A806805F16700FD70071C71E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A806805E16700FD70071C71E /* Foundation.framework */; }; A806808E167010030071C71E /* TSQCalendarCell.m in Sources */ = {isa = PBXBuildFile; fileRef = A8068087167010030071C71E /* TSQCalendarCell.m */; }; A8068090167010030071C71E /* TSQCalendarMonthHeaderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = A8068089167010030071C71E /* TSQCalendarMonthHeaderCell.m */; }; @@ -33,6 +45,9 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 5C4733991AC3575B00269A66 /* TimesSquare.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TimesSquare.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 5C47339C1AC3575C00269A66 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5C47339D1AC3575C00269A66 /* TimesSquare-iOS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "TimesSquare-iOS.h"; sourceTree = ""; }; A806805B16700FD70071C71E /* libTimesSquare.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libTimesSquare.a; sourceTree = BUILT_PRODUCTS_DIR; }; A806805E16700FD70071C71E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; A806806216700FD70071C71E /* TimesSquare-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "TimesSquare-Prefix.pch"; sourceTree = ""; }; @@ -51,6 +66,15 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 5C4733951AC3575B00269A66 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5C4733B31AC357AB00269A66 /* Foundation.framework in Frameworks */, + 5C4733B21AC357A700269A66 /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; A806805816700FD70071C71E /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -63,10 +87,28 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 5C47339A1AC3575C00269A66 /* TimesSquare-iOS */ = { + isa = PBXGroup; + children = ( + 5C47339D1AC3575C00269A66 /* TimesSquare-iOS.h */, + 5C47339B1AC3575C00269A66 /* Supporting Files */, + ); + path = "TimesSquare-iOS"; + sourceTree = ""; + }; + 5C47339B1AC3575C00269A66 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 5C47339C1AC3575C00269A66 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; A806805016700FD70071C71E = { isa = PBXGroup; children = ( A806806016700FD70071C71E /* TimesSquare */, + 5C47339A1AC3575C00269A66 /* TimesSquare-iOS */, A806805D16700FD70071C71E /* Frameworks */, A806805C16700FD70071C71E /* Products */, ); @@ -76,6 +118,7 @@ isa = PBXGroup; children = ( A806805B16700FD70071C71E /* libTimesSquare.a */, + 5C4733991AC3575B00269A66 /* TimesSquare.framework */, ); name = Products; sourceTree = ""; @@ -119,6 +162,19 @@ /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ + 5C4733961AC3575B00269A66 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 5C4733B41AC357B200269A66 /* TimesSquare.h in Headers */, + 5C47339E1AC3575C00269A66 /* TimesSquare-iOS.h in Headers */, + 5C4733B81AC357B200269A66 /* TSQCalendarView.h in Headers */, + 5C4733B51AC357B200269A66 /* TSQCalendarCell.h in Headers */, + 5C4733B61AC357B200269A66 /* TSQCalendarMonthHeaderCell.h in Headers */, + 5C4733B71AC357B200269A66 /* TSQCalendarRowCell.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; EFD8DE6B167AF77100F87FBE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -151,6 +207,24 @@ /* End PBXLegacyTarget section */ /* Begin PBXNativeTarget section */ + 5C4733981AC3575B00269A66 /* TimesSquare-iOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5C4733B01AC3575C00269A66 /* Build configuration list for PBXNativeTarget "TimesSquare-iOS" */; + buildPhases = ( + 5C4733941AC3575B00269A66 /* Sources */, + 5C4733951AC3575B00269A66 /* Frameworks */, + 5C4733961AC3575B00269A66 /* Headers */, + 5C4733971AC3575B00269A66 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "TimesSquare-iOS"; + productName = "TimesSquare-iOS"; + productReference = 5C4733991AC3575B00269A66 /* TimesSquare.framework */; + productType = "com.apple.product-type.framework"; + }; A806805A16700FD70071C71E /* TimesSquare */ = { isa = PBXNativeTarget; buildConfigurationList = A806808016700FD80071C71E /* Build configuration list for PBXNativeTarget "TimesSquare" */; @@ -177,6 +251,11 @@ attributes = { LastUpgradeCheck = 0510; ORGANIZATIONNAME = Square; + TargetAttributes = { + 5C4733981AC3575B00269A66 = { + CreatedOnToolsVersion = 6.2; + }; + }; }; buildConfigurationList = A806805516700FD70071C71E /* Build configuration list for PBXProject "TimesSquare" */; compatibilityVersion = "Xcode 3.2"; @@ -192,11 +271,33 @@ targets = ( A806805A16700FD70071C71E /* TimesSquare */, A81E05F71682A0E000E79A2B /* TimesSquare Documentation */, + 5C4733981AC3575B00269A66 /* TimesSquare-iOS */, ); }; /* End PBXProject section */ +/* Begin PBXResourcesBuildPhase section */ + 5C4733971AC3575B00269A66 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ + 5C4733941AC3575B00269A66 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5C4733B91AC357C000269A66 /* TSQCalendarCell.m in Sources */, + 5C4733BA1AC357C000269A66 /* TSQCalendarMonthHeaderCell.m in Sources */, + 5C4733BB1AC357C000269A66 /* TSQCalendarRowCell.m in Sources */, + 5C4733BC1AC357C000269A66 /* TSQCalendarView.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; A806805716700FD70071C71E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -211,6 +312,87 @@ /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ + 5C4733AC1AC3575C00269A66 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + 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_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + 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; + INFOPLIST_FILE = "TimesSquare-iOS/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = TimesSquare; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 5C4733AD1AC3575C00269A66 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + 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_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + 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; + INFOPLIST_FILE = "TimesSquare-iOS/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = TimesSquare; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; A806807E16700FD80071C71E /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -322,6 +504,14 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 5C4733B01AC3575C00269A66 /* Build configuration list for PBXNativeTarget "TimesSquare-iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5C4733AC1AC3575C00269A66 /* Debug */, + 5C4733AD1AC3575C00269A66 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; A806805516700FD70071C71E /* Build configuration list for PBXProject "TimesSquare" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare-iOS.xcscheme b/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare-iOS.xcscheme new file mode 100644 index 0000000..eabb4f5 --- /dev/null +++ b/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare-iOS.xcscheme @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TimesSquare/TSQCalendarCell.m b/TimesSquare/TSQCalendarCell.m index 99276c9..011e94c 100644 --- a/TimesSquare/TSQCalendarCell.m +++ b/TimesSquare/TSQCalendarCell.m @@ -55,7 +55,7 @@ - (NSUInteger)daysInWeek; { static NSUInteger daysInWeek = 0; if (daysInWeek == 0) { - daysInWeek = [self.calendar maximumRangeOfUnit:NSWeekdayCalendarUnit].length; + daysInWeek = [self.calendar maximumRangeOfUnit:NSCalendarUnitWeekday].length; } return daysInWeek; } diff --git a/TimesSquare/TSQCalendarMonthHeaderCell.m b/TimesSquare/TSQCalendarMonthHeaderCell.m index 8fac8b4..763051d 100644 --- a/TimesSquare/TSQCalendarMonthHeaderCell.m +++ b/TimesSquare/TSQCalendarMonthHeaderCell.m @@ -68,7 +68,7 @@ - (void)createHeaderLabels; } for (NSUInteger index = 0; index < self.daysInWeek; index++) { - NSInteger ordinality = [self.calendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSWeekCalendarUnit forDate:referenceDate]; + NSInteger ordinality = [self.calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitWeekOfMonth forDate:referenceDate]; UILabel *label = [[UILabel alloc] initWithFrame:self.frame]; label.textAlignment = NSTextAlignmentCenter; label.text = [dayFormatter stringFromDate:referenceDate]; diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index c4f05db..d00b0ea 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -151,7 +151,7 @@ - (void)setBeginningDate:(NSDate *)date; [self.notThisMonthButtons[index] setTitle:title forState:UIControlStateDisabled]; [self.notThisMonthButtons[index] setAccessibilityLabel:accessibilityLabel]; - NSDateComponents *thisDateComponents = [self.calendar components:NSDayCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit fromDate:date]; + NSDateComponents *thisDateComponents = [self.calendar components:NSCalendarUnitDay|NSCalendarUnitMonth|NSCalendarUnitYear fromDate:date]; [self.dayButtons[index] setHidden:YES]; [self.notThisMonthButtons[index] setHidden:YES]; @@ -248,9 +248,9 @@ - (void)selectColumnForDate:(NSDate *)date; NSInteger newIndexOfSelectedButton = -1; if (date) { - NSInteger thisDayMonth = [self.calendar components:NSMonthCalendarUnit fromDate:date].month; + NSInteger thisDayMonth = [self.calendar components:NSCalendarUnitMonth fromDate:date].month; if (self.monthOfBeginningDate == thisDayMonth) { - newIndexOfSelectedButton = [self.calendar components:NSDayCalendarUnit fromDate:self.beginningDate toDate:date options:0].day; + newIndexOfSelectedButton = [self.calendar components:NSCalendarUnitDay fromDate:self.beginningDate toDate:date options:0].day; if (newIndexOfSelectedButton >= (NSInteger)self.daysInWeek) { newIndexOfSelectedButton = -1; } @@ -295,7 +295,7 @@ - (NSDateFormatter *)accessibilityFormatter; - (NSInteger)monthOfBeginningDate; { if (!_monthOfBeginningDate) { - _monthOfBeginningDate = [self.calendar components:NSMonthCalendarUnit fromDate:self.firstOfMonth].month; + _monthOfBeginningDate = [self.calendar components:NSCalendarUnitMonth fromDate:self.firstOfMonth].month; } return _monthOfBeginningDate; } @@ -309,7 +309,7 @@ - (void)setFirstOfMonth:(NSDate *)firstOfMonth; - (NSDateComponents *)todayDateComponents; { if (!_todayDateComponents) { - self.todayDateComponents = [self.calendar components:NSDayCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit fromDate:[NSDate date]]; + self.todayDateComponents = [self.calendar components:NSCalendarUnitDay|NSCalendarUnitMonth|NSCalendarUnitYear fromDate:[NSDate date]]; } return _todayDateComponents; } diff --git a/TimesSquare/TSQCalendarView.m b/TimesSquare/TSQCalendarView.m index 9f0e103..b26c7b0 100644 --- a/TimesSquare/TSQCalendarView.m +++ b/TimesSquare/TSQCalendarView.m @@ -105,13 +105,13 @@ - (void)setPinsHeaderToTop:(BOOL)pinsHeaderToTop; - (void)setFirstDate:(NSDate *)firstDate; { // clamp to the beginning of its month - _firstDate = [self clampDate:firstDate toComponents:NSMonthCalendarUnit|NSYearCalendarUnit]; + _firstDate = [self clampDate:firstDate toComponents:NSCalendarUnitMonth|NSCalendarUnitYear]; } - (void)setLastDate:(NSDate *)lastDate; { // clamp to the end of its month - NSDate *firstOfMonth = [self clampDate:lastDate toComponents:NSMonthCalendarUnit|NSYearCalendarUnit]; + NSDate *firstOfMonth = [self clampDate:lastDate toComponents:NSCalendarUnitMonth|NSCalendarUnitYear]; NSDateComponents *offsetComponents = [[NSDateComponents alloc] init]; offsetComponents.month = 1; @@ -122,7 +122,7 @@ - (void)setLastDate:(NSDate *)lastDate; - (void)setSelectedDate:(NSDate *)newSelectedDate; { // clamp to beginning of its day - NSDate *startOfDay = [self clampDate:newSelectedDate toComponents:NSDayCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit]; + NSDate *startOfDay = [self clampDate:newSelectedDate toComponents:NSCalendarUnitDay|NSCalendarUnitMonth|NSCalendarUnitYear]; if ([self.delegate respondsToSelector:@selector(calendarView:shouldSelectDate:)] && ![self.delegate calendarView:self shouldSelectDate:startOfDay]) { return; @@ -182,7 +182,7 @@ - (TSQCalendarRowCell *)cellForRowAtDate:(NSDate *)date; - (NSInteger)sectionForDate:(NSDate *)date; { - return [self.calendar components:NSMonthCalendarUnit fromDate:self.firstDate toDate:date options:0].month; + return [self.calendar components:NSCalendarUnitMonth fromDate:self.firstDate toDate:date options:0].month; } - (NSIndexPath *)indexPathForRowAtDate:(NSDate *)date; @@ -194,8 +194,8 @@ - (NSIndexPath *)indexPathForRowAtDate:(NSDate *)date; NSInteger section = [self sectionForDate:date]; NSDate *firstOfMonth = [self firstOfMonthForSection:section]; - NSInteger firstWeek = [self.calendar components:NSWeekOfMonthCalendarUnit fromDate:firstOfMonth].weekOfMonth; - NSInteger targetWeek = [self.calendar components:NSWeekOfMonthCalendarUnit fromDate:date].weekOfMonth; + NSInteger firstWeek = [self.calendar components:NSCalendarUnitWeekOfMonth fromDate:firstOfMonth].weekOfMonth; + NSInteger targetWeek = [self.calendar components:NSCalendarUnitWeekOfMonth fromDate:date].weekOfMonth; return [NSIndexPath indexPathForRow:targetWeek - firstWeek inSection:section]; } @@ -233,13 +233,13 @@ - (void)layoutSubviews; - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; { - return 1 + [self.calendar components:NSMonthCalendarUnit fromDate:self.firstDate toDate:self.lastDate options:0].month; + return 1 + [self.calendar components:NSCalendarUnitMonth fromDate:self.firstDate toDate:self.lastDate options:0].month; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; { NSDate *firstOfMonth = [self firstOfMonthForSection:section]; - NSRange rangeOfWeeks = [self.calendar rangeOfUnit:NSWeekCalendarUnit inUnit:NSMonthCalendarUnit forDate:firstOfMonth]; + NSRange rangeOfWeeks = [self.calendar rangeOfUnit:NSCalendarUnitWeekOfMonth inUnit:NSCalendarUnitMonth forDate:firstOfMonth]; return rangeOfWeeks.length; } @@ -261,7 +261,7 @@ - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)ce { NSDate *firstOfMonth = [self firstOfMonthForSection:indexPath.section]; [(TSQCalendarCell *)cell setFirstOfMonth:firstOfMonth]; - NSInteger ordinalityOfFirstDay = [self.calendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSWeekCalendarUnit forDate:firstOfMonth]; + NSInteger ordinalityOfFirstDay = [self.calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitWeekOfMonth forDate:firstOfMonth]; NSDateComponents *dateComponents = [NSDateComponents new]; dateComponents.day = 1 - ordinalityOfFirstDay; dateComponents.weekOfMonth = indexPath.row; From 7cde61507d5b7266b9bbc6c39cbd5be9a44d3695 Mon Sep 17 00:00:00 2001 From: Simone Manganelli Date: Wed, 25 Mar 2015 15:31:23 -0700 Subject: [PATCH 19/92] add i386 to valid archs for Carthage --- TimesSquare.xcodeproj/project.pbxproj | 3 +++ .../xcshareddata/xcschemes/TimesSquare-iOS.xcscheme | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/TimesSquare.xcodeproj/project.pbxproj b/TimesSquare.xcodeproj/project.pbxproj index dca1fdc..aaa1c07 100644 --- a/TimesSquare.xcodeproj/project.pbxproj +++ b/TimesSquare.xcodeproj/project.pbxproj @@ -349,6 +349,7 @@ PRODUCT_NAME = TimesSquare; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; + VALID_ARCHS = "arm64 armv7 armv7s i386"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; @@ -388,6 +389,7 @@ PRODUCT_NAME = TimesSquare; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; + VALID_ARCHS = "arm64 armv7 armv7s i386"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; @@ -511,6 +513,7 @@ 5C4733AD1AC3575C00269A66 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; A806805516700FD70071C71E /* Build configuration list for PBXProject "TimesSquare" */ = { isa = XCConfigurationList; diff --git a/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare-iOS.xcscheme b/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare-iOS.xcscheme index eabb4f5..32840fc 100644 --- a/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare-iOS.xcscheme +++ b/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare-iOS.xcscheme @@ -15,7 +15,7 @@ @@ -57,7 +57,7 @@ @@ -76,7 +76,7 @@ @@ -94,7 +94,7 @@ From d1b53bca1eba96a561901c9e0c981e8d02e0dcb4 Mon Sep 17 00:00:00 2001 From: Simone Manganelli Date: Mon, 30 Mar 2015 11:54:25 -0700 Subject: [PATCH 20/92] roll back the 'number of weeks in month' calculation to the iOS 7 units because the new iOS 8 unit names don't result in a proper calculation on iOS 7 --- TimesSquare.xcodeproj/project.pbxproj | 4 ++-- TimesSquare/TSQCalendarView.m | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/TimesSquare.xcodeproj/project.pbxproj b/TimesSquare.xcodeproj/project.pbxproj index aaa1c07..2773000 100644 --- a/TimesSquare.xcodeproj/project.pbxproj +++ b/TimesSquare.xcodeproj/project.pbxproj @@ -412,7 +412,7 @@ "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_PEDANTIC = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; @@ -434,7 +434,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_PEDANTIC = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; diff --git a/TimesSquare/TSQCalendarView.m b/TimesSquare/TSQCalendarView.m index b26c7b0..3e38e64 100644 --- a/TimesSquare/TSQCalendarView.m +++ b/TimesSquare/TSQCalendarView.m @@ -239,7 +239,10 @@ - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; { NSDate *firstOfMonth = [self firstOfMonthForSection:section]; - NSRange rangeOfWeeks = [self.calendar rangeOfUnit:NSCalendarUnitWeekOfMonth inUnit:NSCalendarUnitMonth forDate:firstOfMonth]; + + // using the new calendar units, even though they are available in iOS 7.0, don't actually work for this calculation + // on iOS 7. So we can't use the new units here. + NSRange rangeOfWeeks = [self.calendar rangeOfUnit:NSWeekCalendarUnit inUnit:NSMonthCalendarUnit forDate:firstOfMonth]; return rangeOfWeeks.length; } From 5ef6325cde9df91fc033f3c87bbadc3d1cc5c485 Mon Sep 17 00:00:00 2001 From: Simone Manganelli Date: Tue, 31 Mar 2015 18:00:11 -0700 Subject: [PATCH 21/92] manually copy public headers for some reason --- TimesSquare.xcodeproj/project.pbxproj | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/TimesSquare.xcodeproj/project.pbxproj b/TimesSquare.xcodeproj/project.pbxproj index 2773000..b27cbaf 100644 --- a/TimesSquare.xcodeproj/project.pbxproj +++ b/TimesSquare.xcodeproj/project.pbxproj @@ -19,6 +19,12 @@ 5C4733BA1AC357C000269A66 /* TSQCalendarMonthHeaderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = A8068089167010030071C71E /* TSQCalendarMonthHeaderCell.m */; }; 5C4733BB1AC357C000269A66 /* TSQCalendarRowCell.m in Sources */ = {isa = PBXBuildFile; fileRef = A806808B167010030071C71E /* TSQCalendarRowCell.m */; }; 5C4733BC1AC357C000269A66 /* TSQCalendarView.m in Sources */ = {isa = PBXBuildFile; fileRef = A806808D167010030071C71E /* TSQCalendarView.m */; }; + 5CEF2FEE1ACB788F003E8F61 /* TimesSquare.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = A806806316700FD70071C71E /* TimesSquare.h */; }; + 5CEF2FEF1ACB788F003E8F61 /* TSQCalendarCell.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = A8068086167010030071C71E /* TSQCalendarCell.h */; }; + 5CEF2FF01ACB788F003E8F61 /* TSQCalendarMonthHeaderCell.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = A8068088167010030071C71E /* TSQCalendarMonthHeaderCell.h */; }; + 5CEF2FF11ACB788F003E8F61 /* TSQCalendarRowCell.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = A806808A167010030071C71E /* TSQCalendarRowCell.h */; }; + 5CEF2FF21ACB788F003E8F61 /* TSQCalendarView.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = A806808C167010030071C71E /* TSQCalendarView.h */; }; + 5CEF2FF31ACB788F003E8F61 /* TimesSquare-iOS.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 5C47339D1AC3575C00269A66 /* TimesSquare-iOS.h */; }; A806805F16700FD70071C71E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A806805E16700FD70071C71E /* Foundation.framework */; }; A806808E167010030071C71E /* TSQCalendarCell.m in Sources */ = {isa = PBXBuildFile; fileRef = A8068087167010030071C71E /* TSQCalendarCell.m */; }; A8068090167010030071C71E /* TSQCalendarMonthHeaderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = A8068089167010030071C71E /* TSQCalendarMonthHeaderCell.m */; }; @@ -33,6 +39,21 @@ /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ + 5CEF2FED1ACB785C003E8F61 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = Headers; + dstSubfolderSpec = 1; + files = ( + 5CEF2FEE1ACB788F003E8F61 /* TimesSquare.h in CopyFiles */, + 5CEF2FEF1ACB788F003E8F61 /* TSQCalendarCell.h in CopyFiles */, + 5CEF2FF01ACB788F003E8F61 /* TSQCalendarMonthHeaderCell.h in CopyFiles */, + 5CEF2FF11ACB788F003E8F61 /* TSQCalendarRowCell.h in CopyFiles */, + 5CEF2FF21ACB788F003E8F61 /* TSQCalendarView.h in CopyFiles */, + 5CEF2FF31ACB788F003E8F61 /* TimesSquare-iOS.h in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; A806805916700FD70071C71E /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -215,6 +236,7 @@ 5C4733951AC3575B00269A66 /* Frameworks */, 5C4733961AC3575B00269A66 /* Headers */, 5C4733971AC3575B00269A66 /* Resources */, + 5CEF2FED1ACB785C003E8F61 /* CopyFiles */, ); buildRules = ( ); From de307b24432b25fd3d3c4c7144c4f82a2ba322d0 Mon Sep 17 00:00:00 2001 From: Fidel Sosa Date: Wed, 8 Apr 2015 17:29:49 -0700 Subject: [PATCH 22/92] Fix iOS 8.3 warning --- TimesSquare.xcodeproj/project.pbxproj | 3 ++- .../xcschemes/TimesSquare Documentation.xcscheme | 11 ++++++++++- .../xcshareddata/xcschemes/TimesSquare-iOS.xcscheme | 2 +- .../xcshareddata/xcschemes/TimesSquare.xcscheme | 11 ++++++++++- TimesSquare/TSQCalendarCell.m | 2 +- 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/TimesSquare.xcodeproj/project.pbxproj b/TimesSquare.xcodeproj/project.pbxproj index b27cbaf..510532b 100644 --- a/TimesSquare.xcodeproj/project.pbxproj +++ b/TimesSquare.xcodeproj/project.pbxproj @@ -271,7 +271,7 @@ A806805216700FD70071C71E /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0510; + LastUpgradeCheck = 0630; ORGANIZATIONNAME = Square; TargetAttributes = { 5C4733981AC3575B00269A66 = { @@ -440,6 +440,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 5.0; + ONLY_ACTIVE_ARCH = YES; PUBLIC_HEADERS_FOLDER_PATH = "include/$(PRODUCT_NAME)"; RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = iphoneos; diff --git a/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare Documentation.xcscheme b/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare Documentation.xcscheme index a124484..d4c657e 100644 --- a/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare Documentation.xcscheme +++ b/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare Documentation.xcscheme @@ -1,6 +1,6 @@ + + + + diff --git a/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare-iOS.xcscheme b/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare-iOS.xcscheme index 32840fc..5216f1d 100644 --- a/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare-iOS.xcscheme +++ b/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare-iOS.xcscheme @@ -1,6 +1,6 @@ + + + + diff --git a/TimesSquare/TSQCalendarCell.m b/TimesSquare/TSQCalendarCell.m index 011e94c..ada2031 100644 --- a/TimesSquare/TSQCalendarCell.m +++ b/TimesSquare/TSQCalendarCell.m @@ -97,7 +97,7 @@ - (void)layoutSubviews; CGFloat extraSpace = (CGRectGetWidth(insetRect) - (self.daysInWeek - 1) * self.columnSpacing) - (increment * self.daysInWeek); // Divide the extra space out over the outer columns in increments of the column spacing - NSInteger columnsWithExtraSpace = (NSInteger)fabsf(extraSpace / self.columnSpacing); + NSInteger columnsWithExtraSpace = (NSInteger)fabs(extraSpace / self.columnSpacing); NSInteger columnsOnLeftWithExtraSpace = columnsWithExtraSpace / 2; NSInteger columnsOnRightWithExtraSpace = columnsWithExtraSpace - columnsOnLeftWithExtraSpace; From 146ee810b3af77e9ddbc81f841efc522f872e164 Mon Sep 17 00:00:00 2001 From: Simone Manganelli Date: Fri, 17 Apr 2015 15:25:12 -0700 Subject: [PATCH 23/92] get rid of extra framework header --- TimesSquare-iOS/TimesSquare-iOS.h | 19 ------------------- TimesSquare.xcodeproj/project.pbxproj | 6 ------ 2 files changed, 25 deletions(-) delete mode 100644 TimesSquare-iOS/TimesSquare-iOS.h diff --git a/TimesSquare-iOS/TimesSquare-iOS.h b/TimesSquare-iOS/TimesSquare-iOS.h deleted file mode 100644 index eca88a8..0000000 --- a/TimesSquare-iOS/TimesSquare-iOS.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// TimesSquare-iOS.h -// TimesSquare-iOS -// -// Created by Simone Manganelli on 25/03/15. -// Copyright (c) 2015 Square. All rights reserved. -// - -#import - -//! Project version number for TimesSquare-iOS. -FOUNDATION_EXPORT double TimesSquare_iOSVersionNumber; - -//! Project version string for TimesSquare-iOS. -FOUNDATION_EXPORT const unsigned char TimesSquare_iOSVersionString[]; - -// In this header, you should import all the public headers of your framework using statements like #import - - diff --git a/TimesSquare.xcodeproj/project.pbxproj b/TimesSquare.xcodeproj/project.pbxproj index b27cbaf..06f9271 100644 --- a/TimesSquare.xcodeproj/project.pbxproj +++ b/TimesSquare.xcodeproj/project.pbxproj @@ -7,7 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - 5C47339E1AC3575C00269A66 /* TimesSquare-iOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C47339D1AC3575C00269A66 /* TimesSquare-iOS.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5C4733B21AC357A700269A66 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A806809E167012980071C71E /* CoreGraphics.framework */; }; 5C4733B31AC357AB00269A66 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A806805E16700FD70071C71E /* Foundation.framework */; }; 5C4733B41AC357B200269A66 /* TimesSquare.h in Headers */ = {isa = PBXBuildFile; fileRef = A806806316700FD70071C71E /* TimesSquare.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -24,7 +23,6 @@ 5CEF2FF01ACB788F003E8F61 /* TSQCalendarMonthHeaderCell.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = A8068088167010030071C71E /* TSQCalendarMonthHeaderCell.h */; }; 5CEF2FF11ACB788F003E8F61 /* TSQCalendarRowCell.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = A806808A167010030071C71E /* TSQCalendarRowCell.h */; }; 5CEF2FF21ACB788F003E8F61 /* TSQCalendarView.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = A806808C167010030071C71E /* TSQCalendarView.h */; }; - 5CEF2FF31ACB788F003E8F61 /* TimesSquare-iOS.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 5C47339D1AC3575C00269A66 /* TimesSquare-iOS.h */; }; A806805F16700FD70071C71E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A806805E16700FD70071C71E /* Foundation.framework */; }; A806808E167010030071C71E /* TSQCalendarCell.m in Sources */ = {isa = PBXBuildFile; fileRef = A8068087167010030071C71E /* TSQCalendarCell.m */; }; A8068090167010030071C71E /* TSQCalendarMonthHeaderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = A8068089167010030071C71E /* TSQCalendarMonthHeaderCell.m */; }; @@ -50,7 +48,6 @@ 5CEF2FF01ACB788F003E8F61 /* TSQCalendarMonthHeaderCell.h in CopyFiles */, 5CEF2FF11ACB788F003E8F61 /* TSQCalendarRowCell.h in CopyFiles */, 5CEF2FF21ACB788F003E8F61 /* TSQCalendarView.h in CopyFiles */, - 5CEF2FF31ACB788F003E8F61 /* TimesSquare-iOS.h in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -68,7 +65,6 @@ /* Begin PBXFileReference section */ 5C4733991AC3575B00269A66 /* TimesSquare.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TimesSquare.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 5C47339C1AC3575C00269A66 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 5C47339D1AC3575C00269A66 /* TimesSquare-iOS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "TimesSquare-iOS.h"; sourceTree = ""; }; A806805B16700FD70071C71E /* libTimesSquare.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libTimesSquare.a; sourceTree = BUILT_PRODUCTS_DIR; }; A806805E16700FD70071C71E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; A806806216700FD70071C71E /* TimesSquare-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "TimesSquare-Prefix.pch"; sourceTree = ""; }; @@ -111,7 +107,6 @@ 5C47339A1AC3575C00269A66 /* TimesSquare-iOS */ = { isa = PBXGroup; children = ( - 5C47339D1AC3575C00269A66 /* TimesSquare-iOS.h */, 5C47339B1AC3575C00269A66 /* Supporting Files */, ); path = "TimesSquare-iOS"; @@ -188,7 +183,6 @@ buildActionMask = 2147483647; files = ( 5C4733B41AC357B200269A66 /* TimesSquare.h in Headers */, - 5C47339E1AC3575C00269A66 /* TimesSquare-iOS.h in Headers */, 5C4733B81AC357B200269A66 /* TSQCalendarView.h in Headers */, 5C4733B51AC357B200269A66 /* TSQCalendarCell.h in Headers */, 5C4733B61AC357B200269A66 /* TSQCalendarMonthHeaderCell.h in Headers */, From dd1d06c6c6486618c96a776d150e94d5adc42a99 Mon Sep 17 00:00:00 2001 From: Loretta Chan Date: Fri, 24 Jul 2015 10:10:34 -0700 Subject: [PATCH 24/92] calendar cell has a second title + new delegate --- TimesSquare.xcodeproj/project.pbxproj | 12 +++++++++ TimesSquare/TSQCalendarCell.h | 1 + TimesSquare/TSQCalendarCell.m | 1 + TimesSquare/TSQCalendarDayButton.h | 14 +++++++++++ TimesSquare/TSQCalendarDayButton.m | 35 +++++++++++++++++++++++++++ TimesSquare/TSQCalendarRowCell.h | 1 + TimesSquare/TSQCalendarRowCell.m | 31 ++++++++++++++++++------ TimesSquare/TSQCalendarView.h | 5 ++++ 8 files changed, 93 insertions(+), 7 deletions(-) create mode 100644 TimesSquare/TSQCalendarDayButton.h create mode 100644 TimesSquare/TSQCalendarDayButton.m diff --git a/TimesSquare.xcodeproj/project.pbxproj b/TimesSquare.xcodeproj/project.pbxproj index f2a8df1..4df520a 100644 --- a/TimesSquare.xcodeproj/project.pbxproj +++ b/TimesSquare.xcodeproj/project.pbxproj @@ -23,6 +23,10 @@ 5CEF2FF01ACB788F003E8F61 /* TSQCalendarMonthHeaderCell.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = A8068088167010030071C71E /* TSQCalendarMonthHeaderCell.h */; }; 5CEF2FF11ACB788F003E8F61 /* TSQCalendarRowCell.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = A806808A167010030071C71E /* TSQCalendarRowCell.h */; }; 5CEF2FF21ACB788F003E8F61 /* TSQCalendarView.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = A806808C167010030071C71E /* TSQCalendarView.h */; }; + 87F195FB1B61B2D100EC341E /* TSQCalendarDayButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 87F195F91B61B2D100EC341E /* TSQCalendarDayButton.h */; }; + 87F195FC1B61B2D100EC341E /* TSQCalendarDayButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 87F195F91B61B2D100EC341E /* TSQCalendarDayButton.h */; }; + 87F195FD1B61B2D100EC341E /* TSQCalendarDayButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 87F195FA1B61B2D100EC341E /* TSQCalendarDayButton.m */; }; + 87F195FE1B61B2D100EC341E /* TSQCalendarDayButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 87F195FA1B61B2D100EC341E /* TSQCalendarDayButton.m */; }; A806805F16700FD70071C71E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A806805E16700FD70071C71E /* Foundation.framework */; }; A806808E167010030071C71E /* TSQCalendarCell.m in Sources */ = {isa = PBXBuildFile; fileRef = A8068087167010030071C71E /* TSQCalendarCell.m */; }; A8068090167010030071C71E /* TSQCalendarMonthHeaderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = A8068089167010030071C71E /* TSQCalendarMonthHeaderCell.m */; }; @@ -65,6 +69,8 @@ /* Begin PBXFileReference section */ 5C4733991AC3575B00269A66 /* TimesSquare.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TimesSquare.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 5C47339C1AC3575C00269A66 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 87F195F91B61B2D100EC341E /* TSQCalendarDayButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSQCalendarDayButton.h; sourceTree = ""; }; + 87F195FA1B61B2D100EC341E /* TSQCalendarDayButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSQCalendarDayButton.m; sourceTree = ""; }; A806805B16700FD70071C71E /* libTimesSquare.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libTimesSquare.a; sourceTree = BUILT_PRODUCTS_DIR; }; A806805E16700FD70071C71E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; A806806216700FD70071C71E /* TimesSquare-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "TimesSquare-Prefix.pch"; sourceTree = ""; }; @@ -161,6 +167,8 @@ A806808A167010030071C71E /* TSQCalendarRowCell.h */, A806808B167010030071C71E /* TSQCalendarRowCell.m */, A806808C167010030071C71E /* TSQCalendarView.h */, + 87F195F91B61B2D100EC341E /* TSQCalendarDayButton.h */, + 87F195FA1B61B2D100EC341E /* TSQCalendarDayButton.m */, A806808D167010030071C71E /* TSQCalendarView.m */, A806806116700FD70071C71E /* Supporting Files */, ); @@ -184,6 +192,7 @@ files = ( 5C4733B41AC357B200269A66 /* TimesSquare.h in Headers */, 5C4733B81AC357B200269A66 /* TSQCalendarView.h in Headers */, + 87F195FC1B61B2D100EC341E /* TSQCalendarDayButton.h in Headers */, 5C4733B51AC357B200269A66 /* TSQCalendarCell.h in Headers */, 5C4733B61AC357B200269A66 /* TSQCalendarMonthHeaderCell.h in Headers */, 5C4733B71AC357B200269A66 /* TSQCalendarRowCell.h in Headers */, @@ -196,6 +205,7 @@ files = ( EFD8DE6D167AF77B00F87FBE /* TimesSquare.h in Headers */, EFD8DE6E167AF78100F87FBE /* TSQCalendarCell.h in Headers */, + 87F195FB1B61B2D100EC341E /* TSQCalendarDayButton.h in Headers */, EFD8DE6F167AF78600F87FBE /* TSQCalendarMonthHeaderCell.h in Headers */, EFD8DE70167AF78C00F87FBE /* TSQCalendarRowCell.h in Headers */, EFD8DE71167AF79000F87FBE /* TSQCalendarView.h in Headers */, @@ -309,6 +319,7 @@ files = ( 5C4733B91AC357C000269A66 /* TSQCalendarCell.m in Sources */, 5C4733BA1AC357C000269A66 /* TSQCalendarMonthHeaderCell.m in Sources */, + 87F195FE1B61B2D100EC341E /* TSQCalendarDayButton.m in Sources */, 5C4733BB1AC357C000269A66 /* TSQCalendarRowCell.m in Sources */, 5C4733BC1AC357C000269A66 /* TSQCalendarView.m in Sources */, ); @@ -320,6 +331,7 @@ files = ( A806808E167010030071C71E /* TSQCalendarCell.m in Sources */, A8068090167010030071C71E /* TSQCalendarMonthHeaderCell.m in Sources */, + 87F195FD1B61B2D100EC341E /* TSQCalendarDayButton.m in Sources */, A8068092167010030071C71E /* TSQCalendarRowCell.m in Sources */, A8068094167010030071C71E /* TSQCalendarView.m in Sources */, ); diff --git a/TimesSquare/TSQCalendarCell.h b/TimesSquare/TSQCalendarCell.h index 0f27f27..1f03ae5 100644 --- a/TimesSquare/TSQCalendarCell.h +++ b/TimesSquare/TSQCalendarCell.h @@ -89,4 +89,5 @@ */ - (void)layoutViewsForColumnAtIndex:(NSUInteger)index inRect:(CGRect)rect; + @end diff --git a/TimesSquare/TSQCalendarCell.m b/TimesSquare/TSQCalendarCell.m index ada2031..8ebe6a9 100644 --- a/TimesSquare/TSQCalendarCell.m +++ b/TimesSquare/TSQCalendarCell.m @@ -118,6 +118,7 @@ - (void)layoutSubviews; [self layoutViewsForColumnAtIndex:displayIndex inRect:columnBounds]; start += width + self.columnSpacing; } + } diff --git a/TimesSquare/TSQCalendarDayButton.h b/TimesSquare/TSQCalendarDayButton.h new file mode 100644 index 0000000..fe710ea --- /dev/null +++ b/TimesSquare/TSQCalendarDayButton.h @@ -0,0 +1,14 @@ +// +// TSQCalendarDayButton.h +// TimesSquare +// +// Created by Loretta Chan on 7/23/15. +// Copyright (c) 2015 Square. All rights reserved. +// + +#import + +@interface TSQCalendarDayButton : UIButton + +@property (nonatomic, strong) UILabel *secondTitleLabel; +@end diff --git a/TimesSquare/TSQCalendarDayButton.m b/TimesSquare/TSQCalendarDayButton.m new file mode 100644 index 0000000..d608343 --- /dev/null +++ b/TimesSquare/TSQCalendarDayButton.m @@ -0,0 +1,35 @@ +// +// TSQCalendarDayButton.m +// TimesSquare +// +// Created by Loretta Chan on 7/23/15. +// Copyright (c) 2015 Square. All rights reserved. +// + +#import "TSQCalendarDayButton.h" + +@implementation TSQCalendarDayButton + + +/* +// Only override drawRect: if you perform custom drawing. +// An empty implementation adversely affects performance during animation. +- (void)drawRect:(CGRect)rect { + // Drawing code +} +*/ + +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + self.secondTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 50, 85, 18)]; + self.secondTitleLabel.textAlignment = NSTextAlignmentCenter; + self.secondTitleLabel.userInteractionEnabled = NO; + self.secondTitleLabel.backgroundColor = [UIColor clearColor]; + [self addSubview:self.secondTitleLabel]; + self.secondTitleLabel.text = @"blah blah"; + } + return self; +} +@end diff --git a/TimesSquare/TSQCalendarRowCell.h b/TimesSquare/TSQCalendarRowCell.h index 8c1a055..3f97769 100644 --- a/TimesSquare/TSQCalendarRowCell.h +++ b/TimesSquare/TSQCalendarRowCell.h @@ -73,6 +73,7 @@ This is white by default. */ @property (nonatomic, getter = isBottomRow) BOOL bottomRow; + /** Method to select a specific date within the week. This is funneled through and called by the calendar view, to facilitate deselection of other rows. diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index d00b0ea..45d0f2d 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -9,14 +9,14 @@ #import "TSQCalendarRowCell.h" #import "TSQCalendarView.h" - +#import "TSQCalendarDayButton.h" @interface TSQCalendarRowCell () @property (nonatomic, strong) NSArray *dayButtons; @property (nonatomic, strong) NSArray *notThisMonthButtons; -@property (nonatomic, strong) UIButton *todayButton; -@property (nonatomic, strong) UIButton *selectedButton; +@property (nonatomic, strong) TSQCalendarDayButton *todayButton; +@property (nonatomic, strong) TSQCalendarDayButton *selectedButton; @property (nonatomic, assign) NSInteger indexOfTodayButton; @property (nonatomic, assign) NSInteger indexOfSelectedButton; @@ -27,6 +27,9 @@ @interface TSQCalendarRowCell () @property (nonatomic, strong) NSDateComponents *todayDateComponents; @property (nonatomic) NSInteger monthOfBeginningDate; +@property (nonatomic, strong) UILabel *secondTitleLabel; +@property (nonatomic, strong) NSArray *shiftNotes; + @end @@ -59,13 +62,14 @@ - (void)configureButton:(UIButton *)button; button.adjustsImageWhenDisabled = NO; [button setTitleColor:self.textColor forState:UIControlStateNormal]; [button setTitleShadowColor:[UIColor whiteColor] forState:UIControlStateNormal]; + } - (void)createDayButtons; { NSMutableArray *dayButtons = [NSMutableArray arrayWithCapacity:self.daysInWeek]; for (NSUInteger index = 0; index < self.daysInWeek; index++) { - UIButton *button = [[UIButton alloc] initWithFrame:self.contentView.bounds]; + TSQCalendarDayButton *button = [[TSQCalendarDayButton alloc] initWithFrame:self.contentView.bounds]; [button addTarget:self action:@selector(dateButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; [dayButtons addObject:button]; [self.contentView addSubview:button]; @@ -79,7 +83,7 @@ - (void)createNotThisMonthButtons; { NSMutableArray *notThisMonthButtons = [NSMutableArray arrayWithCapacity:self.daysInWeek]; for (NSUInteger index = 0; index < self.daysInWeek; index++) { - UIButton *button = [[UIButton alloc] initWithFrame:self.contentView.bounds]; + TSQCalendarDayButton *button = [[TSQCalendarDayButton alloc] initWithFrame:self.contentView.bounds]; [notThisMonthButtons addObject:button]; [self.contentView addSubview:button]; [self configureButton:button]; @@ -93,7 +97,7 @@ - (void)createNotThisMonthButtons; - (void)createTodayButton; { - self.todayButton = [[UIButton alloc] initWithFrame:self.contentView.bounds]; + self.todayButton = [[TSQCalendarDayButton alloc] initWithFrame:self.contentView.bounds]; [self.contentView addSubview:self.todayButton]; [self configureButton:self.todayButton]; [self.todayButton addTarget:self action:@selector(todayButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; @@ -107,7 +111,7 @@ - (void)createTodayButton; - (void)createSelectedButton; { - self.selectedButton = [[UIButton alloc] initWithFrame:self.contentView.bounds]; + self.selectedButton = [[TSQCalendarDayButton alloc] initWithFrame:self.contentView.bounds]; [self.contentView addSubview:self.selectedButton]; [self configureButton:self.selectedButton]; @@ -151,6 +155,18 @@ - (void)setBeginningDate:(NSDate *)date; [self.notThisMonthButtons[index] setTitle:title forState:UIControlStateDisabled]; [self.notThisMonthButtons[index] setAccessibilityLabel:accessibilityLabel]; + + NSString *secondTitle = nil; + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:secondTitleForDate:)]) { + secondTitle = [self.calendarView.delegate calendarView:self.calendarView secondTitleForDate:date]; + TSQCalendarDayButton *dayButton = self.dayButtons[index]; + TSQCalendarDayButton *notThisMonthButton = self.notThisMonthButtons[index]; + dayButton.secondTitleLabel.text = secondTitle; + notThisMonthButton.secondTitleLabel.text = secondTitle; + + + } + NSDateComponents *thisDateComponents = [self.calendar components:NSCalendarUnitDay|NSCalendarUnitMonth|NSCalendarUnitYear fromDate:date]; [self.dayButtons[index] setHidden:YES]; @@ -166,6 +182,7 @@ - (void)setBeginningDate:(NSDate *)date; [self.todayButton setTitle:title forState:UIControlStateNormal]; [self.todayButton setAccessibilityLabel:accessibilityLabel]; self.indexOfTodayButton = index; + self.todayButton.secondTitleLabel.text = secondTitle; } else { UIButton *button = self.dayButtons[index]; button.enabled = ![self.calendarView.delegate respondsToSelector:@selector(calendarView:shouldSelectDate:)] || [self.calendarView.delegate calendarView:self.calendarView shouldSelectDate:date]; diff --git a/TimesSquare/TSQCalendarView.h b/TimesSquare/TSQCalendarView.h index d6f0dab..a6e257e 100644 --- a/TimesSquare/TSQCalendarView.h +++ b/TimesSquare/TSQCalendarView.h @@ -97,6 +97,9 @@ */ @property (nonatomic, strong) Class rowCellClass; +// Return all(?) shift notes +@property (nonatomic, readonly) NSArray *shiftNotes; + /** Scrolls the receiver until the specified date month is completely visible. @param date A date that identifies the month that will be visible. @@ -124,6 +127,8 @@ */ - (BOOL)calendarView:(TSQCalendarView *)calendarView shouldSelectDate:(NSDate *)date; +- (NSString*)calendarView: (TSQCalendarView *)calendarView secondTitleForDate: (NSDate*) date; + /** Tells the delegate that a particular date was selected. @param calendarView The calendar view that is selecting a date. From 8d661cb450a3b955594e29c9deb6238896c169cb Mon Sep 17 00:00:00 2001 From: Loretta Chan Date: Mon, 27 Jul 2015 10:59:05 -0700 Subject: [PATCH 25/92] removed blah blah --- TimesSquare/TSQCalendarDayButton.m | 1 - TimesSquare/TSQCalendarRowCell.m | 2 -- 2 files changed, 3 deletions(-) diff --git a/TimesSquare/TSQCalendarDayButton.m b/TimesSquare/TSQCalendarDayButton.m index d608343..f3dfc73 100644 --- a/TimesSquare/TSQCalendarDayButton.m +++ b/TimesSquare/TSQCalendarDayButton.m @@ -28,7 +28,6 @@ - (instancetype)initWithFrame:(CGRect)frame self.secondTitleLabel.userInteractionEnabled = NO; self.secondTitleLabel.backgroundColor = [UIColor clearColor]; [self addSubview:self.secondTitleLabel]; - self.secondTitleLabel.text = @"blah blah"; } return self; } diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 45d0f2d..421c87f 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -163,8 +163,6 @@ - (void)setBeginningDate:(NSDate *)date; TSQCalendarDayButton *notThisMonthButton = self.notThisMonthButtons[index]; dayButton.secondTitleLabel.text = secondTitle; notThisMonthButton.secondTitleLabel.text = secondTitle; - - } NSDateComponents *thisDateComponents = [self.calendar components:NSCalendarUnitDay|NSCalendarUnitMonth|NSCalendarUnitYear fromDate:date]; From 251848f7978d356a91f9e6becf44ebd43bbc7ed5 Mon Sep 17 00:00:00 2001 From: Loretta Chan Date: Wed, 12 Aug 2015 15:28:34 -0700 Subject: [PATCH 26/92] font for secondtitle --- TimesSquare-iOS/Info.plist | 6 ++++++ TimesSquare/TSQCalendarRowCell.h | 4 ++++ TimesSquare/TSQCalendarRowCell.m | 16 +++++++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/TimesSquare-iOS/Info.plist b/TimesSquare-iOS/Info.plist index f55e246..668cf6a 100644 --- a/TimesSquare-iOS/Info.plist +++ b/TimesSquare-iOS/Info.plist @@ -2,6 +2,12 @@ + UIAppFonts + + + + LSApplicationCategoryType + CFBundleDevelopmentRegion en CFBundleExecutable diff --git a/TimesSquare/TSQCalendarRowCell.h b/TimesSquare/TSQCalendarRowCell.h index 3f97769..3b51ed2 100644 --- a/TimesSquare/TSQCalendarRowCell.h +++ b/TimesSquare/TSQCalendarRowCell.h @@ -24,12 +24,16 @@ @property (nonatomic, weak, readonly) UIFont *dayOfMonthFont; +@property (nonatomic, weak, readonly) UIFont *secondTitleFont; + + /** The text color for a day that's "today". This is white by default. */ @property (nonatomic, weak, readonly) UIColor *todayTextColor; +@property (nonatomic, weak, readonly) UIColor *secondTitleTextColor; /** @name Images */ diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 421c87f..9340327 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -50,14 +50,27 @@ - (UIFont *)dayOfMonthFont return [UIFont boldSystemFontOfSize:19.0f]; } +- (UIFont *)secondTitleFont +{ + return [UIFont boldSystemFontOfSize:12.0f]; +} + - (UIColor *)todayTextColor { return [UIColor whiteColor]; } -- (void)configureButton:(UIButton *)button; +- (UIColor *)secondTitleTextColor +{ + return [UIColor blackColor]; +} + + +- (void)configureButton:(TSQCalendarDayButton *)button; { button.titleLabel.font = [self dayOfMonthFont]; + button.secondTitleLabel.font = [self secondTitleFont]; + button.secondTitleLabel.textColor = [self secondTitleTextColor]; button.titleLabel.shadowOffset = self.shadowOffset; button.adjustsImageWhenDisabled = NO; [button setTitleColor:self.textColor forState:UIControlStateNormal]; @@ -98,6 +111,7 @@ - (void)createNotThisMonthButtons; - (void)createTodayButton; { self.todayButton = [[TSQCalendarDayButton alloc] initWithFrame:self.contentView.bounds]; + [self.contentView addSubview:self.todayButton]; [self configureButton:self.todayButton]; [self.todayButton addTarget:self action:@selector(todayButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; From 8d8586f1795b53fc91677484307035c0d98b1c84 Mon Sep 17 00:00:00 2001 From: Loretta Chan Date: Thu, 13 Aug 2015 17:37:14 -0700 Subject: [PATCH 27/92] fixed title not showing problem on selected day --- TimesSquare/TSQCalendarRowCell.m | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 9340327..19757a3 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -63,14 +63,22 @@ - (UIColor *)todayTextColor - (UIColor *)secondTitleTextColor { return [UIColor blackColor]; + } -- (void)configureButton:(TSQCalendarDayButton *)button; +- (void)configureButton:(TSQCalendarDayButton *)button isSelected: (BOOL) selected; { button.titleLabel.font = [self dayOfMonthFont]; button.secondTitleLabel.font = [self secondTitleFont]; - button.secondTitleLabel.textColor = [self secondTitleTextColor]; + if (!selected) { + button.secondTitleLabel.textColor = [self secondTitleTextColor]; + } else { + button.secondTitleLabel.textColor = [UIColor whiteColor]; + button.secondTitleLabel.shadowColor = [UIColor colorWithWhite:0.0f alpha:0.75f]; + } + button.secondTitleLabel.adjustsFontSizeToFitWidth = NO; + button.secondTitleLabel.lineBreakMode = NSLineBreakByTruncatingTail; button.titleLabel.shadowOffset = self.shadowOffset; button.adjustsImageWhenDisabled = NO; [button setTitleColor:self.textColor forState:UIControlStateNormal]; @@ -86,7 +94,7 @@ - (void)createDayButtons; [button addTarget:self action:@selector(dateButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; [dayButtons addObject:button]; [self.contentView addSubview:button]; - [self configureButton:button]; + [self configureButton:button isSelected:NO]; [button setTitleColor:[self.textColor colorWithAlphaComponent:0.5f] forState:UIControlStateDisabled]; } self.dayButtons = dayButtons; @@ -99,7 +107,7 @@ - (void)createNotThisMonthButtons; TSQCalendarDayButton *button = [[TSQCalendarDayButton alloc] initWithFrame:self.contentView.bounds]; [notThisMonthButtons addObject:button]; [self.contentView addSubview:button]; - [self configureButton:button]; + [self configureButton:button isSelected: NO]; [button setTitleColor:[self.textColor colorWithAlphaComponent:0.5f] forState:UIControlStateDisabled]; button.enabled = NO; UIColor *backgroundPattern = [UIColor colorWithPatternImage:[self notThisMonthBackgroundImage]]; @@ -113,7 +121,7 @@ - (void)createTodayButton; self.todayButton = [[TSQCalendarDayButton alloc] initWithFrame:self.contentView.bounds]; [self.contentView addSubview:self.todayButton]; - [self configureButton:self.todayButton]; + [self configureButton:self.todayButton isSelected:NO]; [self.todayButton addTarget:self action:@selector(todayButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; [self.todayButton setTitleColor:[self todayTextColor] forState:UIControlStateNormal]; @@ -127,10 +135,8 @@ - (void)createSelectedButton; { self.selectedButton = [[TSQCalendarDayButton alloc] initWithFrame:self.contentView.bounds]; [self.contentView addSubview:self.selectedButton]; - [self configureButton:self.selectedButton]; - + [self configureButton:self.selectedButton isSelected:YES]; [self.selectedButton setAccessibilityTraits:UIAccessibilityTraitSelected|self.selectedButton.accessibilityTraits]; - self.selectedButton.enabled = NO; [self.selectedButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; [self.selectedButton setBackgroundImage:[self selectedBackgroundImage] forState:UIControlStateNormal]; @@ -294,6 +300,11 @@ - (void)selectColumnForDate:(NSDate *)date; [self.selectedButton setTitle:newTitle forState:UIControlStateNormal]; [self.selectedButton setTitle:newTitle forState:UIControlStateDisabled]; [self.selectedButton setAccessibilityLabel:[self.dayButtons[newIndexOfSelectedButton] accessibilityLabel]]; + + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:secondTitleForDate:)]) { + self.selectedButton.secondTitleLabel.text = [self.calendarView.delegate calendarView:self.calendarView secondTitleForDate:date]; + } + } else { self.selectedButton.hidden = YES; } From 978628c39fabc6c0c060536782f87a6c84012fb1 Mon Sep 17 00:00:00 2001 From: Loretta Chan Date: Thu, 20 Aug 2015 10:35:33 -0700 Subject: [PATCH 28/92] moved day title label up by 10 pt --- TimesSquare/TSQCalendarDayButton.m | 3 ++- TimesSquare/TSQCalendarRowCell.m | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/TimesSquare/TSQCalendarDayButton.m b/TimesSquare/TSQCalendarDayButton.m index f3dfc73..b85e7ad 100644 --- a/TimesSquare/TSQCalendarDayButton.m +++ b/TimesSquare/TSQCalendarDayButton.m @@ -23,7 +23,8 @@ - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { - self.secondTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 50, 85, 18)]; + [self setTitleEdgeInsets:UIEdgeInsetsMake(-10, 0, 0, 0)]; + self.secondTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 50, 65, 18)]; self.secondTitleLabel.textAlignment = NSTextAlignmentCenter; self.secondTitleLabel.userInteractionEnabled = NO; self.secondTitleLabel.backgroundColor = [UIColor clearColor]; diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 19757a3..98a6ce9 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -75,7 +75,6 @@ - (void)configureButton:(TSQCalendarDayButton *)button isSelected: (BOOL) select button.secondTitleLabel.textColor = [self secondTitleTextColor]; } else { button.secondTitleLabel.textColor = [UIColor whiteColor]; - button.secondTitleLabel.shadowColor = [UIColor colorWithWhite:0.0f alpha:0.75f]; } button.secondTitleLabel.adjustsFontSizeToFitWidth = NO; button.secondTitleLabel.lineBreakMode = NSLineBreakByTruncatingTail; From 3f161ea2d6497e710d921480eabb7d261e8c22b0 Mon Sep 17 00:00:00 2001 From: Simone Manganelli Date: Fri, 11 Sep 2015 12:11:04 -0700 Subject: [PATCH 29/92] change secondTitle name to subtitle; allow for custom date and subtitle label colors; also clean up the code a little to make it more manageable --- TimesSquare/TSQCalendarDayButton.h | 2 +- TimesSquare/TSQCalendarDayButton.m | 10 +- TimesSquare/TSQCalendarRowCell.h | 4 +- TimesSquare/TSQCalendarRowCell.m | 202 ++++++++++++++++++++++++----- TimesSquare/TSQCalendarView.h | 8 +- 5 files changed, 181 insertions(+), 45 deletions(-) diff --git a/TimesSquare/TSQCalendarDayButton.h b/TimesSquare/TSQCalendarDayButton.h index fe710ea..e0d2961 100644 --- a/TimesSquare/TSQCalendarDayButton.h +++ b/TimesSquare/TSQCalendarDayButton.h @@ -10,5 +10,5 @@ @interface TSQCalendarDayButton : UIButton -@property (nonatomic, strong) UILabel *secondTitleLabel; +@property (nonatomic, strong) UILabel *subtitleLabel; @end diff --git a/TimesSquare/TSQCalendarDayButton.m b/TimesSquare/TSQCalendarDayButton.m index b85e7ad..59e3089 100644 --- a/TimesSquare/TSQCalendarDayButton.m +++ b/TimesSquare/TSQCalendarDayButton.m @@ -24,11 +24,11 @@ - (instancetype)initWithFrame:(CGRect)frame self = [super initWithFrame:frame]; if (self) { [self setTitleEdgeInsets:UIEdgeInsetsMake(-10, 0, 0, 0)]; - self.secondTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 50, 65, 18)]; - self.secondTitleLabel.textAlignment = NSTextAlignmentCenter; - self.secondTitleLabel.userInteractionEnabled = NO; - self.secondTitleLabel.backgroundColor = [UIColor clearColor]; - [self addSubview:self.secondTitleLabel]; + self.subtitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 50, 65, 18)]; + self.subtitleLabel.textAlignment = NSTextAlignmentCenter; + self.subtitleLabel.userInteractionEnabled = NO; + self.subtitleLabel.backgroundColor = [UIColor clearColor]; + [self addSubview:self.subtitleLabel]; } return self; } diff --git a/TimesSquare/TSQCalendarRowCell.h b/TimesSquare/TSQCalendarRowCell.h index 3b51ed2..9427ca2 100644 --- a/TimesSquare/TSQCalendarRowCell.h +++ b/TimesSquare/TSQCalendarRowCell.h @@ -24,7 +24,7 @@ @property (nonatomic, weak, readonly) UIFont *dayOfMonthFont; -@property (nonatomic, weak, readonly) UIFont *secondTitleFont; +@property (nonatomic, weak, readonly) UIFont *subtitleFont; /** The text color for a day that's "today". @@ -33,7 +33,7 @@ This is white by default. */ @property (nonatomic, weak, readonly) UIColor *todayTextColor; -@property (nonatomic, weak, readonly) UIColor *secondTitleTextColor; +@property (nonatomic, weak, readonly) UIColor *subtitleTextColor; /** @name Images */ diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 98a6ce9..a0cb577 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -11,6 +11,15 @@ #import "TSQCalendarView.h" #import "TSQCalendarDayButton.h" +typedef NS_ENUM(NSInteger, CalendarButtonType) { + CalendarButtonTypeNormalDay = 0, + CalendarButtonTypeOtherMonth = 1, + CalendarButtonTypeToday = 2, + CalendarButtonTypeSelected = 3 +}; + + + @interface TSQCalendarRowCell () @property (nonatomic, strong) NSArray *dayButtons; @@ -27,7 +36,7 @@ @interface TSQCalendarRowCell () @property (nonatomic, strong) NSDateComponents *todayDateComponents; @property (nonatomic) NSInteger monthOfBeginningDate; -@property (nonatomic, strong) UILabel *secondTitleLabel; +@property (nonatomic, strong) UILabel *subtitleLabel; @property (nonatomic, strong) NSArray *shiftNotes; @end @@ -50,7 +59,7 @@ - (UIFont *)dayOfMonthFont return [UIFont boldSystemFontOfSize:19.0f]; } -- (UIFont *)secondTitleFont +- (UIFont *)subtitleFont { return [UIFont boldSystemFontOfSize:12.0f]; } @@ -60,24 +69,23 @@ - (UIColor *)todayTextColor return [UIColor whiteColor]; } -- (UIColor *)secondTitleTextColor +- (UIColor *)subtitleTextColor { return [UIColor blackColor]; - } - (void)configureButton:(TSQCalendarDayButton *)button isSelected: (BOOL) selected; { button.titleLabel.font = [self dayOfMonthFont]; - button.secondTitleLabel.font = [self secondTitleFont]; + button.subtitleLabel.font = [self subtitleFont]; if (!selected) { - button.secondTitleLabel.textColor = [self secondTitleTextColor]; + button.subtitleLabel.textColor = [self subtitleTextColor]; } else { - button.secondTitleLabel.textColor = [UIColor whiteColor]; + button.subtitleLabel.textColor = [UIColor whiteColor]; } - button.secondTitleLabel.adjustsFontSizeToFitWidth = NO; - button.secondTitleLabel.lineBreakMode = NSLineBreakByTruncatingTail; + button.subtitleLabel.adjustsFontSizeToFitWidth = NO; + button.subtitleLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; button.titleLabel.shadowOffset = self.shadowOffset; button.adjustsImageWhenDisabled = NO; [button setTitleColor:self.textColor forState:UIControlStateNormal]; @@ -145,6 +153,112 @@ - (void)createSelectedButton; self.indexOfSelectedButton = -1; } +- (void)updateButton:(TSQCalendarDayButton *)button + buttonType:(CalendarButtonType)buttonType + forDate:(NSDate *)date +{ + UIColor *dateColor = nil; + UIColor *disabledDateColor = nil; + + + + // prefer the delegate date color over everything else; this will always be + // used if the delegate returns a color + + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:dateColorForDate:)]) + { + dateColor = [self.calendarView.delegate calendarView:self.calendarView dateColorForDate:date]; + } + + + + // prefer the delegate disabledDate color over everything else; this will + // always be used if the delegate returns a color (except for other month + // buttons) + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:disabledDateColorForDate:)]) + { + disabledDateColor = [self.calendarView.delegate calendarView:self.calendarView disabledDateColorForDate:date]; + } + + + + // if the delegate doesn't return a date color, fall back to some sane defaults, + // which can still be overridden in subclasses + if (! dateColor) + { + if (buttonType == CalendarButtonTypeToday) + { + dateColor = [self todayTextColor]; + } + else if (buttonType == CalendarButtonTypeSelected) + { + dateColor = [UIColor whiteColor]; + } + else if (buttonType == CalendarButtonTypeNormalDay) + { + dateColor = self.textColor; + } + else + { + dateColor = [self.textColor colorWithAlphaComponent:0.5f]; + } + } + + + + // if the delegate doesn't return a disabled date color, fall back to a sane + // default. Other month buttons will always get this disabled color. + if ((! disabledDateColor) || (buttonType == CalendarButtonTypeOtherMonth)) + { + disabledDateColor = [self.textColor colorWithAlphaComponent:0.5f]; + } + + [button setTitleColor:dateColor forState:UIControlStateNormal]; + [button setTitleColor:disabledDateColor forState:UIControlStateDisabled]; + + + + NSString *subtitle = nil; + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:subtitleForDate:)]) + { + subtitle = [self.calendarView.delegate calendarView:self.calendarView subtitleForDate:date]; + button.subtitleLabel.text = subtitle; + + UIColor *subtitleColor = nil; + + // only check the color if the delegate also responds to the subtitle + // delegate method. Prefer this subtitle color returned by the delegate, + // except for other month buttons. + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:subtitleColorForDate:)]) + { + subtitleColor = [self.calendarView.delegate calendarView:self.calendarView subtitleColorForDate:date]; + } + + // if the delegate doesn't return a subtitle color, fall back to sane + // defaults + if (! subtitleColor) + { + if (buttonType == CalendarButtonTypeSelected) + { + subtitleColor = [UIColor whiteColor]; + } + else + { + subtitleColor = [self subtitleTextColor]; + } + } + + // prefer a disabled color for other month buttons, even if the delegate + // returned a color + if (buttonType == CalendarButtonTypeOtherMonth) + { + subtitleColor = [self.textColor colorWithAlphaComponent:0.5f]; + } + + button.subtitleLabel.textColor = subtitleColor; + } +} + - (void)setBeginningDate:(NSDate *)date; { _beginningDate = date; @@ -167,45 +281,61 @@ - (void)setBeginningDate:(NSDate *)date; for (NSUInteger index = 0; index < self.daysInWeek; index++) { NSString *title = [self.dayFormatter stringFromDate:date]; NSString *accessibilityLabel = [self.accessibilityFormatter stringFromDate:date]; - [self.dayButtons[index] setTitle:title forState:UIControlStateNormal]; - [self.dayButtons[index] setTitle:title forState:UIControlStateDisabled]; - [self.dayButtons[index] setAccessibilityLabel:accessibilityLabel]; - [self.notThisMonthButtons[index] setTitle:title forState:UIControlStateNormal]; - [self.notThisMonthButtons[index] setTitle:title forState:UIControlStateDisabled]; - [self.notThisMonthButtons[index] setAccessibilityLabel:accessibilityLabel]; - - NSString *secondTitle = nil; - if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:secondTitleForDate:)]) { - secondTitle = [self.calendarView.delegate calendarView:self.calendarView secondTitleForDate:date]; - TSQCalendarDayButton *dayButton = self.dayButtons[index]; - TSQCalendarDayButton *notThisMonthButton = self.notThisMonthButtons[index]; - dayButton.secondTitleLabel.text = secondTitle; - notThisMonthButton.secondTitleLabel.text = secondTitle; - } + TSQCalendarDayButton *currentDayButton = self.dayButtons[index]; + TSQCalendarDayButton *currentNotThisMonthButton = self.notThisMonthButtons[index]; + [currentDayButton setTitle:title forState:UIControlStateNormal]; + [currentDayButton setTitle:title forState:UIControlStateDisabled]; + [currentDayButton setAccessibilityLabel:accessibilityLabel]; + [currentNotThisMonthButton setTitle:title forState:UIControlStateNormal]; + [currentNotThisMonthButton setTitle:title forState:UIControlStateDisabled]; + [currentNotThisMonthButton setAccessibilityLabel:accessibilityLabel]; NSDateComponents *thisDateComponents = [self.calendar components:NSCalendarUnitDay|NSCalendarUnitMonth|NSCalendarUnitYear fromDate:date]; - [self.dayButtons[index] setHidden:YES]; - [self.notThisMonthButtons[index] setHidden:YES]; + [currentDayButton setHidden:YES]; + [currentNotThisMonthButton setHidden:YES]; NSInteger thisDayMonth = thisDateComponents.month; - if (self.monthOfBeginningDate != thisDayMonth) { - [self.notThisMonthButtons[index] setHidden:NO]; - } else { - - if ([self.todayDateComponents isEqual:thisDateComponents]) { + if (self.monthOfBeginningDate != thisDayMonth) + { + [currentNotThisMonthButton setHidden:NO]; + } + else + { + BOOL buttonEnabled = YES; + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:shouldSelectDate:)]) + { + buttonEnabled = [self.calendarView.delegate calendarView:self.calendarView shouldSelectDate:date]; + } + + if ([self.todayDateComponents isEqual:thisDateComponents]) + { self.todayButton.hidden = NO; [self.todayButton setTitle:title forState:UIControlStateNormal]; [self.todayButton setAccessibilityLabel:accessibilityLabel]; self.indexOfTodayButton = index; - self.todayButton.secondTitleLabel.text = secondTitle; - } else { + self.todayButton.enabled = buttonEnabled; + + [self updateButton:self.todayButton + buttonType:CalendarButtonTypeToday + forDate:date]; + } + else + { UIButton *button = self.dayButtons[index]; - button.enabled = ![self.calendarView.delegate respondsToSelector:@selector(calendarView:shouldSelectDate:)] || [self.calendarView.delegate calendarView:self.calendarView shouldSelectDate:date]; + button.enabled = buttonEnabled; button.hidden = NO; } } + + [self updateButton:currentDayButton + buttonType:CalendarButtonTypeNormalDay + forDate:date]; + + [self updateButton:currentNotThisMonthButton + buttonType:CalendarButtonTypeOtherMonth + forDate:date]; date = [self.calendar dateByAddingComponents:offset toDate:date options:0]; } @@ -300,8 +430,8 @@ - (void)selectColumnForDate:(NSDate *)date; [self.selectedButton setTitle:newTitle forState:UIControlStateDisabled]; [self.selectedButton setAccessibilityLabel:[self.dayButtons[newIndexOfSelectedButton] accessibilityLabel]]; - if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:secondTitleForDate:)]) { - self.selectedButton.secondTitleLabel.text = [self.calendarView.delegate calendarView:self.calendarView secondTitleForDate:date]; + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:subtitleForDate:)]) { + self.selectedButton.subtitleLabel.text = [self.calendarView.delegate calendarView:self.calendarView subtitleForDate:date]; } } else { diff --git a/TimesSquare/TSQCalendarView.h b/TimesSquare/TSQCalendarView.h index 5dc2079..d8d0227 100644 --- a/TimesSquare/TSQCalendarView.h +++ b/TimesSquare/TSQCalendarView.h @@ -137,7 +137,13 @@ */ - (BOOL)calendarView:(TSQCalendarView *)calendarView shouldSelectDate:(NSDate *)date; -- (NSString*)calendarView: (TSQCalendarView *)calendarView secondTitleForDate: (NSDate*) date; +- (NSString*)calendarView: (TSQCalendarView *)calendarView subtitleForDate: (NSDate*) date; + +- (UIColor*)calendarView: (TSQCalendarView *)calendarView dateColorForDate: (NSDate*) date; + +- (UIColor*)calendarView: (TSQCalendarView *)calendarView disabledDateColorForDate: (NSDate*) date; + +- (UIColor*)calendarView: (TSQCalendarView *)calendarView subtitleColorForDate: (NSDate*) date; /** Tells the delegate that a particular date was selected. From b81c079ed8cec30e05990542bd8fe818b3ea1e4b Mon Sep 17 00:00:00 2001 From: Simone Manganelli Date: Mon, 28 Sep 2015 17:13:45 -0700 Subject: [PATCH 30/92] add a separate subtitle symbol label for the + so we can truncate the subtitle properly --- TimesSquare/TSQCalendarDayButton.h | 2 ++ TimesSquare/TSQCalendarDayButton.m | 5 ++++- TimesSquare/TSQCalendarRowCell.m | 25 +++++++++++++++++-------- TimesSquare/TSQCalendarView.h | 2 ++ 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/TimesSquare/TSQCalendarDayButton.h b/TimesSquare/TSQCalendarDayButton.h index e0d2961..ac3023d 100644 --- a/TimesSquare/TSQCalendarDayButton.h +++ b/TimesSquare/TSQCalendarDayButton.h @@ -11,4 +11,6 @@ @interface TSQCalendarDayButton : UIButton @property (nonatomic, strong) UILabel *subtitleLabel; +@property (nonatomic, strong) UILabel *subtitleSymbolLabel; + @end diff --git a/TimesSquare/TSQCalendarDayButton.m b/TimesSquare/TSQCalendarDayButton.m index 59e3089..ef36ec1 100644 --- a/TimesSquare/TSQCalendarDayButton.m +++ b/TimesSquare/TSQCalendarDayButton.m @@ -27,8 +27,11 @@ - (instancetype)initWithFrame:(CGRect)frame self.subtitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 50, 65, 18)]; self.subtitleLabel.textAlignment = NSTextAlignmentCenter; self.subtitleLabel.userInteractionEnabled = NO; - self.subtitleLabel.backgroundColor = [UIColor clearColor]; [self addSubview:self.subtitleLabel]; + + self.subtitleSymbolLabel = [[UILabel alloc] initWithFrame:CGRectMake(75, 50, 8, 18)]; + self.subtitleSymbolLabel.userInteractionEnabled = NO; + [self addSubview:self.subtitleSymbolLabel]; } return self; } diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index a0cb577..a6c3ef1 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -79,13 +79,16 @@ - (void)configureButton:(TSQCalendarDayButton *)button isSelected: (BOOL) select { button.titleLabel.font = [self dayOfMonthFont]; button.subtitleLabel.font = [self subtitleFont]; + button.subtitleSymbolLabel.font = [self subtitleFont]; if (!selected) { button.subtitleLabel.textColor = [self subtitleTextColor]; + button.subtitleSymbolLabel.textColor = [self subtitleTextColor]; } else { button.subtitleLabel.textColor = [UIColor whiteColor]; + button.subtitleSymbolLabel.textColor = [UIColor whiteColor]; } button.subtitleLabel.adjustsFontSizeToFitWidth = NO; - button.subtitleLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; + button.subtitleLabel.lineBreakMode = NSLineBreakByTruncatingTail; button.titleLabel.shadowOffset = self.shadowOffset; button.adjustsImageWhenDisabled = NO; [button setTitleColor:self.textColor forState:UIControlStateNormal]; @@ -218,10 +221,11 @@ - (void)updateButton:(TSQCalendarDayButton *)button - NSString *subtitle = nil; + button.subtitleLabel.text = nil; + button.subtitleSymbolLabel.text = nil; if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:subtitleForDate:)]) { - subtitle = [self.calendarView.delegate calendarView:self.calendarView subtitleForDate:date]; + NSString *subtitle = [self.calendarView.delegate calendarView:self.calendarView subtitleForDate:date]; button.subtitleLabel.text = subtitle; UIColor *subtitleColor = nil; @@ -256,6 +260,14 @@ - (void)updateButton:(TSQCalendarDayButton *)button } button.subtitleLabel.textColor = subtitleColor; + + + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:subtitleTrailingSymbolForDate:)]) + { + NSString *symbolString = [self.calendarView.delegate calendarView:self.calendarView subtitleTrailingSymbolForDate:date]; + button.subtitleSymbolLabel.text = symbolString; + button.subtitleSymbolLabel.textColor = subtitleColor; + } } } @@ -429,11 +441,8 @@ - (void)selectColumnForDate:(NSDate *)date; [self.selectedButton setTitle:newTitle forState:UIControlStateNormal]; [self.selectedButton setTitle:newTitle forState:UIControlStateDisabled]; [self.selectedButton setAccessibilityLabel:[self.dayButtons[newIndexOfSelectedButton] accessibilityLabel]]; - - if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:subtitleForDate:)]) { - self.selectedButton.subtitleLabel.text = [self.calendarView.delegate calendarView:self.calendarView subtitleForDate:date]; - } - + self.selectedButton.subtitleLabel.text = [self.dayButtons[newIndexOfSelectedButton] subtitleLabel].text; + self.selectedButton.subtitleSymbolLabel.text = [self.dayButtons[newIndexOfSelectedButton] subtitleSymbolLabel].text; } else { self.selectedButton.hidden = YES; } diff --git a/TimesSquare/TSQCalendarView.h b/TimesSquare/TSQCalendarView.h index d8d0227..1e0b953 100644 --- a/TimesSquare/TSQCalendarView.h +++ b/TimesSquare/TSQCalendarView.h @@ -139,6 +139,8 @@ - (NSString*)calendarView: (TSQCalendarView *)calendarView subtitleForDate: (NSDate*) date; +- (NSString*)calendarView: (TSQCalendarView *)calendarView subtitleTrailingSymbolForDate: (NSDate*) date; + - (UIColor*)calendarView: (TSQCalendarView *)calendarView dateColorForDate: (NSDate*) date; - (UIColor*)calendarView: (TSQCalendarView *)calendarView disabledDateColorForDate: (NSDate*) date; From a9aae18d88b64d95e69b7258a843b622c7f3b8e0 Mon Sep 17 00:00:00 2001 From: Simone Manganelli Date: Thu, 7 Jan 2016 20:26:40 -0800 Subject: [PATCH 31/92] fix an annoying warning --- TimesSquare/TSQCalendarView.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TimesSquare/TSQCalendarView.m b/TimesSquare/TSQCalendarView.m index 262b08a..4139258 100644 --- a/TimesSquare/TSQCalendarView.m +++ b/TimesSquare/TSQCalendarView.m @@ -307,7 +307,7 @@ - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger } static NSString *identifier = @"header"; - TSQCalendarMonthHeaderCell *cell = [tableView dequeueReusableHeaderFooterViewWithIdentifier:identifier]; + TSQCalendarMonthHeaderCell *cell = (TSQCalendarMonthHeaderCell *)[tableView dequeueReusableHeaderFooterViewWithIdentifier:identifier]; if (!cell) { cell = [self makeHeaderCellWithIdentifier:identifier]; cell.firstOfMonth = [self firstOfMonthForSection:section]; From 6c7df210ceb6601049c70be16c4fb39ae63903c7 Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Thu, 4 Feb 2016 13:59:58 -0800 Subject: [PATCH 32/92] expose all colors are overrideable --- TimesSquare/TSQCalendarRowCell.h | 11 ++++++ TimesSquare/TSQCalendarRowCell.m | 57 +++++++++++++++++++++++++++----- 2 files changed, 59 insertions(+), 9 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.h b/TimesSquare/TSQCalendarRowCell.h index 9427ca2..dc10828 100644 --- a/TimesSquare/TSQCalendarRowCell.h +++ b/TimesSquare/TSQCalendarRowCell.h @@ -32,9 +32,20 @@ This is white by default. */ @property (nonatomic, weak, readonly) UIColor *todayTextColor; +@property (nonatomic, weak, readonly) UIColor *todayTextShadowColor; +@property (nonatomic, weak, readonly) UIColor *todaySubtitleTextColor; +@property (nonatomic, weak, readonly) UIColor *textShadowColor; @property (nonatomic, weak, readonly) UIColor *subtitleTextColor; +/** The text color for a day that's selected + + This is white by default. + */ +@property (nonatomic, weak, readonly) UIColor *selectedTextColor; +@property (nonatomic, weak, readonly) UIColor *selectedTextShadowColor; +@property (nonatomic, weak, readonly) UIColor *selectedSubtitleTextColor; + /** @name Images */ /** The background image for the entire row. diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index a6c3ef1..6628755 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -54,6 +54,8 @@ - (id)initWithCalendar:(NSCalendar *)calendar reuseIdentifier:(NSString *)reuseI return self; } +#pragma mark - Fonts + - (UIFont *)dayOfMonthFont { return [UIFont boldSystemFontOfSize:19.0f]; @@ -64,6 +66,8 @@ - (UIFont *)subtitleFont return [UIFont boldSystemFontOfSize:12.0f]; } +#pragma mark - Colors + - (UIColor *)todayTextColor { return [UIColor whiteColor]; @@ -74,6 +78,37 @@ - (UIColor *)subtitleTextColor return [UIColor blackColor]; } +- (UIColor *)selectedTextColor +{ + return [UIColor whiteColor]; +} + +- (UIColor *)selectedSubtitleTextColor +{ + return [UIColor whiteColor]; +} + +- (UIColor *)textShadowColor +{ + return [UIColor whiteColor]; +} + +- (UIColor *)todayTextShadowColor +{ + return [UIColor colorWithWhite:0.0f alpha:0.75f]; +} + +- (UIColor *)selectedTextShadowColor +{ + return [UIColor colorWithWhite:0.0f alpha:0.75f]; +} + +- (UIColor *)todaySubtitleTextColor +{ + return [self subtitleTextColor]; +} + +#pragma mark - Buttons - (void)configureButton:(TSQCalendarDayButton *)button isSelected: (BOOL) selected; { @@ -84,15 +119,15 @@ - (void)configureButton:(TSQCalendarDayButton *)button isSelected: (BOOL) select button.subtitleLabel.textColor = [self subtitleTextColor]; button.subtitleSymbolLabel.textColor = [self subtitleTextColor]; } else { - button.subtitleLabel.textColor = [UIColor whiteColor]; - button.subtitleSymbolLabel.textColor = [UIColor whiteColor]; + button.subtitleLabel.textColor = [self selectedSubtitleTextColor]; + button.subtitleSymbolLabel.textColor = [self selectedSubtitleTextColor]; } button.subtitleLabel.adjustsFontSizeToFitWidth = NO; button.subtitleLabel.lineBreakMode = NSLineBreakByTruncatingTail; button.titleLabel.shadowOffset = self.shadowOffset; button.adjustsImageWhenDisabled = NO; [button setTitleColor:self.textColor forState:UIControlStateNormal]; - [button setTitleShadowColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [button setTitleShadowColor:[self textShadowColor] forState:UIControlStateNormal]; } @@ -136,7 +171,7 @@ - (void)createTodayButton; [self.todayButton setTitleColor:[self todayTextColor] forState:UIControlStateNormal]; [self.todayButton setBackgroundImage:[self todayBackgroundImage] forState:UIControlStateNormal]; - [self.todayButton setTitleShadowColor:[UIColor colorWithWhite:0.0f alpha:0.75f] forState:UIControlStateNormal]; + [self.todayButton setTitleShadowColor:[self todayTextShadowColor] forState:UIControlStateNormal]; self.todayButton.titleLabel.shadowOffset = CGSizeMake(0.0f, -1.0f / [UIScreen mainScreen].scale); } @@ -148,9 +183,9 @@ - (void)createSelectedButton; [self configureButton:self.selectedButton isSelected:YES]; [self.selectedButton setAccessibilityTraits:UIAccessibilityTraitSelected|self.selectedButton.accessibilityTraits]; self.selectedButton.enabled = NO; - [self.selectedButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [self.selectedButton setTitleColor:[self selectedTextColor] forState:UIControlStateNormal]; [self.selectedButton setBackgroundImage:[self selectedBackgroundImage] forState:UIControlStateNormal]; - [self.selectedButton setTitleShadowColor:[UIColor colorWithWhite:0.0f alpha:0.75f] forState:UIControlStateNormal]; + [self.selectedButton setTitleShadowColor:[self selectedTextShadowColor] forState:UIControlStateNormal]; self.selectedButton.titleLabel.shadowOffset = CGSizeMake(0.0f, -1.0f / [UIScreen mainScreen].scale); self.indexOfSelectedButton = -1; @@ -195,7 +230,7 @@ - (void)updateButton:(TSQCalendarDayButton *)button } else if (buttonType == CalendarButtonTypeSelected) { - dateColor = [UIColor whiteColor]; + dateColor = [self selectedTextColor]; } else if (buttonType == CalendarButtonTypeNormalDay) { @@ -242,9 +277,13 @@ - (void)updateButton:(TSQCalendarDayButton *)button // defaults if (! subtitleColor) { - if (buttonType == CalendarButtonTypeSelected) + if (buttonType == CalendarButtonTypeToday) + { + subtitleColor = [self todaySubtitleTextColor]; + } + else if (buttonType == CalendarButtonTypeSelected) { - subtitleColor = [UIColor whiteColor]; + subtitleColor = [self selectedSubtitleTextColor]; } else { From 4252d69242717dbb0a5149835383d959c5586d58 Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Thu, 4 Feb 2016 18:26:04 -0800 Subject: [PATCH 33/92] expose contentSize for calendar view --- TimesSquare/TSQCalendarView.h | 6 ++++++ TimesSquare/TSQCalendarView.m | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/TimesSquare/TSQCalendarView.h b/TimesSquare/TSQCalendarView.h index 1e0b953..2cd4dd0 100644 --- a/TimesSquare/TSQCalendarView.h +++ b/TimesSquare/TSQCalendarView.h @@ -83,6 +83,12 @@ */ @property (nonatomic) CGPoint contentOffset; +/** The size of the calendar content view + + This property is equivalent to the one defined on `UIScrollView`. + */ +@property (nonatomic) CGSize contentSize; + /** The cell class to use for month headers. Since there's very little configuration to be done for each cell, this can be set as a shortcut to implementing a data source. diff --git a/TimesSquare/TSQCalendarView.m b/TimesSquare/TSQCalendarView.m index 4139258..0cc9ec3 100644 --- a/TimesSquare/TSQCalendarView.m +++ b/TimesSquare/TSQCalendarView.m @@ -346,4 +346,9 @@ - (NSDate *)clampDate:(NSDate *)date toComponents:(NSUInteger)unitFlags return [self.calendar dateFromComponents:components]; } +- (CGSize)contentSize +{ + return self.tableView.contentSize; +} + @end From 771b74187de7f02ad83d537ee94b72dbb602e928 Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Thu, 4 Feb 2016 22:10:09 -0800 Subject: [PATCH 34/92] prevent nil from being passed into [NSCalendar components:fromDate:] --- TimesSquare/TSQCalendarView.m | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/TimesSquare/TSQCalendarView.m b/TimesSquare/TSQCalendarView.m index 0cc9ec3..a8f936f 100644 --- a/TimesSquare/TSQCalendarView.m +++ b/TimesSquare/TSQCalendarView.m @@ -342,6 +342,11 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView; - (NSDate *)clampDate:(NSDate *)date toComponents:(NSUInteger)unitFlags { + if (date == nil) { + // [__NSCFCalendar components:fromDate:]: date cannot be nil + return nil; + } + NSDateComponents *components = [self.calendar components:unitFlags fromDate:date]; return [self.calendar dateFromComponents:components]; } From 37f88bec9a05ea3e9e1866f5b65cb429e66f0e37 Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Fri, 5 Feb 2016 12:00:31 -0800 Subject: [PATCH 35/92] add button type property --- TimesSquare/TSQCalendarDayButton.h | 10 ++++++++++ TimesSquare/TSQCalendarDayButton.m | 3 +++ TimesSquare/TSQCalendarRowCell.m | 16 ++++------------ 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/TimesSquare/TSQCalendarDayButton.h b/TimesSquare/TSQCalendarDayButton.h index ac3023d..00971e3 100644 --- a/TimesSquare/TSQCalendarDayButton.h +++ b/TimesSquare/TSQCalendarDayButton.h @@ -8,8 +8,18 @@ #import +typedef NS_ENUM(NSInteger, CalendarButtonType) { + CalendarButtonTypeNormalDay = 0, + CalendarButtonTypeOtherMonth = 1, + CalendarButtonTypeToday = 2, + CalendarButtonTypeSelected = 3, + CalendarButtonTypeInitial = 4, +}; + @interface TSQCalendarDayButton : UIButton +@property (nonatomic, assign) CalendarButtonType type; + @property (nonatomic, strong) UILabel *subtitleLabel; @property (nonatomic, strong) UILabel *subtitleSymbolLabel; diff --git a/TimesSquare/TSQCalendarDayButton.m b/TimesSquare/TSQCalendarDayButton.m index ef36ec1..7618df8 100644 --- a/TimesSquare/TSQCalendarDayButton.m +++ b/TimesSquare/TSQCalendarDayButton.m @@ -23,6 +23,9 @@ - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { + // default button type to normal day + self.type = CalendarButtonTypeNormalDay; + [self setTitleEdgeInsets:UIEdgeInsetsMake(-10, 0, 0, 0)]; self.subtitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 50, 65, 18)]; self.subtitleLabel.textAlignment = NSTextAlignmentCenter; diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 6628755..fd6043b 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -11,15 +11,6 @@ #import "TSQCalendarView.h" #import "TSQCalendarDayButton.h" -typedef NS_ENUM(NSInteger, CalendarButtonType) { - CalendarButtonTypeNormalDay = 0, - CalendarButtonTypeOtherMonth = 1, - CalendarButtonTypeToday = 2, - CalendarButtonTypeSelected = 3 -}; - - - @interface TSQCalendarRowCell () @property (nonatomic, strong) NSArray *dayButtons; @@ -197,9 +188,10 @@ - (void)updateButton:(TSQCalendarDayButton *)button { UIColor *dateColor = nil; UIColor *disabledDateColor = nil; - - - + + // update button type + button.type = buttonType; + // prefer the delegate date color over everything else; this will always be // used if the delegate returns a color From 7631d70430ee57a4e7fd9184a6b9e172b427729f Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Fri, 5 Feb 2016 17:19:22 -0800 Subject: [PATCH 36/92] update to recommended project settings --- TimesSquare-iOS/Info.plist | 14 +++++++------- TimesSquare.xcodeproj/project.pbxproj | 5 ++++- .../xcschemes/TimesSquare Documentation.xcscheme | 13 ++++++++----- .../xcschemes/TimesSquare-iOS.xcscheme | 13 ++++++++----- .../xcshareddata/xcschemes/TimesSquare.xcscheme | 13 ++++++++----- 5 files changed, 35 insertions(+), 23 deletions(-) diff --git a/TimesSquare-iOS/Info.plist b/TimesSquare-iOS/Info.plist index 668cf6a..f8785d5 100644 --- a/TimesSquare-iOS/Info.plist +++ b/TimesSquare-iOS/Info.plist @@ -2,18 +2,12 @@ - UIAppFonts - - - - LSApplicationCategoryType - CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - com.square.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -26,7 +20,13 @@ ???? CFBundleVersion $(CURRENT_PROJECT_VERSION) + LSApplicationCategoryType + NSPrincipalClass + UIAppFonts + + + diff --git a/TimesSquare.xcodeproj/project.pbxproj b/TimesSquare.xcodeproj/project.pbxproj index 7b2e882..6e61b7b 100644 --- a/TimesSquare.xcodeproj/project.pbxproj +++ b/TimesSquare.xcodeproj/project.pbxproj @@ -275,7 +275,7 @@ A806805216700FD70071C71E /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0640; + LastUpgradeCheck = 0720; ORGANIZATIONNAME = Square; TargetAttributes = { 5C4733981AC3575B00269A66 = { @@ -374,6 +374,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.square.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = TimesSquare; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; @@ -414,6 +415,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = "com.square.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = TimesSquare; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; @@ -432,6 +434,7 @@ CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; diff --git a/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare Documentation.xcscheme b/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare Documentation.xcscheme index 9366e66..72565b6 100644 --- a/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare Documentation.xcscheme +++ b/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare Documentation.xcscheme @@ -1,6 +1,6 @@ + shouldUseLaunchSchemeArgsEnv = "YES"> + + + shouldUseLaunchSchemeArgsEnv = "YES"> @@ -62,15 +62,18 @@ ReferencedContainer = "container:TimesSquare.xcodeproj"> + + + shouldUseLaunchSchemeArgsEnv = "YES"> @@ -39,15 +39,18 @@ + + Date: Fri, 5 Feb 2016 19:15:47 -0800 Subject: [PATCH 37/92] make day button remember which day it is consolidate day button coloring introduce initial day colors add delegate method for shadow color remove today button (treat as normal day button) --- TimesSquare/TSQCalendarDayButton.h | 8 +- TimesSquare/TSQCalendarDayButton.m | 34 ++- TimesSquare/TSQCalendarRowCell.h | 14 ++ TimesSquare/TSQCalendarRowCell.m | 321 ++++++++++++++++------------- TimesSquare/TSQCalendarView.h | 11 + 5 files changed, 228 insertions(+), 160 deletions(-) diff --git a/TimesSquare/TSQCalendarDayButton.h b/TimesSquare/TSQCalendarDayButton.h index 00971e3..869d4e1 100644 --- a/TimesSquare/TSQCalendarDayButton.h +++ b/TimesSquare/TSQCalendarDayButton.h @@ -11,16 +11,18 @@ typedef NS_ENUM(NSInteger, CalendarButtonType) { CalendarButtonTypeNormalDay = 0, CalendarButtonTypeOtherMonth = 1, - CalendarButtonTypeToday = 2, - CalendarButtonTypeSelected = 3, - CalendarButtonTypeInitial = 4, + CalendarButtonTypeSelected = 2, }; @interface TSQCalendarDayButton : UIButton @property (nonatomic, assign) CalendarButtonType type; +@property (nonatomic, strong) NSDate *day; @property (nonatomic, strong) UILabel *subtitleLabel; @property (nonatomic, strong) UILabel *subtitleSymbolLabel; +- (BOOL)isForToday; +- (BOOL)isForDay:(NSDate *)date; + @end diff --git a/TimesSquare/TSQCalendarDayButton.m b/TimesSquare/TSQCalendarDayButton.m index 7618df8..28fc826 100644 --- a/TimesSquare/TSQCalendarDayButton.m +++ b/TimesSquare/TSQCalendarDayButton.m @@ -10,15 +10,6 @@ @implementation TSQCalendarDayButton - -/* -// Only override drawRect: if you perform custom drawing. -// An empty implementation adversely affects performance during animation. -- (void)drawRect:(CGRect)rect { - // Drawing code -} -*/ - - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; @@ -38,4 +29,29 @@ - (instancetype)initWithFrame:(CGRect)frame } return self; } + +- (BOOL)isForToday +{ + NSDate *today = [NSDate date]; + return [self isForDayIgnoringTime:today]; +} + +- (BOOL)isForDay:(NSDate *)day +{ + return [self isForDayIgnoringTime:day]; +} + +- (BOOL)isForDayIgnoringTime:(NSDate *)aDay +{ + if (aDay == nil || self.day == nil) { + return NO; + } + + NSDateComponents *components1 = [[NSCalendar currentCalendar] components:(NSCalendarUnitYear| NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:self.day]; + NSDateComponents *components2 = [[NSCalendar currentCalendar] components:(NSCalendarUnitYear| NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:aDay]; + return ((components1.year == components2.year) && + (components1.month == components2.month) && + (components1.day == components2.day)); +} + @end diff --git a/TimesSquare/TSQCalendarRowCell.h b/TimesSquare/TSQCalendarRowCell.h index dc10828..61f8dfc 100644 --- a/TimesSquare/TSQCalendarRowCell.h +++ b/TimesSquare/TSQCalendarRowCell.h @@ -46,6 +46,14 @@ This is white by default. @property (nonatomic, weak, readonly) UIColor *selectedTextShadowColor; @property (nonatomic, weak, readonly) UIColor *selectedSubtitleTextColor; +/** The text color for the initial day + + This uses the default text colors. + */ +@property (nonatomic, weak, readonly) UIColor *initialDayTextColor; +@property (nonatomic, weak, readonly) UIColor *initialDayTextShadowColor; +@property (nonatomic, weak, readonly) UIColor *initialDaySubtitleTextColor; + /** @name Images */ /** The background image for the entire row. @@ -68,6 +76,12 @@ This is white by default. */ @property (nonatomic, weak, readonly) UIImage *todayBackgroundImage; +/** The background image for the initial date. + + This is dark gray in the system's built-in Calendar app. You probably want to use a stretchable image. + */ +@property (nonatomic, weak, readonly) UIImage *initialDayBackgroundImage; + /** The background image for a day that's not this month. These are the trailing days from the previous month or the leading days from the following month. This can be `nil`. diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index fd6043b..f315fa0 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -15,16 +15,13 @@ @interface TSQCalendarRowCell () @property (nonatomic, strong) NSArray *dayButtons; @property (nonatomic, strong) NSArray *notThisMonthButtons; -@property (nonatomic, strong) TSQCalendarDayButton *todayButton; @property (nonatomic, strong) TSQCalendarDayButton *selectedButton; -@property (nonatomic, assign) NSInteger indexOfTodayButton; @property (nonatomic, assign) NSInteger indexOfSelectedButton; @property (nonatomic, strong) NSDateFormatter *dayFormatter; @property (nonatomic, strong) NSDateFormatter *accessibilityFormatter; -@property (nonatomic, strong) NSDateComponents *todayDateComponents; @property (nonatomic) NSInteger monthOfBeginningDate; @property (nonatomic, strong) UILabel *subtitleLabel; @@ -99,27 +96,34 @@ - (UIColor *)todaySubtitleTextColor return [self subtitleTextColor]; } +- (UIColor *)initialDayTextColor +{ + return [self textColor]; +} + +- (UIColor *)initialDayTextShadowColor +{ + return [self textShadowColor]; +} + +- (UIColor *)initialDaySubtitleTextColor +{ + return [self subtitleTextColor]; +} + #pragma mark - Buttons -- (void)configureButton:(TSQCalendarDayButton *)button isSelected: (BOOL) selected; +- (void)configureButton:(TSQCalendarDayButton *)button { + [self updateColorsForButton:button]; + button.titleLabel.font = [self dayOfMonthFont]; button.subtitleLabel.font = [self subtitleFont]; button.subtitleSymbolLabel.font = [self subtitleFont]; - if (!selected) { - button.subtitleLabel.textColor = [self subtitleTextColor]; - button.subtitleSymbolLabel.textColor = [self subtitleTextColor]; - } else { - button.subtitleLabel.textColor = [self selectedSubtitleTextColor]; - button.subtitleSymbolLabel.textColor = [self selectedSubtitleTextColor]; - } button.subtitleLabel.adjustsFontSizeToFitWidth = NO; button.subtitleLabel.lineBreakMode = NSLineBreakByTruncatingTail; button.titleLabel.shadowOffset = self.shadowOffset; button.adjustsImageWhenDisabled = NO; - [button setTitleColor:self.textColor forState:UIControlStateNormal]; - [button setTitleShadowColor:[self textShadowColor] forState:UIControlStateNormal]; - } - (void)createDayButtons; @@ -127,11 +131,11 @@ - (void)createDayButtons; NSMutableArray *dayButtons = [NSMutableArray arrayWithCapacity:self.daysInWeek]; for (NSUInteger index = 0; index < self.daysInWeek; index++) { TSQCalendarDayButton *button = [[TSQCalendarDayButton alloc] initWithFrame:self.contentView.bounds]; + button.type = CalendarButtonTypeNormalDay; [button addTarget:self action:@selector(dateButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; [dayButtons addObject:button]; [self.contentView addSubview:button]; - [self configureButton:button isSelected:NO]; - [button setTitleColor:[self.textColor colorWithAlphaComponent:0.5f] forState:UIControlStateDisabled]; + [self configureButton:button]; } self.dayButtons = dayButtons; } @@ -141,10 +145,10 @@ - (void)createNotThisMonthButtons; NSMutableArray *notThisMonthButtons = [NSMutableArray arrayWithCapacity:self.daysInWeek]; for (NSUInteger index = 0; index < self.daysInWeek; index++) { TSQCalendarDayButton *button = [[TSQCalendarDayButton alloc] initWithFrame:self.contentView.bounds]; + button.type = CalendarButtonTypeOtherMonth; [notThisMonthButtons addObject:button]; [self.contentView addSubview:button]; - [self configureButton:button isSelected: NO]; - [button setTitleColor:[self.textColor colorWithAlphaComponent:0.5f] forState:UIControlStateDisabled]; + [self configureButton:button]; button.enabled = NO; UIColor *backgroundPattern = [UIColor colorWithPatternImage:[self notThisMonthBackgroundImage]]; button.backgroundColor = backgroundPattern; @@ -152,45 +156,52 @@ - (void)createNotThisMonthButtons; self.notThisMonthButtons = notThisMonthButtons; } -- (void)createTodayButton; -{ - self.todayButton = [[TSQCalendarDayButton alloc] initWithFrame:self.contentView.bounds]; - - [self.contentView addSubview:self.todayButton]; - [self configureButton:self.todayButton isSelected:NO]; - [self.todayButton addTarget:self action:@selector(todayButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; - - [self.todayButton setTitleColor:[self todayTextColor] forState:UIControlStateNormal]; - [self.todayButton setBackgroundImage:[self todayBackgroundImage] forState:UIControlStateNormal]; - [self.todayButton setTitleShadowColor:[self todayTextShadowColor] forState:UIControlStateNormal]; - - self.todayButton.titleLabel.shadowOffset = CGSizeMake(0.0f, -1.0f / [UIScreen mainScreen].scale); -} - - (void)createSelectedButton; { - self.selectedButton = [[TSQCalendarDayButton alloc] initWithFrame:self.contentView.bounds]; - [self.contentView addSubview:self.selectedButton]; - [self configureButton:self.selectedButton isSelected:YES]; - [self.selectedButton setAccessibilityTraits:UIAccessibilityTraitSelected|self.selectedButton.accessibilityTraits]; - self.selectedButton.enabled = NO; - [self.selectedButton setTitleColor:[self selectedTextColor] forState:UIControlStateNormal]; - [self.selectedButton setBackgroundImage:[self selectedBackgroundImage] forState:UIControlStateNormal]; - [self.selectedButton setTitleShadowColor:[self selectedTextShadowColor] forState:UIControlStateNormal]; - - self.selectedButton.titleLabel.shadowOffset = CGSizeMake(0.0f, -1.0f / [UIScreen mainScreen].scale); + TSQCalendarDayButton *button = [[TSQCalendarDayButton alloc] initWithFrame:self.contentView.bounds]; + button.type = CalendarButtonTypeSelected; + [self.contentView addSubview:button]; + [self configureButton:button]; + [button setAccessibilityTraits:UIAccessibilityTraitSelected|button.accessibilityTraits]; + button.enabled = NO; + button.hidden = YES; self.indexOfSelectedButton = -1; + + self.selectedButton = button; } -- (void)updateButton:(TSQCalendarDayButton *)button - buttonType:(CalendarButtonType)buttonType - forDate:(NSDate *)date +- (void)updateColorsForButton:(TSQCalendarDayButton *)button { UIColor *dateColor = nil; UIColor *disabledDateColor = nil; + UIColor *dateShadowColor = nil; - // update button type - button.type = buttonType; + NSDate *date = button.day; + + // ** BACKGROUND IMAGE **/ + + UIImage *backgroundImage = nil; + switch (button.type) + { + case CalendarButtonTypeNormalDay: + if ([button isForDay:self.calendarView.initialDate]) { + backgroundImage = [self initialDayBackgroundImage]; + } else if ([button isForToday]) { + backgroundImage = [self todayBackgroundImage]; + } + break; + + case CalendarButtonTypeOtherMonth: + break; + + case CalendarButtonTypeSelected: + backgroundImage = [self selectedBackgroundImage]; + break; + } + + [button setBackgroundImage:backgroundImage forState:UIControlStateNormal]; + + // ** DATE COLOR **/ // prefer the delegate date color over everything else; this will always be // used if the delegate returns a color @@ -200,8 +211,34 @@ - (void)updateButton:(TSQCalendarDayButton *)button dateColor = [self.calendarView.delegate calendarView:self.calendarView dateColorForDate:date]; } - - + // if the delegate doesn't return a date color, fall back to some sane defaults, + // which can still be overridden in subclasses + if (! dateColor) + { + switch (button.type) + { + case CalendarButtonTypeNormalDay: + if ([button isForToday]) { + dateColor = [self todayTextColor]; + } else if ([button isForDay:self.calendarView.initialDate]) { + dateColor = [self initialDayTextColor]; + } else { + dateColor = self.textColor; + } + break; + + case CalendarButtonTypeOtherMonth: + dateColor = [self.textColor colorWithAlphaComponent:0.5f]; + break; + + case CalendarButtonTypeSelected: + dateColor = [self selectedTextColor]; + break; + } + } + + // ** DISABLED DATE COLOR **/ + // prefer the delegate disabledDate color over everything else; this will // always be used if the delegate returns a color (except for other month // buttons) @@ -210,44 +247,54 @@ - (void)updateButton:(TSQCalendarDayButton *)button disabledDateColor = [self.calendarView.delegate calendarView:self.calendarView disabledDateColorForDate:date]; } - - - // if the delegate doesn't return a date color, fall back to some sane defaults, - // which can still be overridden in subclasses - if (! dateColor) - { - if (buttonType == CalendarButtonTypeToday) - { - dateColor = [self todayTextColor]; - } - else if (buttonType == CalendarButtonTypeSelected) - { - dateColor = [self selectedTextColor]; - } - else if (buttonType == CalendarButtonTypeNormalDay) - { - dateColor = self.textColor; - } - else - { - dateColor = [self.textColor colorWithAlphaComponent:0.5f]; - } - } - - - // if the delegate doesn't return a disabled date color, fall back to a sane // default. Other month buttons will always get this disabled color. - if ((! disabledDateColor) || (buttonType == CalendarButtonTypeOtherMonth)) + if ((! disabledDateColor) || (button.type == CalendarButtonTypeOtherMonth)) { disabledDateColor = [self.textColor colorWithAlphaComponent:0.5f]; } - + + // ** DATE SHADOW COLOR **/ + + // prefer the delegate date shadow color over everything else; this will + // always be used if the delegate returns a color + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:dateShadowColorForDate:)]) + { + dateShadowColor = [self.calendarView.delegate calendarView:self.calendarView dateShadowColorForDate:date]; + } + + if (! dateShadowColor) + { + switch (button.type) + { + case CalendarButtonTypeNormalDay: + if ([button isForToday]) { + dateShadowColor = [self todayTextShadowColor]; + } else if ([button isForDay:self.calendarView.initialDate]) { + dateShadowColor = [self initialDayTextShadowColor]; + } else if (button.type == CalendarButtonTypeNormalDay) { + dateShadowColor = [self textShadowColor]; + } + break; + + case CalendarButtonTypeOtherMonth: + break; + + case CalendarButtonTypeSelected: + dateShadowColor = [self selectedTextShadowColor]; + break; + } + } + [button setTitleColor:dateColor forState:UIControlStateNormal]; [button setTitleColor:disabledDateColor forState:UIControlStateDisabled]; - - - + button.titleLabel.shadowColor = dateShadowColor; +} + +- (void)updateSubtitlesForButton:(TSQCalendarDayButton *)button +{ + NSDate *date = button.day; + button.subtitleLabel.text = nil; button.subtitleSymbolLabel.text = nil; if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:subtitleForDate:)]) @@ -269,23 +316,30 @@ - (void)updateButton:(TSQCalendarDayButton *)button // defaults if (! subtitleColor) { - if (buttonType == CalendarButtonTypeToday) - { - subtitleColor = [self todaySubtitleTextColor]; - } - else if (buttonType == CalendarButtonTypeSelected) + switch (button.type) { - subtitleColor = [self selectedSubtitleTextColor]; - } - else - { - subtitleColor = [self subtitleTextColor]; + case CalendarButtonTypeNormalDay: + if ([button isForToday]) { + subtitleColor = [self todaySubtitleTextColor]; + } else if ([button isForDay:self.calendarView.initialDate]) { + subtitleColor = [self initialDaySubtitleTextColor]; + } else { + subtitleColor = [self subtitleTextColor]; + } + break; + + case CalendarButtonTypeOtherMonth: + break; + + case CalendarButtonTypeSelected: + subtitleColor = [self selectedSubtitleTextColor]; + break; } } // prefer a disabled color for other month buttons, even if the delegate // returned a color - if (buttonType == CalendarButtonTypeOtherMonth) + if (button.type == CalendarButtonTypeOtherMonth) { subtitleColor = [self.textColor colorWithAlphaComponent:0.5f]; } @@ -309,24 +363,20 @@ - (void)setBeginningDate:(NSDate *)date; if (!self.dayButtons) { [self createDayButtons]; [self createNotThisMonthButtons]; - [self createTodayButton]; [self createSelectedButton]; } NSDateComponents *offset = [NSDateComponents new]; offset.day = 1; - self.todayButton.hidden = YES; - self.indexOfTodayButton = -1; - self.selectedButton.hidden = YES; - self.indexOfSelectedButton = -1; - for (NSUInteger index = 0; index < self.daysInWeek; index++) { NSString *title = [self.dayFormatter stringFromDate:date]; NSString *accessibilityLabel = [self.accessibilityFormatter stringFromDate:date]; TSQCalendarDayButton *currentDayButton = self.dayButtons[index]; TSQCalendarDayButton *currentNotThisMonthButton = self.notThisMonthButtons[index]; + currentDayButton.day = date; + currentNotThisMonthButton.day = date; [currentDayButton setTitle:title forState:UIControlStateNormal]; [currentDayButton setTitle:title forState:UIControlStateDisabled]; [currentDayButton setAccessibilityLabel:accessibilityLabel]; @@ -352,33 +402,18 @@ - (void)setBeginningDate:(NSDate *)date; buttonEnabled = [self.calendarView.delegate calendarView:self.calendarView shouldSelectDate:date]; } - if ([self.todayDateComponents isEqual:thisDateComponents]) - { - self.todayButton.hidden = NO; - [self.todayButton setTitle:title forState:UIControlStateNormal]; - [self.todayButton setAccessibilityLabel:accessibilityLabel]; - self.indexOfTodayButton = index; - self.todayButton.enabled = buttonEnabled; - - [self updateButton:self.todayButton - buttonType:CalendarButtonTypeToday - forDate:date]; - } - else - { - UIButton *button = self.dayButtons[index]; - button.enabled = buttonEnabled; - button.hidden = NO; - } + UIButton *button = self.dayButtons[index]; + button.enabled = buttonEnabled; + button.hidden = NO; } - - [self updateButton:currentDayButton - buttonType:CalendarButtonTypeNormalDay - forDate:date]; - - [self updateButton:currentNotThisMonthButton - buttonType:CalendarButtonTypeOtherMonth - forDate:date]; + + // update button colors + [self updateColorsForButton:currentDayButton]; + [self updateColorsForButton:currentNotThisMonthButton]; + + // update button subtitles + [self updateSubtitlesForButton:currentDayButton]; + [self updateSubtitlesForButton:currentNotThisMonthButton]; date = [self.calendar dateByAddingComponents:offset toDate:date options:0]; } @@ -406,14 +441,6 @@ - (IBAction)dateButtonPressed:(id)sender; self.calendarView.selectedDate = selectedDate; } -- (IBAction)todayButtonPressed:(id)sender; -{ - NSDateComponents *offset = [NSDateComponents new]; - offset.day = self.indexOfTodayButton; - NSDate *selectedDate = [self.calendar dateByAddingComponents:offset toDate:self.beginningDate options:0]; - self.calendarView.selectedDate = selectedDate; -} - - (void)layoutSubviews; { if (!self.backgroundView) { @@ -439,9 +466,6 @@ - (void)layoutViewsForColumnAtIndex:(NSUInteger)index inRect:(CGRect)rect; dayButton.frame = rect; notThisMonthButton.frame = rect; - if (self.indexOfTodayButton == (NSInteger)index) { - self.todayButton.frame = rect; - } if (self.indexOfSelectedButton == (NSInteger)index) { self.selectedButton.frame = rect; } @@ -467,17 +491,26 @@ - (void)selectColumnForDate:(NSDate *)date; self.indexOfSelectedButton = newIndexOfSelectedButton; if (newIndexOfSelectedButton >= 0) { + // update selected button colors + TSQCalendarDayButton *dayButton = self.dayButtons[newIndexOfSelectedButton]; + self.selectedButton.day = dayButton.day; + [self updateColorsForButton:self.selectedButton]; + [self updateSubtitlesForButton:self.selectedButton]; + + // update selected button text self.selectedButton.hidden = NO; - NSString *newTitle = [self.dayButtons[newIndexOfSelectedButton] currentTitle]; + self.selectedButton.enabled = YES; + NSString *newTitle = [dayButton currentTitle]; [self.selectedButton setTitle:newTitle forState:UIControlStateNormal]; [self.selectedButton setTitle:newTitle forState:UIControlStateDisabled]; - [self.selectedButton setAccessibilityLabel:[self.dayButtons[newIndexOfSelectedButton] accessibilityLabel]]; - self.selectedButton.subtitleLabel.text = [self.dayButtons[newIndexOfSelectedButton] subtitleLabel].text; - self.selectedButton.subtitleSymbolLabel.text = [self.dayButtons[newIndexOfSelectedButton] subtitleSymbolLabel].text; + [self.selectedButton setAccessibilityLabel:[dayButton accessibilityLabel]]; + self.selectedButton.subtitleLabel.text = [dayButton subtitleLabel].text; + self.selectedButton.subtitleSymbolLabel.text = [dayButton subtitleSymbolLabel].text; } else { self.selectedButton.hidden = YES; + self.selectedButton.enabled = NO; } - + [self setNeedsLayout]; } @@ -515,12 +548,4 @@ - (void)setFirstOfMonth:(NSDate *)firstOfMonth; self.monthOfBeginningDate = 0; } -- (NSDateComponents *)todayDateComponents; -{ - if (!_todayDateComponents) { - self.todayDateComponents = [self.calendar components:NSCalendarUnitDay|NSCalendarUnitMonth|NSCalendarUnitYear fromDate:[NSDate date]]; - } - return _todayDateComponents; -} - @end diff --git a/TimesSquare/TSQCalendarView.h b/TimesSquare/TSQCalendarView.h index 2cd4dd0..002236f 100644 --- a/TimesSquare/TSQCalendarView.h +++ b/TimesSquare/TSQCalendarView.h @@ -42,6 +42,15 @@ */ @property (nonatomic, strong) NSDate *selectedDate; + +/** The initial date to be highlighted on the calendar. + + Set this property to any `NSDate`; `TSQCalendarView` will only look at the month, day, and year. + You can read and write this property + */ + +@property (nonatomic, strong) NSDate *initialDate; + /** @name Calendar Configuration */ /** The calendar type to use when displaying. @@ -149,6 +158,8 @@ - (UIColor*)calendarView: (TSQCalendarView *)calendarView dateColorForDate: (NSDate*) date; +- (UIColor*)calendarView: (TSQCalendarView *)calendarView dateShadowColorForDate: (NSDate*) date; + - (UIColor*)calendarView: (TSQCalendarView *)calendarView disabledDateColorForDate: (NSDate*) date; - (UIColor*)calendarView: (TSQCalendarView *)calendarView subtitleColorForDate: (NSDate*) date; From f5420da77436d0ba87c169c78fe0b6ce6fde838d Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Sat, 6 Feb 2016 00:57:05 -0600 Subject: [PATCH 38/92] no need to update background image every update --- TimesSquare/TSQCalendarRowCell.m | 33 ++++++++++---------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index f315fa0..e0a9fb8 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -162,6 +162,7 @@ - (void)createSelectedButton; button.type = CalendarButtonTypeSelected; [self.contentView addSubview:button]; [self configureButton:button]; + [button setBackgroundImage:[self selectedBackgroundImage] forState:UIControlStateNormal]; [button setAccessibilityTraits:UIAccessibilityTraitSelected|button.accessibilityTraits]; button.enabled = NO; button.hidden = YES; @@ -178,29 +179,6 @@ - (void)updateColorsForButton:(TSQCalendarDayButton *)button NSDate *date = button.day; - // ** BACKGROUND IMAGE **/ - - UIImage *backgroundImage = nil; - switch (button.type) - { - case CalendarButtonTypeNormalDay: - if ([button isForDay:self.calendarView.initialDate]) { - backgroundImage = [self initialDayBackgroundImage]; - } else if ([button isForToday]) { - backgroundImage = [self todayBackgroundImage]; - } - break; - - case CalendarButtonTypeOtherMonth: - break; - - case CalendarButtonTypeSelected: - backgroundImage = [self selectedBackgroundImage]; - break; - } - - [button setBackgroundImage:backgroundImage forState:UIControlStateNormal]; - // ** DATE COLOR **/ // prefer the delegate date color over everything else; this will always be @@ -407,6 +385,15 @@ - (void)setBeginningDate:(NSDate *)date; button.hidden = NO; } + // update background image + UIImage *backgroundImage = nil; + if ([currentDayButton isForDay:self.calendarView.initialDate]) { + backgroundImage = [self initialDayBackgroundImage]; + } else if ([currentDayButton isForToday]) { + backgroundImage = [self todayBackgroundImage]; + } + [currentDayButton setBackgroundImage:backgroundImage forState:UIControlStateNormal]; + // update button colors [self updateColorsForButton:currentDayButton]; [self updateColorsForButton:currentNotThisMonthButton]; From bb66e0b1a14dc68ad09cd897c488604a00a21395 Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Sat, 6 Feb 2016 01:14:37 -0600 Subject: [PATCH 39/92] allow user to disable scrolling on the calendar view --- TimesSquare/TSQCalendarView.h | 4 ++++ TimesSquare/TSQCalendarView.m | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/TimesSquare/TSQCalendarView.h b/TimesSquare/TSQCalendarView.h index 002236f..4ab3862 100644 --- a/TimesSquare/TSQCalendarView.h +++ b/TimesSquare/TSQCalendarView.h @@ -115,6 +115,10 @@ // Return all(?) shift notes @property (nonatomic, readonly) NSArray *shiftNotes; +// Returns and modifies the scrollEnabled on the table view + +@property (nonatomic) BOOL scrollEnabled; + /** Scrolls the receiver until the specified date month is completely visible. @param date A date that identifies the month that will be visible. diff --git a/TimesSquare/TSQCalendarView.m b/TimesSquare/TSQCalendarView.m index a8f936f..2d96f15 100644 --- a/TimesSquare/TSQCalendarView.m +++ b/TimesSquare/TSQCalendarView.m @@ -152,6 +152,16 @@ - (void)setSelectedDate:(NSDate *)newSelectedDate; } } +- (BOOL)scrollEnabled +{ + return self.tableView.scrollEnabled; +} + +- (void)setScrollEnabled:(BOOL)scrollEnabled +{ + self.tableView.scrollEnabled = scrollEnabled; +} + - (void)scrollToDate:(NSDate *)date animated:(BOOL)animated { NSInteger section = [self sectionForDate:date]; From 1b31be14f1640e24e90963589d76b7818afe582c Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Mon, 8 Feb 2016 10:49:14 -0600 Subject: [PATCH 40/92] internalize subtitle labels on day button --- TimesSquare/TSQCalendarDayButton.h | 7 ++-- TimesSquare/TSQCalendarDayButton.m | 60 ++++++++++++++++++++++++++++++ TimesSquare/TSQCalendarRowCell.m | 33 +++++++--------- 3 files changed, 78 insertions(+), 22 deletions(-) diff --git a/TimesSquare/TSQCalendarDayButton.h b/TimesSquare/TSQCalendarDayButton.h index 869d4e1..1f57112 100644 --- a/TimesSquare/TSQCalendarDayButton.h +++ b/TimesSquare/TSQCalendarDayButton.h @@ -18,9 +18,10 @@ typedef NS_ENUM(NSInteger, CalendarButtonType) { @property (nonatomic, assign) CalendarButtonType type; @property (nonatomic, strong) NSDate *day; - -@property (nonatomic, strong) UILabel *subtitleLabel; -@property (nonatomic, strong) UILabel *subtitleSymbolLabel; +@property (nonatomic, readwrite) NSString *subtitle; +@property (nonatomic, readwrite) NSString *subtitleSymbol; +@property (nonatomic, readwrite) UIFont *subtitleFont; +@property (nonatomic, readwrite) UIColor *subtitleColor; - (BOOL)isForToday; - (BOOL)isForDay:(NSDate *)date; diff --git a/TimesSquare/TSQCalendarDayButton.m b/TimesSquare/TSQCalendarDayButton.m index 28fc826..fb19529 100644 --- a/TimesSquare/TSQCalendarDayButton.m +++ b/TimesSquare/TSQCalendarDayButton.m @@ -8,6 +8,13 @@ #import "TSQCalendarDayButton.h" +@interface TSQCalendarDayButton () + +@property (nonatomic, strong) UILabel *subtitleLabel; +@property (nonatomic, strong) UILabel *subtitleSymbolLabel; + +@end + @implementation TSQCalendarDayButton - (instancetype)initWithFrame:(CGRect)frame @@ -21,6 +28,8 @@ - (instancetype)initWithFrame:(CGRect)frame self.subtitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 50, 65, 18)]; self.subtitleLabel.textAlignment = NSTextAlignmentCenter; self.subtitleLabel.userInteractionEnabled = NO; + self.subtitleLabel.adjustsFontSizeToFitWidth = NO; + self.subtitleLabel.lineBreakMode = NSLineBreakByTruncatingTail; [self addSubview:self.subtitleLabel]; self.subtitleSymbolLabel = [[UILabel alloc] initWithFrame:CGRectMake(75, 50, 8, 18)]; @@ -30,6 +39,57 @@ - (instancetype)initWithFrame:(CGRect)frame return self; } +- (NSString *)subtitle +{ + return self.subtitleLabel.text; +} + +- (void)setSubtitle:(NSString *)subtitle; +{ + if (![self.subtitleLabel.text isEqualToString:subtitle]) + { + self.subtitleLabel.text = subtitle; + } +} + +- (NSString *)subtitleSymbol +{ + return self.subtitleSymbolLabel.text; +} + +- (void)setSubtitleSymbol:(NSString *)subtitleSymbol +{ + if (![self.subtitleSymbolLabel.text isEqualToString:subtitleSymbol]) + { + self.subtitleSymbolLabel.text = subtitleSymbol; + } +} + +- (UIFont *)subtitleFont +{ + return self.subtitleLabel.font; +} + +- (void)updateSubtitleFont:(UIFont *)subtitleFont +{ + if (![self.subtitleFont isEqual:subtitleFont]) + { + self.subtitleLabel.font = subtitleFont; + self.subtitleSymbolLabel.font = subtitleFont; + } +} + +- (UIColor *)subtitleColor +{ + return self.subtitleLabel.textColor; +} + +- (void)setSubtitleColor:(UIColor *)subtitleColor +{ + self.subtitleLabel.textColor = subtitleColor; + self.subtitleSymbolLabel.textColor = subtitleColor; +} + - (BOOL)isForToday { NSDate *today = [NSDate date]; diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index e0a9fb8..92d9474 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -24,7 +24,6 @@ @interface TSQCalendarRowCell () @property (nonatomic) NSInteger monthOfBeginningDate; -@property (nonatomic, strong) UILabel *subtitleLabel; @property (nonatomic, strong) NSArray *shiftNotes; @end @@ -118,10 +117,7 @@ - (void)configureButton:(TSQCalendarDayButton *)button [self updateColorsForButton:button]; button.titleLabel.font = [self dayOfMonthFont]; - button.subtitleLabel.font = [self subtitleFont]; - button.subtitleSymbolLabel.font = [self subtitleFont]; - button.subtitleLabel.adjustsFontSizeToFitWidth = NO; - button.subtitleLabel.lineBreakMode = NSLineBreakByTruncatingTail; + button.subtitleFont = [self subtitleFont]; button.titleLabel.shadowOffset = self.shadowOffset; button.adjustsImageWhenDisabled = NO; } @@ -273,14 +269,14 @@ - (void)updateSubtitlesForButton:(TSQCalendarDayButton *)button { NSDate *date = button.day; - button.subtitleLabel.text = nil; - button.subtitleSymbolLabel.text = nil; + NSString *subtitle = nil; + NSString *subtitleSymbol = nil; + UIColor *subtitleColor = nil; + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:subtitleForDate:)]) { NSString *subtitle = [self.calendarView.delegate calendarView:self.calendarView subtitleForDate:date]; - button.subtitleLabel.text = subtitle; - - UIColor *subtitleColor = nil; + subtitle = subtitle; // only check the color if the delegate also responds to the subtitle // delegate method. Prefer this subtitle color returned by the delegate, @@ -321,17 +317,16 @@ - (void)updateSubtitlesForButton:(TSQCalendarDayButton *)button { subtitleColor = [self.textColor colorWithAlphaComponent:0.5f]; } - - button.subtitleLabel.textColor = subtitleColor; - - + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:subtitleTrailingSymbolForDate:)]) { - NSString *symbolString = [self.calendarView.delegate calendarView:self.calendarView subtitleTrailingSymbolForDate:date]; - button.subtitleSymbolLabel.text = symbolString; - button.subtitleSymbolLabel.textColor = subtitleColor; + subtitleSymbol = [self.calendarView.delegate calendarView:self.calendarView subtitleTrailingSymbolForDate:date]; } } + + button.subtitle = subtitle; + button.subtitleSymbol = subtitleSymbol; + button.subtitleColor = subtitleColor; } - (void)setBeginningDate:(NSDate *)date; @@ -491,8 +486,8 @@ - (void)selectColumnForDate:(NSDate *)date; [self.selectedButton setTitle:newTitle forState:UIControlStateNormal]; [self.selectedButton setTitle:newTitle forState:UIControlStateDisabled]; [self.selectedButton setAccessibilityLabel:[dayButton accessibilityLabel]]; - self.selectedButton.subtitleLabel.text = [dayButton subtitleLabel].text; - self.selectedButton.subtitleSymbolLabel.text = [dayButton subtitleSymbolLabel].text; + self.selectedButton.subtitle = dayButton.subtitle; + self.selectedButton.subtitleSymbol = dayButton.subtitleSymbol; } else { self.selectedButton.hidden = YES; self.selectedButton.enabled = NO; From df490447d32ed21eb2baf2172955d45a863262b6 Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Mon, 8 Feb 2016 13:19:38 -0600 Subject: [PATCH 41/92] add ability to specify today icon --- TimesSquare/TSQCalendarDayButton.h | 1 + TimesSquare/TSQCalendarDayButton.m | 50 ++++++++++++++++++++++++++++++ TimesSquare/TSQCalendarRowCell.h | 4 +++ TimesSquare/TSQCalendarRowCell.m | 9 ++++++ 4 files changed, 64 insertions(+) diff --git a/TimesSquare/TSQCalendarDayButton.h b/TimesSquare/TSQCalendarDayButton.h index 1f57112..cfd0d96 100644 --- a/TimesSquare/TSQCalendarDayButton.h +++ b/TimesSquare/TSQCalendarDayButton.h @@ -22,6 +22,7 @@ typedef NS_ENUM(NSInteger, CalendarButtonType) { @property (nonatomic, readwrite) NSString *subtitleSymbol; @property (nonatomic, readwrite) UIFont *subtitleFont; @property (nonatomic, readwrite) UIColor *subtitleColor; +@property (nonatomic, readwrite) UIImage *icon; - (BOOL)isForToday; - (BOOL)isForDay:(NSDate *)date; diff --git a/TimesSquare/TSQCalendarDayButton.m b/TimesSquare/TSQCalendarDayButton.m index fb19529..822e7a4 100644 --- a/TimesSquare/TSQCalendarDayButton.m +++ b/TimesSquare/TSQCalendarDayButton.m @@ -13,6 +13,8 @@ @interface TSQCalendarDayButton () @property (nonatomic, strong) UILabel *subtitleLabel; @property (nonatomic, strong) UILabel *subtitleSymbolLabel; +@property (nonatomic, strong) UIImageView *iconImageView; + @end @implementation TSQCalendarDayButton @@ -35,6 +37,10 @@ - (instancetype)initWithFrame:(CGRect)frame self.subtitleSymbolLabel = [[UILabel alloc] initWithFrame:CGRectMake(75, 50, 8, 18)]; self.subtitleSymbolLabel.userInteractionEnabled = NO; [self addSubview:self.subtitleSymbolLabel]; + + self.iconImageView = [[UIImageView alloc] initWithFrame:CGRectZero]; + self.iconImageView.userInteractionEnabled = NO; + [self addSubview:self.iconImageView]; } return self; } @@ -49,6 +55,7 @@ - (void)setSubtitle:(NSString *)subtitle; if (![self.subtitleLabel.text isEqualToString:subtitle]) { self.subtitleLabel.text = subtitle; + [self layoutSubviews]; } } @@ -62,6 +69,7 @@ - (void)setSubtitleSymbol:(NSString *)subtitleSymbol if (![self.subtitleSymbolLabel.text isEqualToString:subtitleSymbol]) { self.subtitleSymbolLabel.text = subtitleSymbol; + [self layoutSubviews]; } } @@ -76,6 +84,7 @@ - (void)updateSubtitleFont:(UIFont *)subtitleFont { self.subtitleLabel.font = subtitleFont; self.subtitleSymbolLabel.font = subtitleFont; + [self layoutSubviews]; } } @@ -90,6 +99,47 @@ - (void)setSubtitleColor:(UIColor *)subtitleColor self.subtitleSymbolLabel.textColor = subtitleColor; } +- (UIImage *)icon +{ + return self.iconImageView.image; +} + +- (void)setIcon:(UIImage *)icon +{ + if (![self.iconImageView.image isEqual:icon]) + { + self.iconImageView.image = icon; + [self layoutSubviews]; + } +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + CGFloat subtitleCenterY = 0.75f * CGRectGetMaxY(self.bounds); + self.iconImageView.hidden = (self.iconImageView.image == nil); + if (! self.iconImageView.hidden) + { + self.iconImageView.hidden = NO; + + CGFloat iconWidth = self.iconImageView.image.size.width; + CGFloat iconHeight = self.iconImageView.image.size.height; + + CGFloat midX = CGRectGetMidX(self.bounds); + + CGFloat originX = midX - iconWidth/2.0f; + CGFloat originY = subtitleCenterY - iconHeight/2.0f; + + self.iconImageView.frame = CGRectMake(originX, + originY, + iconWidth, + iconHeight); + +#warning need to layout icon differently if subtitle is displayed + } +} + - (BOOL)isForToday { NSDate *today = [NSDate date]; diff --git a/TimesSquare/TSQCalendarRowCell.h b/TimesSquare/TSQCalendarRowCell.h index 61f8dfc..8d500e4 100644 --- a/TimesSquare/TSQCalendarRowCell.h +++ b/TimesSquare/TSQCalendarRowCell.h @@ -88,6 +88,10 @@ This is white by default. */ @property (nonatomic, weak, readonly) UIImage *notThisMonthBackgroundImage; +/** A small icon that appears below the day number to indicate today */ + +@property (nonatomic, weak, readonly) UIImage *todayIcon; + /** @name State Properties Set by Calendar View */ /** The date at the beginning of the week for this cell. diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 92d9474..e2b9fad 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -263,6 +263,15 @@ - (void)updateColorsForButton:(TSQCalendarDayButton *)button [button setTitleColor:dateColor forState:UIControlStateNormal]; [button setTitleColor:disabledDateColor forState:UIControlStateDisabled]; button.titleLabel.shadowColor = dateShadowColor; + + // ** ICON **/ + + UIImage *icon = nil; + if ([button isForToday]) { + icon = [self todayIcon]; + } + // can extend later to support other icons + button.icon = icon; } - (void)updateSubtitlesForButton:(TSQCalendarDayButton *)button From 8cfe5624eebe30db202d930676fd6cfb6b127472 Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Mon, 8 Feb 2016 13:21:11 -0800 Subject: [PATCH 42/92] fix a couple subtitle issues --- TimesSquare/TSQCalendarDayButton.m | 2 +- TimesSquare/TSQCalendarRowCell.m | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/TimesSquare/TSQCalendarDayButton.m b/TimesSquare/TSQCalendarDayButton.m index 822e7a4..4b7e1cd 100644 --- a/TimesSquare/TSQCalendarDayButton.m +++ b/TimesSquare/TSQCalendarDayButton.m @@ -78,7 +78,7 @@ - (UIFont *)subtitleFont return self.subtitleLabel.font; } -- (void)updateSubtitleFont:(UIFont *)subtitleFont +- (void)setSubtitleFont:(UIFont *)subtitleFont { if (![self.subtitleFont isEqual:subtitleFont]) { diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index e2b9fad..93dd2b3 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -284,9 +284,8 @@ - (void)updateSubtitlesForButton:(TSQCalendarDayButton *)button if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:subtitleForDate:)]) { - NSString *subtitle = [self.calendarView.delegate calendarView:self.calendarView subtitleForDate:date]; - subtitle = subtitle; - + subtitle = [self.calendarView.delegate calendarView:self.calendarView subtitleForDate:date]; + // only check the color if the delegate also responds to the subtitle // delegate method. Prefer this subtitle color returned by the delegate, // except for other month buttons. From 6564582f9f78dff60a1c69d5053f8e1ebb17477d Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Mon, 8 Feb 2016 14:08:31 -0800 Subject: [PATCH 43/92] layout subtitle and symbol correctly based on cell size. shift icon left of subtitle if exist --- TimesSquare/TSQCalendarDayButton.m | 77 +++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 7 deletions(-) diff --git a/TimesSquare/TSQCalendarDayButton.m b/TimesSquare/TSQCalendarDayButton.m index 4b7e1cd..b95c45b 100644 --- a/TimesSquare/TSQCalendarDayButton.m +++ b/TimesSquare/TSQCalendarDayButton.m @@ -19,6 +19,9 @@ @interface TSQCalendarDayButton () @implementation TSQCalendarDayButton +static const CGFloat TSQCalendarRowCellMaxSubtitleHeight = 18.0f; +static const CGFloat TSQCalendarRowCellSubtitleBuffer = 15.0f; + - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; @@ -27,14 +30,14 @@ - (instancetype)initWithFrame:(CGRect)frame self.type = CalendarButtonTypeNormalDay; [self setTitleEdgeInsets:UIEdgeInsetsMake(-10, 0, 0, 0)]; - self.subtitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 50, 65, 18)]; + self.subtitleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; self.subtitleLabel.textAlignment = NSTextAlignmentCenter; self.subtitleLabel.userInteractionEnabled = NO; self.subtitleLabel.adjustsFontSizeToFitWidth = NO; self.subtitleLabel.lineBreakMode = NSLineBreakByTruncatingTail; [self addSubview:self.subtitleLabel]; - self.subtitleSymbolLabel = [[UILabel alloc] initWithFrame:CGRectMake(75, 50, 8, 18)]; + self.subtitleSymbolLabel = [[UILabel alloc] initWithFrame:CGRectZero]; self.subtitleSymbolLabel.userInteractionEnabled = NO; [self addSubview:self.subtitleSymbolLabel]; @@ -113,30 +116,90 @@ - (void)setIcon:(UIImage *)icon } } +- (CGSize)maxSubtitleSize +{ + CGFloat maxWidth = self.bounds.size.width - 2 * TSQCalendarRowCellSubtitleBuffer; + return CGSizeMake(maxWidth, TSQCalendarRowCellMaxSubtitleHeight); +} + +- (CGSize)maxSubtitleSymboleSize +{ + return CGSizeMake(8.0f, TSQCalendarRowCellMaxSubtitleHeight); +} + - (void)layoutSubviews { [super layoutSubviews]; + CGFloat midX = CGRectGetMidX(self.bounds); CGFloat subtitleCenterY = 0.75f * CGRectGetMaxY(self.bounds); + + self.subtitleLabel.hidden = !([self.subtitleLabel.text length] > 0); + self.subtitleSymbolLabel.hidden = !([self.subtitleSymbolLabel.text length] > 0); self.iconImageView.hidden = (self.iconImageView.image == nil); + + CGFloat iconWidth = self.iconImageView.image.size.width; + CGFloat iconHeight = self.iconImageView.image.size.height; + + if (! self.subtitleLabel.hidden) + { + CGSize maxSubtitleSize = [self maxSubtitleSize]; + CGSize sizeThatFits = [self.subtitleLabel sizeThatFits:maxSubtitleSize]; + + CGFloat subtitleWidth = fminf(sizeThatFits.width, maxSubtitleSize.width); + CGFloat subtitleHeight = fminf(sizeThatFits.height, maxSubtitleSize.height); + CGFloat originX = midX - subtitleWidth/2.0f; + CGFloat originY = subtitleCenterY - subtitleHeight/2.0f; + + self.subtitleLabel.frame = CGRectMake(originX, + originY, + subtitleWidth, + subtitleHeight); + } + + if (! self.subtitleSymbolLabel.hidden) + { + CGSize maxSymbolSize = [self maxSubtitleSymboleSize]; + CGSize sizeThatFits = [self.subtitleSymbolLabel sizeThatFits:maxSymbolSize]; + + CGFloat symbolWidth = fminf(sizeThatFits.width, maxSymbolSize.width); + CGFloat symbolHeight = fminf(sizeThatFits.height, maxSymbolSize.height); + CGFloat originX = CGRectGetMaxX(self.bounds) - TSQCalendarRowCellSubtitleBuffer; + CGFloat originY = subtitleCenterY - symbolHeight/2.0f; + + if (! self.subtitleLabel.hidden) + { + // when subtitle is showing, shift symbol to right of subtitle + CGFloat symbolBuffer = (TSQCalendarRowCellSubtitleBuffer - symbolWidth)/2.0f; + originX = CGRectGetMaxX(self.subtitleLabel.frame) + symbolBuffer; + } + + self.subtitleSymbolLabel.frame = CGRectMake(originX, + originY, + symbolWidth, + symbolHeight); + } + if (! self.iconImageView.hidden) { self.iconImageView.hidden = NO; - CGFloat iconWidth = self.iconImageView.image.size.width; - CGFloat iconHeight = self.iconImageView.image.size.height; - CGFloat midX = CGRectGetMidX(self.bounds); CGFloat originX = midX - iconWidth/2.0f; CGFloat originY = subtitleCenterY - iconHeight/2.0f; + if (! self.subtitleLabel.hidden) + { + // when subtitle is showing, shift icon to left of subtitle + CGFloat iconBuffer = (TSQCalendarRowCellSubtitleBuffer - iconWidth)/2.0f; + originX = self.subtitleLabel.frame.origin.x - iconWidth - iconBuffer; + } + self.iconImageView.frame = CGRectMake(originX, originY, iconWidth, iconHeight); - -#warning need to layout icon differently if subtitle is displayed } } From e9bd6b2515fc87ee3ccab2b26f7ae8e1fb1fb89b Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Mon, 8 Feb 2016 16:43:08 -0800 Subject: [PATCH 44/92] fix typo for symbol --- TimesSquare/TSQCalendarDayButton.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TimesSquare/TSQCalendarDayButton.m b/TimesSquare/TSQCalendarDayButton.m index b95c45b..b38e40a 100644 --- a/TimesSquare/TSQCalendarDayButton.m +++ b/TimesSquare/TSQCalendarDayButton.m @@ -122,7 +122,7 @@ - (CGSize)maxSubtitleSize return CGSizeMake(maxWidth, TSQCalendarRowCellMaxSubtitleHeight); } -- (CGSize)maxSubtitleSymboleSize +- (CGSize)maxSubtitleSymbolSize { return CGSizeMake(8.0f, TSQCalendarRowCellMaxSubtitleHeight); } @@ -159,7 +159,7 @@ - (void)layoutSubviews if (! self.subtitleSymbolLabel.hidden) { - CGSize maxSymbolSize = [self maxSubtitleSymboleSize]; + CGSize maxSymbolSize = [self maxSubtitleSymbolSize]; CGSize sizeThatFits = [self.subtitleSymbolLabel sizeThatFits:maxSymbolSize]; CGFloat symbolWidth = fminf(sizeThatFits.width, maxSymbolSize.width); From 68d502ae61f09b53f0fc28af89428ee7487aa1e4 Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Mon, 8 Feb 2016 16:59:47 -0800 Subject: [PATCH 45/92] move to observation model to relayout subviews for calendar day button --- TimesSquare/TSQCalendarDayButton.h | 9 +- TimesSquare/TSQCalendarDayButton.m | 147 ++++++++++++----------------- TimesSquare/TSQCalendarRowCell.m | 16 ++-- 3 files changed, 75 insertions(+), 97 deletions(-) diff --git a/TimesSquare/TSQCalendarDayButton.h b/TimesSquare/TSQCalendarDayButton.h index cfd0d96..2da01a8 100644 --- a/TimesSquare/TSQCalendarDayButton.h +++ b/TimesSquare/TSQCalendarDayButton.h @@ -18,11 +18,10 @@ typedef NS_ENUM(NSInteger, CalendarButtonType) { @property (nonatomic, assign) CalendarButtonType type; @property (nonatomic, strong) NSDate *day; -@property (nonatomic, readwrite) NSString *subtitle; -@property (nonatomic, readwrite) NSString *subtitleSymbol; -@property (nonatomic, readwrite) UIFont *subtitleFont; -@property (nonatomic, readwrite) UIColor *subtitleColor; -@property (nonatomic, readwrite) UIImage *icon; + +@property (nonatomic, strong) UILabel *subtitleLabel; +@property (nonatomic, strong) UILabel *subtitleSymbolLabel; +@property (nonatomic, strong) UIImageView *iconImageView; - (BOOL)isForToday; - (BOOL)isForDay:(NSDate *)date; diff --git a/TimesSquare/TSQCalendarDayButton.m b/TimesSquare/TSQCalendarDayButton.m index b38e40a..53f4ca9 100644 --- a/TimesSquare/TSQCalendarDayButton.m +++ b/TimesSquare/TSQCalendarDayButton.m @@ -8,15 +8,6 @@ #import "TSQCalendarDayButton.h" -@interface TSQCalendarDayButton () - -@property (nonatomic, strong) UILabel *subtitleLabel; -@property (nonatomic, strong) UILabel *subtitleSymbolLabel; - -@property (nonatomic, strong) UIImageView *iconImageView; - -@end - @implementation TSQCalendarDayButton static const CGFloat TSQCalendarRowCellMaxSubtitleHeight = 18.0f; @@ -44,87 +35,15 @@ - (instancetype)initWithFrame:(CGRect)frame self.iconImageView = [[UIImageView alloc] initWithFrame:CGRectZero]; self.iconImageView.userInteractionEnabled = NO; [self addSubview:self.iconImageView]; - } - return self; -} - -- (NSString *)subtitle -{ - return self.subtitleLabel.text; -} - -- (void)setSubtitle:(NSString *)subtitle; -{ - if (![self.subtitleLabel.text isEqualToString:subtitle]) - { - self.subtitleLabel.text = subtitle; - [self layoutSubviews]; - } -} - -- (NSString *)subtitleSymbol -{ - return self.subtitleSymbolLabel.text; -} - -- (void)setSubtitleSymbol:(NSString *)subtitleSymbol -{ - if (![self.subtitleSymbolLabel.text isEqualToString:subtitleSymbol]) - { - self.subtitleSymbolLabel.text = subtitleSymbol; - [self layoutSubviews]; - } -} - -- (UIFont *)subtitleFont -{ - return self.subtitleLabel.font; -} - -- (void)setSubtitleFont:(UIFont *)subtitleFont -{ - if (![self.subtitleFont isEqual:subtitleFont]) - { - self.subtitleLabel.font = subtitleFont; - self.subtitleSymbolLabel.font = subtitleFont; - [self layoutSubviews]; - } -} - -- (UIColor *)subtitleColor -{ - return self.subtitleLabel.textColor; -} - -- (void)setSubtitleColor:(UIColor *)subtitleColor -{ - self.subtitleLabel.textColor = subtitleColor; - self.subtitleSymbolLabel.textColor = subtitleColor; -} - -- (UIImage *)icon -{ - return self.iconImageView.image; -} -- (void)setIcon:(UIImage *)icon -{ - if (![self.iconImageView.image isEqual:icon]) - { - self.iconImageView.image = icon; - [self layoutSubviews]; + [self registerForNotifications]; } + return self; } -- (CGSize)maxSubtitleSize -{ - CGFloat maxWidth = self.bounds.size.width - 2 * TSQCalendarRowCellSubtitleBuffer; - return CGSizeMake(maxWidth, TSQCalendarRowCellMaxSubtitleHeight); -} - -- (CGSize)maxSubtitleSymbolSize +- (void)dealloc { - return CGSizeMake(8.0f, TSQCalendarRowCellMaxSubtitleHeight); + [self unregisterForNotifications]; } - (void)layoutSubviews @@ -203,6 +122,64 @@ - (void)layoutSubviews } } +#pragma mark - Observations + +- (void)registerForNotifications +{ + [self.subtitleLabel addObserver:self + forKeyPath:@"font" + options:NSKeyValueObservingOptionNew + context:nil]; + + [self.subtitleLabel addObserver:self + forKeyPath:@"text" + options:NSKeyValueObservingOptionNew + context:nil]; + + [self.subtitleSymbolLabel addObserver:self + forKeyPath:@"font" + options:NSKeyValueObservingOptionNew + context:nil]; + + [self.subtitleSymbolLabel addObserver:self + forKeyPath:@"text" + options:NSKeyValueObservingOptionNew + context:nil]; + + [self.iconImageView addObserver:self + forKeyPath:@"image" + options:NSKeyValueObservingOptionNew + context:nil]; +} + +- (void)unregisterForNotifications +{ + [self.subtitleLabel removeObserver:self forKeyPath:@"font"]; + [self.subtitleLabel removeObserver:self forKeyPath:@"text"]; + [self.subtitleSymbolLabel removeObserver:self forKeyPath:@"font"]; + [self.subtitleSymbolLabel removeObserver:self forKeyPath:@"text"]; + [self.iconImageView removeObserver:self forKeyPath:@"image"]; +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + // relayout subviews when certain properties of the subtitle label, subtitle symbol label, or icon image view changes + [self layoutSubviews]; +} + +#pragma mark - Helper Methods + +- (CGSize)maxSubtitleSize +{ + CGFloat maxWidth = self.bounds.size.width - 2 * TSQCalendarRowCellSubtitleBuffer; + return CGSizeMake(maxWidth, TSQCalendarRowCellMaxSubtitleHeight); +} + +- (CGSize)maxSubtitleSymbolSize +{ + return CGSizeMake(8.0f, TSQCalendarRowCellMaxSubtitleHeight); +} + - (BOOL)isForToday { NSDate *today = [NSDate date]; diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 93dd2b3..599680f 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -117,7 +117,8 @@ - (void)configureButton:(TSQCalendarDayButton *)button [self updateColorsForButton:button]; button.titleLabel.font = [self dayOfMonthFont]; - button.subtitleFont = [self subtitleFont]; + button.subtitleLabel.font = [self subtitleFont]; + button.subtitleSymbolLabel.font = [self subtitleFont]; button.titleLabel.shadowOffset = self.shadowOffset; button.adjustsImageWhenDisabled = NO; } @@ -271,7 +272,7 @@ - (void)updateColorsForButton:(TSQCalendarDayButton *)button icon = [self todayIcon]; } // can extend later to support other icons - button.icon = icon; + button.iconImageView.image = icon; } - (void)updateSubtitlesForButton:(TSQCalendarDayButton *)button @@ -332,9 +333,10 @@ - (void)updateSubtitlesForButton:(TSQCalendarDayButton *)button } } - button.subtitle = subtitle; - button.subtitleSymbol = subtitleSymbol; - button.subtitleColor = subtitleColor; + button.subtitleLabel.text = subtitle; + button.subtitleSymbolLabel.text = subtitleSymbol; + button.subtitleLabel.textColor = subtitleColor; + button.subtitleSymbolLabel.textColor = subtitleColor; } - (void)setBeginningDate:(NSDate *)date; @@ -494,8 +496,8 @@ - (void)selectColumnForDate:(NSDate *)date; [self.selectedButton setTitle:newTitle forState:UIControlStateNormal]; [self.selectedButton setTitle:newTitle forState:UIControlStateDisabled]; [self.selectedButton setAccessibilityLabel:[dayButton accessibilityLabel]]; - self.selectedButton.subtitle = dayButton.subtitle; - self.selectedButton.subtitleSymbol = dayButton.subtitleSymbol; + self.selectedButton.subtitleLabel.text = dayButton.subtitleLabel.text; + self.selectedButton.subtitleSymbolLabel.text = dayButton.subtitleSymbolLabel.text; } else { self.selectedButton.hidden = YES; self.selectedButton.enabled = NO; From bf7e13b167ee8dd33c5b5d71ffd1b0090769e83e Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Mon, 8 Feb 2016 17:05:16 -0800 Subject: [PATCH 46/92] tint icon the same color as the selected text when selected --- TimesSquare/TSQCalendarRowCell.m | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 599680f..ac7146a 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -268,11 +268,22 @@ - (void)updateColorsForButton:(TSQCalendarDayButton *)button // ** ICON **/ UIImage *icon = nil; - if ([button isForToday]) { + UIColor *iconTintColor = nil; + + if ([button isForToday]) + { icon = [self todayIcon]; + + if (button.type == CalendarButtonTypeSelected) + { + // when selected, tint the icon the same as selected text + icon = [icon imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + iconTintColor = dateColor; + } } // can extend later to support other icons button.iconImageView.image = icon; + button.iconImageView.tintColor = iconTintColor; } - (void)updateSubtitlesForButton:(TSQCalendarDayButton *)button From 43be9659cbc2810715741b7521feb03385381d45 Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Mon, 8 Feb 2016 17:33:54 -0800 Subject: [PATCH 47/92] need to reload table data whenever initial date changes --- TimesSquare/TSQCalendarView.m | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/TimesSquare/TSQCalendarView.m b/TimesSquare/TSQCalendarView.m index 2d96f15..20c0301 100644 --- a/TimesSquare/TSQCalendarView.m +++ b/TimesSquare/TSQCalendarView.m @@ -152,6 +152,15 @@ - (void)setSelectedDate:(NSDate *)newSelectedDate; } } +- (void)setInitialDate:(NSDate *)initialDate +{ + if ([_initialDate isEqualToDate:initialDate]) + { + _initialDate = initialDate; + [self.tableView reloadData]; + } +} + - (BOOL)scrollEnabled { return self.tableView.scrollEnabled; From 82aa279b0ad49e64f5351da7085816f418f1f202 Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Mon, 8 Feb 2016 17:38:43 -0800 Subject: [PATCH 48/92] =?UTF-8?q?SIGH=E2=80=A6=20Forgot=20to=20negate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TimesSquare/TSQCalendarView.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TimesSquare/TSQCalendarView.m b/TimesSquare/TSQCalendarView.m index 20c0301..38f3e03 100644 --- a/TimesSquare/TSQCalendarView.m +++ b/TimesSquare/TSQCalendarView.m @@ -154,7 +154,7 @@ - (void)setSelectedDate:(NSDate *)newSelectedDate; - (void)setInitialDate:(NSDate *)initialDate { - if ([_initialDate isEqualToDate:initialDate]) + if (![_initialDate isEqualToDate:initialDate]) { _initialDate = initialDate; [self.tableView reloadData]; From 66109ab935a4ba040d422ea89aee41267217f565 Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Wed, 10 Feb 2016 10:26:35 -0800 Subject: [PATCH 49/92] initial day selection should go away as soon as user selects a day --- TimesSquare/TSQCalendarDayButton.h | 1 + TimesSquare/TSQCalendarRowCell.h | 8 ++++ TimesSquare/TSQCalendarRowCell.m | 36 ++++++++++++----- TimesSquare/TSQCalendarView.m | 64 +++++++++++++++++++++--------- 4 files changed, 82 insertions(+), 27 deletions(-) diff --git a/TimesSquare/TSQCalendarDayButton.h b/TimesSquare/TSQCalendarDayButton.h index 2da01a8..d2bab7f 100644 --- a/TimesSquare/TSQCalendarDayButton.h +++ b/TimesSquare/TSQCalendarDayButton.h @@ -12,6 +12,7 @@ typedef NS_ENUM(NSInteger, CalendarButtonType) { CalendarButtonTypeNormalDay = 0, CalendarButtonTypeOtherMonth = 1, CalendarButtonTypeSelected = 2, + CalendarButtonTypeInitialDay = 3, }; @interface TSQCalendarDayButton : UIButton diff --git a/TimesSquare/TSQCalendarRowCell.h b/TimesSquare/TSQCalendarRowCell.h index 8d500e4..a62a99d 100644 --- a/TimesSquare/TSQCalendarRowCell.h +++ b/TimesSquare/TSQCalendarRowCell.h @@ -115,4 +115,12 @@ This is white by default. */ - (void)selectColumnForDate:(NSDate *)date; +/** Method to select the initial date within the week. + + This is funneled through and called by the calendar view, to facilitate deselection of other rows. + + @param date The initial date to select, or nil to deselect all columns. + */ +- (void)selectColumnForInitialDate:(NSDate *)date; + @end diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index ac7146a..8cf4ab2 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -195,8 +195,6 @@ - (void)updateColorsForButton:(TSQCalendarDayButton *)button case CalendarButtonTypeNormalDay: if ([button isForToday]) { dateColor = [self todayTextColor]; - } else if ([button isForDay:self.calendarView.initialDate]) { - dateColor = [self initialDayTextColor]; } else { dateColor = self.textColor; } @@ -209,6 +207,9 @@ - (void)updateColorsForButton:(TSQCalendarDayButton *)button case CalendarButtonTypeSelected: dateColor = [self selectedTextColor]; break; + + case CalendarButtonTypeInitialDay: + dateColor = [self initialDayTextColor]; } } @@ -245,8 +246,6 @@ - (void)updateColorsForButton:(TSQCalendarDayButton *)button case CalendarButtonTypeNormalDay: if ([button isForToday]) { dateShadowColor = [self todayTextShadowColor]; - } else if ([button isForDay:self.calendarView.initialDate]) { - dateShadowColor = [self initialDayTextShadowColor]; } else if (button.type == CalendarButtonTypeNormalDay) { dateShadowColor = [self textShadowColor]; } @@ -258,6 +257,10 @@ - (void)updateColorsForButton:(TSQCalendarDayButton *)button case CalendarButtonTypeSelected: dateShadowColor = [self selectedTextShadowColor]; break; + + case CalendarButtonTypeInitialDay: + dateShadowColor = [self initialDayTextShadowColor]; + break; } } @@ -315,8 +318,6 @@ - (void)updateSubtitlesForButton:(TSQCalendarDayButton *)button case CalendarButtonTypeNormalDay: if ([button isForToday]) { subtitleColor = [self todaySubtitleTextColor]; - } else if ([button isForDay:self.calendarView.initialDate]) { - subtitleColor = [self initialDaySubtitleTextColor]; } else { subtitleColor = [self subtitleTextColor]; } @@ -328,6 +329,10 @@ - (void)updateSubtitlesForButton:(TSQCalendarDayButton *)button case CalendarButtonTypeSelected: subtitleColor = [self selectedSubtitleTextColor]; break; + + case CalendarButtonTypeInitialDay: + subtitleColor = [self initialDaySubtitleTextColor]; + break; } } @@ -403,9 +408,7 @@ - (void)setBeginningDate:(NSDate *)date; // update background image UIImage *backgroundImage = nil; - if ([currentDayButton isForDay:self.calendarView.initialDate]) { - backgroundImage = [self initialDayBackgroundImage]; - } else if ([currentDayButton isForToday]) { + if ([currentDayButton isForToday]) { backgroundImage = [self todayBackgroundImage]; } [currentDayButton setBackgroundImage:backgroundImage forState:UIControlStateNormal]; @@ -475,6 +478,16 @@ - (void)layoutViewsForColumnAtIndex:(NSUInteger)index inRect:(CGRect)rect; } - (void)selectColumnForDate:(NSDate *)date; +{ + [self selectColumnForDate:date isInitialDay:NO]; +} + +- (void)selectColumnForInitialDate:(NSDate *)date +{ + [self selectColumnForDate:date isInitialDay:YES]; +} + +- (void)selectColumnForDate:(NSDate *)date isInitialDay:(BOOL)isInitialDay { if (!date && self.indexOfSelectedButton == -1) { return; @@ -494,9 +507,14 @@ - (void)selectColumnForDate:(NSDate *)date; self.indexOfSelectedButton = newIndexOfSelectedButton; if (newIndexOfSelectedButton >= 0) { + // update background image + UIImage *backgroundImage = isInitialDay ? [self initialDayBackgroundImage] : [self selectedBackgroundImage]; + [self.selectedButton setBackgroundImage:backgroundImage forState:UIControlStateNormal]; + // update selected button colors TSQCalendarDayButton *dayButton = self.dayButtons[newIndexOfSelectedButton]; self.selectedButton.day = dayButton.day; + self.selectedButton.type = isInitialDay ? CalendarButtonTypeInitialDay : CalendarButtonTypeSelected; [self updateColorsForButton:self.selectedButton]; [self updateSubtitlesForButton:self.selectedButton]; diff --git a/TimesSquare/TSQCalendarView.m b/TimesSquare/TSQCalendarView.m index 38f3e03..112ac79 100644 --- a/TimesSquare/TSQCalendarView.m +++ b/TimesSquare/TSQCalendarView.m @@ -128,9 +128,47 @@ - (void)setSelectedDate:(NSDate *)newSelectedDate; return; } + [self updateSelectedDate:startOfDay isInitialDate:NO]; + + _selectedDate = startOfDay; + + if (startOfDay == nil && self.initialDate != nil) { + [self updateSelectedDate:self.initialDate isInitialDate:YES]; + } + + if ([self.delegate respondsToSelector:@selector(calendarView:didSelectDate:)]) { + [self.delegate calendarView:self didSelectDate:startOfDay]; + } +} + +- (void)setInitialDate:(NSDate *)initialDate +{ + // clamp to beginning of its day + NSDate *startOfDay = [self clampDate:initialDate toComponents:NSCalendarUnitDay|NSCalendarUnitMonth|NSCalendarUnitYear]; + + if (self.selectedDate == nil) { + // only show initial date if user hasn't already selected a date + [self updateSelectedDate:startOfDay isInitialDate:YES]; + } + + _initialDate = startOfDay; +} + +- (void)updateSelectedDate:(NSDate *)date isInitialDate:(BOOL)isInitialDate +{ + // clear existing selected cells [[self cellForRowAtDate:_selectedDate] selectColumnForDate:nil]; - [[self cellForRowAtDate:startOfDay] selectColumnForDate:startOfDay]; - NSIndexPath *newIndexPath = [self indexPathForRowAtDate:startOfDay]; + [[self cellForRowAtDate:_initialDate] selectColumnForDate:nil]; + + // update new selected cell + TSQCalendarRowCell *dateRowCell = [self cellForRowAtDate:date]; + if (isInitialDate) { + [dateRowCell selectColumnForInitialDate:date]; + } else { + [dateRowCell selectColumnForDate:date]; + } + + NSIndexPath *newIndexPath = [self indexPathForRowAtDate:date]; CGRect newIndexPathRect = [self.tableView rectForRowAtIndexPath:newIndexPath]; CGRect scrollBounds = self.tableView.bounds; @@ -144,21 +182,6 @@ - (void)setSelectedDate:(NSDate *)newSelectedDate; [self.tableView scrollToRowAtIndexPath:newIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES]; } } - - _selectedDate = startOfDay; - - if ([self.delegate respondsToSelector:@selector(calendarView:didSelectDate:)]) { - [self.delegate calendarView:self didSelectDate:startOfDay]; - } -} - -- (void)setInitialDate:(NSDate *)initialDate -{ - if (![_initialDate isEqualToDate:initialDate]) - { - _initialDate = initialDate; - [self.tableView reloadData]; - } } - (BOOL)scrollEnabled @@ -300,8 +323,13 @@ - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)ce dateComponents.day = 1 - ordinalityOfFirstDay; dateComponents.weekOfMonth = indexPath.row; [(TSQCalendarRowCell *)cell setBeginningDate:[self.calendar dateByAddingComponents:dateComponents toDate:firstOfMonth options:0]]; - [(TSQCalendarRowCell *)cell selectColumnForDate:self.selectedDate]; + if (self.selectedDate) { + [(TSQCalendarRowCell *)cell selectColumnForDate:self.selectedDate]; + } else if (self.initialDate) { + [(TSQCalendarRowCell *)cell selectColumnForInitialDate:self.initialDate]; + } + BOOL isBottomRow = indexPath.row == [self tableView:tableView numberOfRowsInSection:indexPath.section] - 1; [(TSQCalendarRowCell *)cell setBottomRow:isBottomRow]; } From 4133d7f51cc54c72ead5ed12f17420f4d5dd18d8 Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Wed, 10 Feb 2016 13:12:14 -0800 Subject: [PATCH 50/92] allow initial date to be selected. --- TimesSquare/TSQCalendarRowCell.m | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 8cf4ab2..8bc3f5d 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -157,6 +157,7 @@ - (void)createSelectedButton; { TSQCalendarDayButton *button = [[TSQCalendarDayButton alloc] initWithFrame:self.contentView.bounds]; button.type = CalendarButtonTypeSelected; + [button addTarget:self action:@selector(dateButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; [self.contentView addSubview:button]; [self configureButton:button]; [button setBackgroundImage:[self selectedBackgroundImage] forState:UIControlStateNormal]; @@ -441,9 +442,8 @@ - (void)setBottomRow:(BOOL)bottomRow; - (IBAction)dateButtonPressed:(id)sender; { - NSDateComponents *offset = [NSDateComponents new]; - offset.day = [self.dayButtons indexOfObject:sender]; - NSDate *selectedDate = [self.calendar dateByAddingComponents:offset toDate:self.beginningDate options:0]; + TSQCalendarDayButton *dayButton = (TSQCalendarDayButton *)sender; + NSDate *selectedDate = dayButton.day; self.calendarView.selectedDate = selectedDate; } @@ -515,7 +515,8 @@ - (void)selectColumnForDate:(NSDate *)date isInitialDay:(BOOL)isInitialDay TSQCalendarDayButton *dayButton = self.dayButtons[newIndexOfSelectedButton]; self.selectedButton.day = dayButton.day; self.selectedButton.type = isInitialDay ? CalendarButtonTypeInitialDay : CalendarButtonTypeSelected; - [self updateColorsForButton:self.selectedButton]; + self.selectedButton.enabled = isInitialDay; + [self updateAppearanceForButton:self.selectedButton]; [self updateSubtitlesForButton:self.selectedButton]; // update selected button text From b9ce33e9fed8f04bfccbb822bf76226eb76da96c Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Wed, 10 Feb 2016 13:13:14 -0800 Subject: [PATCH 51/92] fix colors for initial date when disabled or special day --- TimesSquare/TSQCalendarRowCell.m | 233 ++++++++++++++++++------------- 1 file changed, 139 insertions(+), 94 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 8bc3f5d..ba57462 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -114,7 +114,7 @@ - (UIColor *)initialDaySubtitleTextColor - (void)configureButton:(TSQCalendarDayButton *)button { - [self updateColorsForButton:button]; + [self updateAppearanceForButton:button]; button.titleLabel.font = [self dayOfMonthFont]; button.subtitleLabel.font = [self subtitleFont]; @@ -169,7 +169,7 @@ - (void)createSelectedButton; self.selectedButton = button; } -- (void)updateColorsForButton:(TSQCalendarDayButton *)button +- (void)updateAppearanceForButton:(TSQCalendarDayButton *)button { UIColor *dateColor = nil; UIColor *disabledDateColor = nil; @@ -177,92 +177,113 @@ - (void)updateColorsForButton:(TSQCalendarDayButton *)button NSDate *date = button.day; + BOOL dateIsSelectable = YES; + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:shouldSelectDate:)]) { + dateIsSelectable = [self.calendarView.delegate calendarView:self.calendarView shouldSelectDate:date]; + } + + // ** DISABLED DATE COLOR **/ + + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:disabledDateColorForDate:)]) { + // prefer the delegate disabledDate color over everything else; this will + // always be used if the delegate returns a color (except for other month + // buttons) + disabledDateColor = [self.calendarView.delegate calendarView:self.calendarView disabledDateColorForDate:date]; + } + + // if the delegate doesn't return a disabled date color, fall back to a sane + // default. Other month buttons will always get this disabled color. + if ((! disabledDateColor) || (button.type == CalendarButtonTypeOtherMonth)) + { + disabledDateColor = [self.textColor colorWithAlphaComponent:0.5f]; + } + // ** DATE COLOR **/ // prefer the delegate date color over everything else; this will always be // used if the delegate returns a color - + UIColor *delegateDateColor = nil; if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:dateColorForDate:)]) { - dateColor = [self.calendarView.delegate calendarView:self.calendarView dateColorForDate:date]; + delegateDateColor = [self.calendarView.delegate calendarView:self.calendarView dateColorForDate:date]; } // if the delegate doesn't return a date color, fall back to some sane defaults, // which can still be overridden in subclasses - if (! dateColor) + switch (button.type) { - switch (button.type) - { - case CalendarButtonTypeNormalDay: - if ([button isForToday]) { - dateColor = [self todayTextColor]; - } else { - dateColor = self.textColor; - } - break; - - case CalendarButtonTypeOtherMonth: - dateColor = [self.textColor colorWithAlphaComponent:0.5f]; - break; - - case CalendarButtonTypeSelected: - dateColor = [self selectedTextColor]; - break; + case CalendarButtonTypeNormalDay: + if (delegateDateColor) { + dateColor = delegateDateColor; + } else if ([button isForToday]) { + dateColor = [self todayTextColor]; + } else { + dateColor = self.textColor; + } + break; - case CalendarButtonTypeInitialDay: - dateColor = [self initialDayTextColor]; - } - } + case CalendarButtonTypeOtherMonth: + dateColor = [self.textColor colorWithAlphaComponent:0.5f]; + break; - // ** DISABLED DATE COLOR **/ + case CalendarButtonTypeSelected: + dateColor = [self selectedTextColor]; + break; - // prefer the delegate disabledDate color over everything else; this will - // always be used if the delegate returns a color (except for other month - // buttons) - if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:disabledDateColorForDate:)]) - { - disabledDateColor = [self.calendarView.delegate calendarView:self.calendarView disabledDateColorForDate:date]; - } - - // if the delegate doesn't return a disabled date color, fall back to a sane - // default. Other month buttons will always get this disabled color. - if ((! disabledDateColor) || (button.type == CalendarButtonTypeOtherMonth)) - { - disabledDateColor = [self.textColor colorWithAlphaComponent:0.5f]; + case CalendarButtonTypeInitialDay: + if (dateIsSelectable) { + if (delegateDateColor) { + dateColor = delegateDateColor; + } else if ([button isForToday]) { + dateColor = [self todayTextColor]; + } else { + dateColor = [self initialDayTextColor]; + } + } else { + dateColor = disabledDateColor; + } } // ** DATE SHADOW COLOR **/ // prefer the delegate date shadow color over everything else; this will // always be used if the delegate returns a color + UIColor *delegateDateShadowColor = nil; if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:dateShadowColorForDate:)]) { - dateShadowColor = [self.calendarView.delegate calendarView:self.calendarView dateShadowColorForDate:date]; + delegateDateShadowColor = [self.calendarView.delegate calendarView:self.calendarView dateShadowColorForDate:date]; } - if (! dateShadowColor) + switch (button.type) { - switch (button.type) - { - case CalendarButtonTypeNormalDay: - if ([button isForToday]) { - dateShadowColor = [self todayTextShadowColor]; - } else if (button.type == CalendarButtonTypeNormalDay) { - dateShadowColor = [self textShadowColor]; - } - break; + case CalendarButtonTypeNormalDay: + if (delegateDateShadowColor) { + dateShadowColor = delegateDateShadowColor; + } else if ([button isForToday]) { + dateShadowColor = [self todayTextShadowColor]; + } else { + dateShadowColor = [self textShadowColor]; + } + break; - case CalendarButtonTypeOtherMonth: - break; + case CalendarButtonTypeOtherMonth: + break; - case CalendarButtonTypeSelected: - dateShadowColor = [self selectedTextShadowColor]; - break; + case CalendarButtonTypeSelected: + dateShadowColor = [self selectedTextShadowColor]; + break; - case CalendarButtonTypeInitialDay: - dateShadowColor = [self initialDayTextShadowColor]; - break; - } + case CalendarButtonTypeInitialDay: + if (dateIsSelectable) { + if (delegateDateShadowColor) { + dateShadowColor = delegateDateShadowColor; + } else if ([button isForToday]) { + dateShadowColor = [self todayTextShadowColor]; + } else { + dateShadowColor = [self initialDayTextShadowColor]; + } + } + break; } [button setTitleColor:dateColor forState:UIControlStateNormal]; @@ -298,6 +319,27 @@ - (void)updateSubtitlesForButton:(TSQCalendarDayButton *)button NSString *subtitleSymbol = nil; UIColor *subtitleColor = nil; + BOOL dateIsSelectable = YES; + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:shouldSelectDate:)]) { + dateIsSelectable = [self.calendarView.delegate calendarView:self.calendarView shouldSelectDate:date]; + } + + // ** DISABLED DATE COLOR **/ + UIColor *disabledDateColor = nil; + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:disabledDateColorForDate:)]) { + // prefer the delegate disabledDate color over everything else; this will + // always be used if the delegate returns a color (except for other month + // buttons) + disabledDateColor = [self.calendarView.delegate calendarView:self.calendarView disabledDateColorForDate:date]; + } + + // if the delegate doesn't return a disabled date color, fall back to a sane + // default. Other month buttons will always get this disabled color. + if ((! disabledDateColor) || (button.type == CalendarButtonTypeOtherMonth)) + { + disabledDateColor = [self.textColor colorWithAlphaComponent:0.5f]; + } + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:subtitleForDate:)]) { subtitle = [self.calendarView.delegate calendarView:self.calendarView subtitleForDate:date]; @@ -305,43 +347,46 @@ - (void)updateSubtitlesForButton:(TSQCalendarDayButton *)button // only check the color if the delegate also responds to the subtitle // delegate method. Prefer this subtitle color returned by the delegate, // except for other month buttons. - if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:subtitleColorForDate:)]) - { - subtitleColor = [self.calendarView.delegate calendarView:self.calendarView subtitleColorForDate:date]; + UIColor *delegateSubtitleColor = nil; + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:subtitleColorForDate:)]) { + delegateSubtitleColor = [self.calendarView.delegate calendarView:self.calendarView subtitleColorForDate:date]; } - - // if the delegate doesn't return a subtitle color, fall back to sane - // defaults - if (! subtitleColor) + + switch (button.type) { - switch (button.type) - { - case CalendarButtonTypeNormalDay: - if ([button isForToday]) { - subtitleColor = [self todaySubtitleTextColor]; - } else { - subtitleColor = [self subtitleTextColor]; - } - break; + case CalendarButtonTypeNormalDay: + if (delegateSubtitleColor) { + subtitleColor = delegateSubtitleColor; + } else if ([button isForToday]) { + subtitleColor = [self todaySubtitleTextColor]; + } else { + subtitleColor = [self subtitleTextColor]; + } + break; - case CalendarButtonTypeOtherMonth: - break; + case CalendarButtonTypeOtherMonth: + // prefer a disabled color for other month buttons, even if the delegate + // returned a color + subtitleColor = disabledDateColor; + break; - case CalendarButtonTypeSelected: - subtitleColor = [self selectedSubtitleTextColor]; - break; + case CalendarButtonTypeSelected: + subtitleColor = [self selectedSubtitleTextColor]; + break; - case CalendarButtonTypeInitialDay: - subtitleColor = [self initialDaySubtitleTextColor]; - break; - } - } - - // prefer a disabled color for other month buttons, even if the delegate - // returned a color - if (button.type == CalendarButtonTypeOtherMonth) - { - subtitleColor = [self.textColor colorWithAlphaComponent:0.5f]; + case CalendarButtonTypeInitialDay: + if (dateIsSelectable) { + if (delegateSubtitleColor) { + subtitleColor = delegateSubtitleColor; + } else if ([button isForToday]) { + subtitleColor = [self todaySubtitleTextColor]; + } else { + subtitleColor = [self initialDaySubtitleTextColor]; + } + } else { + subtitleColor = disabledDateColor; + } + break; } if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:subtitleTrailingSymbolForDate:)]) @@ -415,8 +460,8 @@ - (void)setBeginningDate:(NSDate *)date; [currentDayButton setBackgroundImage:backgroundImage forState:UIControlStateNormal]; // update button colors - [self updateColorsForButton:currentDayButton]; - [self updateColorsForButton:currentNotThisMonthButton]; + [self updateAppearanceForButton:currentDayButton]; + [self updateAppearanceForButton:currentNotThisMonthButton]; // update button subtitles [self updateSubtitlesForButton:currentDayButton]; From 856088b8059e029a2fa1c87c3b98e913a3621a91 Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Wed, 10 Feb 2016 13:30:40 -0800 Subject: [PATCH 52/92] make frames land on integers --- TimesSquare/TSQCalendarDayButton.m | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/TimesSquare/TSQCalendarDayButton.m b/TimesSquare/TSQCalendarDayButton.m index 53f4ca9..d91a11f 100644 --- a/TimesSquare/TSQCalendarDayButton.m +++ b/TimesSquare/TSQCalendarDayButton.m @@ -70,10 +70,11 @@ - (void)layoutSubviews CGFloat originX = midX - subtitleWidth/2.0f; CGFloat originY = subtitleCenterY - subtitleHeight/2.0f; - self.subtitleLabel.frame = CGRectMake(originX, - originY, - subtitleWidth, - subtitleHeight); + CGRect subtitleFrame = CGRectMake(floorf(originX), + floorf(originY), + subtitleWidth, + subtitleHeight); + self.subtitleLabel.frame = CGRectIntegral(subtitleFrame); } if (! self.subtitleSymbolLabel.hidden) @@ -93,10 +94,11 @@ - (void)layoutSubviews originX = CGRectGetMaxX(self.subtitleLabel.frame) + symbolBuffer; } - self.subtitleSymbolLabel.frame = CGRectMake(originX, - originY, - symbolWidth, - symbolHeight); + CGRect symbolFrame = CGRectMake(floorf(originX), + floorf(originY), + symbolWidth, + symbolHeight); + self.subtitleSymbolLabel.frame = CGRectIntegral(symbolFrame); } if (! self.iconImageView.hidden) @@ -115,10 +117,11 @@ - (void)layoutSubviews originX = self.subtitleLabel.frame.origin.x - iconWidth - iconBuffer; } - self.iconImageView.frame = CGRectMake(originX, - originY, - iconWidth, - iconHeight); + CGRect iconFrame = CGRectMake(floorf(originX), + floorf(originY), + iconWidth, + iconHeight); + self.iconImageView.frame = CGRectIntegral(iconFrame); } } From 64f2e8331a67149136a7bb194046378d81b4ae56 Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Thu, 31 Mar 2016 09:39:46 -0700 Subject: [PATCH 53/92] do not show today icon when it's for other month --- TimesSquare/TSQCalendarRowCell.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index ba57462..621062d 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -295,7 +295,7 @@ - (void)updateAppearanceForButton:(TSQCalendarDayButton *)button UIImage *icon = nil; UIColor *iconTintColor = nil; - if ([button isForToday]) + if ([button isForToday] && button.type != CalendarButtonTypeOtherMonth) { icon = [self todayIcon]; From 435de142c6663dd98c4d18a3983798f2af598ea5 Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Tue, 9 Aug 2016 17:13:37 -0700 Subject: [PATCH 54/92] Use new NSCalendarUnit enums to replace deprecated enums --- TimesSquare/TSQCalendarView.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TimesSquare/TSQCalendarView.m b/TimesSquare/TSQCalendarView.m index 112ac79..3b08c80 100644 --- a/TimesSquare/TSQCalendarView.m +++ b/TimesSquare/TSQCalendarView.m @@ -296,7 +296,7 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger // using the new calendar units, even though they are available in iOS 7.0, don't actually work for this calculation // on iOS 7. So we can't use the new units here. - NSRange rangeOfWeeks = [self.calendar rangeOfUnit:NSWeekCalendarUnit inUnit:NSMonthCalendarUnit forDate:firstOfMonth]; + NSRange rangeOfWeeks = [self.calendar rangeOfUnit:NSCalendarUnitWeekOfMonth inUnit:NSCalendarUnitMonth forDate:firstOfMonth]; return rangeOfWeeks.length; } From 5618c0ebd2638d3affb5cbeb8ce79fe2a032c13a Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Tue, 9 Aug 2016 22:36:28 -0700 Subject: [PATCH 55/92] allow delegate to provide additional text attributes to the date --- TimesSquare/TSQCalendarRowCell.m | 84 ++++++++++++++++++++++++++------ TimesSquare/TSQCalendarView.h | 2 + 2 files changed, 71 insertions(+), 15 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 621062d..c3bc3d9 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -288,7 +288,7 @@ - (void)updateAppearanceForButton:(TSQCalendarDayButton *)button [button setTitleColor:dateColor forState:UIControlStateNormal]; [button setTitleColor:disabledDateColor forState:UIControlStateDisabled]; - button.titleLabel.shadowColor = dateShadowColor; + [button setTitleShadowColor:dateShadowColor forState:UIControlStateNormal]; // ** ICON **/ @@ -311,6 +311,67 @@ - (void)updateAppearanceForButton:(TSQCalendarDayButton *)button button.iconImageView.tintColor = iconTintColor; } +- (void)updateTitleForButton:(TSQCalendarDayButton *)button +{ + NSDate *date = button.day; + + if (date == nil) { + return; + } + + NSString *title = [self.dayFormatter stringFromDate:date]; + [button setTitle:title forState:UIControlStateNormal]; + [button setTitle:title forState:UIControlStateDisabled]; + + // add accessibility label + NSString *accessibilityLabel = [self.accessibilityFormatter stringFromDate:date]; + [button setAccessibilityLabel:accessibilityLabel]; + + // check if we should use an attributed string + NSDictionary *additionalAttributes = nil; + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:additionalDateTextAttributesForDate:)]) { + additionalAttributes = [self.calendarView.delegate calendarView:self.calendarView additionalDateTextAttributesForDate:date]; + } + + if (additionalAttributes) { + // create text attributes for normal button + NSMutableDictionary *normalAttributes = [additionalAttributes mutableCopy]; + + if ([button titleColorForState:UIControlStateNormal]) { + normalAttributes[NSForegroundColorAttributeName] = [button titleColorForState:UIControlStateNormal]; + } + + if ([button titleShadowColorForState:UIControlStateNormal]) { + NSShadow *shadow = [NSShadow new]; + shadow.shadowOffset = button.titleLabel.shadowOffset; + shadow.shadowColor = [button titleShadowColorForState:UIControlStateNormal]; + normalAttributes[NSShadowAttributeName] = shadow; + } + + // update button title with normal attributes + NSAttributedString *normalTitle = [[NSAttributedString alloc] initWithString:title attributes:normalAttributes]; + [button setAttributedTitle:normalTitle forState:UIControlStateNormal]; + + // create text attributes for disabled button + NSMutableDictionary *disabledAttributes = [normalAttributes mutableCopy]; + + if ([button titleColorForState:UIControlStateDisabled]) { + disabledAttributes[NSForegroundColorAttributeName] = [button titleColorForState:UIControlStateDisabled]; + } + + if ([button titleShadowColorForState:UIControlStateDisabled]) { + NSShadow *shadow = [NSShadow new]; + shadow.shadowOffset = button.titleLabel.shadowOffset; + shadow.shadowColor = [button titleShadowColorForState:UIControlStateDisabled]; + disabledAttributes[NSShadowAttributeName] = shadow; + } + + // update button title with normal attributes + NSAttributedString *disabledTitle = [[NSAttributedString alloc] initWithString:title attributes:disabledAttributes]; + [button setAttributedTitle:disabledTitle forState:UIControlStateDisabled]; + } +} + - (void)updateSubtitlesForButton:(TSQCalendarDayButton *)button { NSDate *date = button.day; @@ -415,20 +476,12 @@ - (void)setBeginningDate:(NSDate *)date; offset.day = 1; for (NSUInteger index = 0; index < self.daysInWeek; index++) { - NSString *title = [self.dayFormatter stringFromDate:date]; - NSString *accessibilityLabel = [self.accessibilityFormatter stringFromDate:date]; - + TSQCalendarDayButton *currentDayButton = self.dayButtons[index]; TSQCalendarDayButton *currentNotThisMonthButton = self.notThisMonthButtons[index]; currentDayButton.day = date; currentNotThisMonthButton.day = date; - [currentDayButton setTitle:title forState:UIControlStateNormal]; - [currentDayButton setTitle:title forState:UIControlStateDisabled]; - [currentDayButton setAccessibilityLabel:accessibilityLabel]; - [currentNotThisMonthButton setTitle:title forState:UIControlStateNormal]; - [currentNotThisMonthButton setTitle:title forState:UIControlStateDisabled]; - [currentNotThisMonthButton setAccessibilityLabel:accessibilityLabel]; - + NSDateComponents *thisDateComponents = [self.calendar components:NSCalendarUnitDay|NSCalendarUnitMonth|NSCalendarUnitYear fromDate:date]; [currentDayButton setHidden:YES]; @@ -463,6 +516,10 @@ - (void)setBeginningDate:(NSDate *)date; [self updateAppearanceForButton:currentDayButton]; [self updateAppearanceForButton:currentNotThisMonthButton]; + // update button title + [self updateTitleForButton:currentDayButton]; + [self updateTitleForButton:currentNotThisMonthButton]; + // update button subtitles [self updateSubtitlesForButton:currentDayButton]; [self updateSubtitlesForButton:currentNotThisMonthButton]; @@ -567,10 +624,7 @@ - (void)selectColumnForDate:(NSDate *)date isInitialDay:(BOOL)isInitialDay // update selected button text self.selectedButton.hidden = NO; self.selectedButton.enabled = YES; - NSString *newTitle = [dayButton currentTitle]; - [self.selectedButton setTitle:newTitle forState:UIControlStateNormal]; - [self.selectedButton setTitle:newTitle forState:UIControlStateDisabled]; - [self.selectedButton setAccessibilityLabel:[dayButton accessibilityLabel]]; + [self updateTitleForButton:self.selectedButton]; self.selectedButton.subtitleLabel.text = dayButton.subtitleLabel.text; self.selectedButton.subtitleSymbolLabel.text = dayButton.subtitleSymbolLabel.text; } else { diff --git a/TimesSquare/TSQCalendarView.h b/TimesSquare/TSQCalendarView.h index 4ab3862..5bf9a58 100644 --- a/TimesSquare/TSQCalendarView.h +++ b/TimesSquare/TSQCalendarView.h @@ -168,6 +168,8 @@ - (UIColor*)calendarView: (TSQCalendarView *)calendarView subtitleColorForDate: (NSDate*) date; +- (NSDictionary*)calendarView: (TSQCalendarView *)calendarView additionalDateTextAttributesForDate: (NSDate*) date; + /** Tells the delegate that a particular date was selected. @param calendarView The calendar view that is selecting a date. From d19d187cdab6e8f62234b55f3eb03bef5e112c77 Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Mon, 3 Apr 2017 13:59:14 -0700 Subject: [PATCH 56/92] ignore selectedDate if cell doesn't exist --- TimesSquare/TSQCalendarView.m | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/TimesSquare/TSQCalendarView.m b/TimesSquare/TSQCalendarView.m index 3b08c80..8dc23ad 100644 --- a/TimesSquare/TSQCalendarView.m +++ b/TimesSquare/TSQCalendarView.m @@ -162,6 +162,10 @@ - (void)updateSelectedDate:(NSDate *)date isInitialDate:(BOOL)isInitialDate // update new selected cell TSQCalendarRowCell *dateRowCell = [self cellForRowAtDate:date]; + if (dateRowCell == nil) { + return; + } + if (isInitialDate) { [dateRowCell selectColumnForInitialDate:date]; } else { @@ -169,6 +173,10 @@ - (void)updateSelectedDate:(NSDate *)date isInitialDate:(BOOL)isInitialDate } NSIndexPath *newIndexPath = [self indexPathForRowAtDate:date]; + if (newIndexPath == nil) { + return; + } + CGRect newIndexPathRect = [self.tableView rectForRowAtIndexPath:newIndexPath]; CGRect scrollBounds = self.tableView.bounds; From 789fd3660b27b33ae1db1b06fd0b835336f5840d Mon Sep 17 00:00:00 2001 From: Simone Manganelli Date: Thu, 6 Apr 2017 18:22:21 -0700 Subject: [PATCH 57/92] remove unused property --- TimesSquare/TSQCalendarRowCell.m | 2 -- TimesSquare/TSQCalendarView.h | 3 --- 2 files changed, 5 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index c3bc3d9..4953b49 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -24,8 +24,6 @@ @interface TSQCalendarRowCell () @property (nonatomic) NSInteger monthOfBeginningDate; -@property (nonatomic, strong) NSArray *shiftNotes; - @end diff --git a/TimesSquare/TSQCalendarView.h b/TimesSquare/TSQCalendarView.h index 5bf9a58..f53c9d3 100644 --- a/TimesSquare/TSQCalendarView.h +++ b/TimesSquare/TSQCalendarView.h @@ -112,9 +112,6 @@ */ @property (nonatomic, strong) Class rowCellClass; -// Return all(?) shift notes -@property (nonatomic, readonly) NSArray *shiftNotes; - // Returns and modifies the scrollEnabled on the table view @property (nonatomic) BOOL scrollEnabled; From 92015b22125f27991a2232eb06bf51876c42bc44 Mon Sep 17 00:00:00 2001 From: Simone Manganelli Date: Thu, 6 Apr 2017 18:24:42 -0700 Subject: [PATCH 58/92] add pragma mark separators --- TimesSquare/TSQCalendarView.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/TimesSquare/TSQCalendarView.m b/TimesSquare/TSQCalendarView.m index 8dc23ad..131f7c9 100644 --- a/TimesSquare/TSQCalendarView.m +++ b/TimesSquare/TSQCalendarView.m @@ -228,7 +228,7 @@ - (TSQCalendarMonthHeaderCell *)makeHeaderCellWithIdentifier:(NSString *)identif return cell; } -#pragma mark Calendar calculations +#pragma mark - Calendar calculations - (NSDate *)firstOfMonthForSection:(NSInteger)section; { @@ -262,7 +262,7 @@ - (NSIndexPath *)indexPathForRowAtDate:(NSDate *)date; return [NSIndexPath indexPathForRow:targetWeek - firstWeek inSection:section]; } -#pragma mark UIView +#pragma mark - UIView - (void)layoutSubviews; { @@ -291,7 +291,7 @@ - (void)layoutSubviews; } } -#pragma mark UITableViewDataSource +#pragma mark - UITableViewDataSource - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; { @@ -320,7 +320,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N return cell; } -#pragma mark UITableViewDelegate +#pragma mark - UITableViewDelegate - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath; { @@ -371,7 +371,7 @@ - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger } -#pragma mark UIScrollViewDelegate +#pragma mark - UIScrollViewDelegate - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset; { From f37f50d8c828d0274dede3d67b3e2b59ef659ddb Mon Sep 17 00:00:00 2001 From: Simone Manganelli Date: Thu, 6 Apr 2017 18:31:22 -0700 Subject: [PATCH 59/92] add a way to hide the vertical scroll indicator if needed --- TimesSquare/TSQCalendarView.h | 4 ++++ TimesSquare/TSQCalendarView.m | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/TimesSquare/TSQCalendarView.h b/TimesSquare/TSQCalendarView.h index f53c9d3..80cf624 100644 --- a/TimesSquare/TSQCalendarView.h +++ b/TimesSquare/TSQCalendarView.h @@ -116,6 +116,10 @@ @property (nonatomic) BOOL scrollEnabled; +// Returns and modifies the showsVerticalScrollIndicator on the table view + +@property (nonatomic) BOOL showsVerticalScrollIndicator; + /** Scrolls the receiver until the specified date month is completely visible. @param date A date that identifies the month that will be visible. diff --git a/TimesSquare/TSQCalendarView.m b/TimesSquare/TSQCalendarView.m index 131f7c9..58770be 100644 --- a/TimesSquare/TSQCalendarView.m +++ b/TimesSquare/TSQCalendarView.m @@ -228,6 +228,16 @@ - (TSQCalendarMonthHeaderCell *)makeHeaderCellWithIdentifier:(NSString *)identif return cell; } +- (void)setShowsVerticalScrollIndicator:(BOOL)showsVerticalScrollIndicator +{ + self.tableView.showsVerticalScrollIndicator = showsVerticalScrollIndicator; +} + +- (BOOL)showsVerticalScrollIndicator +{ + return self.tableView.showsVerticalScrollIndicator; +} + #pragma mark - Calendar calculations - (NSDate *)firstOfMonthForSection:(NSInteger)section; From cc7ceee82a651e15dce7a7758e9bb85f62ea3d57 Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Tue, 27 Feb 2018 04:42:06 -0800 Subject: [PATCH 60/92] allow delegate to specify background image --- TimesSquare/TSQCalendarRowCell.m | 21 +++++++++++++-------- TimesSquare/TSQCalendarView.h | 2 ++ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 4953b49..b78acbe 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -307,6 +307,18 @@ - (void)updateAppearanceForButton:(TSQCalendarDayButton *)button // can extend later to support other icons button.iconImageView.image = icon; button.iconImageView.tintColor = iconTintColor; + + // ** BACKGROUND IMAGE **/ + + UIImage *backgroundImage = nil; + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:backgroundImageForDate:)]) { + backgroundImage = [self.calendarView.delegate calendarView:self.calendarView backgroundImageForDate:date]; + } + + if (backgroundImage == nil && [button isForToday]) { + backgroundImage = [self todayBackgroundImage]; + } + [button setBackgroundImage:backgroundImage forState:UIControlStateNormal]; } - (void)updateTitleForButton:(TSQCalendarDayButton *)button @@ -503,14 +515,7 @@ - (void)setBeginningDate:(NSDate *)date; button.hidden = NO; } - // update background image - UIImage *backgroundImage = nil; - if ([currentDayButton isForToday]) { - backgroundImage = [self todayBackgroundImage]; - } - [currentDayButton setBackgroundImage:backgroundImage forState:UIControlStateNormal]; - - // update button colors + // update button appearance [self updateAppearanceForButton:currentDayButton]; [self updateAppearanceForButton:currentNotThisMonthButton]; diff --git a/TimesSquare/TSQCalendarView.h b/TimesSquare/TSQCalendarView.h index 80cf624..1c0c3a4 100644 --- a/TimesSquare/TSQCalendarView.h +++ b/TimesSquare/TSQCalendarView.h @@ -169,6 +169,8 @@ - (UIColor*)calendarView: (TSQCalendarView *)calendarView subtitleColorForDate: (NSDate*) date; +- (UIImage*)calendarView: (TSQCalendarView *)calendarView backgroundImageForDate: (NSDate*) date; + - (NSDictionary*)calendarView: (TSQCalendarView *)calendarView additionalDateTextAttributesForDate: (NSDate*) date; /** Tells the delegate that a particular date was selected. From fd55cfc94d56fd89ca436331d233d0074563538e Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Tue, 27 Feb 2018 03:15:55 -0800 Subject: [PATCH 61/92] update project settings --- TimesSquare.xcodeproj/project.pbxproj | 46 +++++++++++++++++-- .../TimesSquare Documentation.xcscheme | 4 +- .../xcschemes/TimesSquare-iOS.xcscheme | 4 +- .../xcschemes/TimesSquare.xcscheme | 4 +- 4 files changed, 50 insertions(+), 8 deletions(-) diff --git a/TimesSquare.xcodeproj/project.pbxproj b/TimesSquare.xcodeproj/project.pbxproj index 6e61b7b..40ad1ec 100644 --- a/TimesSquare.xcodeproj/project.pbxproj +++ b/TimesSquare.xcodeproj/project.pbxproj @@ -275,7 +275,7 @@ A806805216700FD70071C71E /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0720; + LastUpgradeCheck = 0920; ORGANIZATIONNAME = Square; TargetAttributes = { 5C4733981AC3575B00269A66 = { @@ -352,7 +352,7 @@ CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -396,7 +396,7 @@ CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; @@ -431,12 +431,27 @@ ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -444,11 +459,14 @@ ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_TREAT_WARNINGS_AS_ERRORS = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_PEDANTIC = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 5.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; ONLY_ACTIVE_ARCH = YES; PUBLIC_HEADERS_FOLDER_PATH = "include/$(PRODUCT_NAME)"; RUN_CLANG_STATIC_ANALYZER = YES; @@ -462,16 +480,34 @@ ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_TREAT_WARNINGS_AS_ERRORS = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_PEDANTIC = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 5.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; PUBLIC_HEADERS_FOLDER_PATH = "include/$(PRODUCT_NAME)"; RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = iphoneos; diff --git a/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare Documentation.xcscheme b/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare Documentation.xcscheme index 72565b6..358a044 100644 --- a/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare Documentation.xcscheme +++ b/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare Documentation.xcscheme @@ -1,6 +1,6 @@ @@ -36,6 +37,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare-iOS.xcscheme b/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare-iOS.xcscheme index b1a2877..0c64bd5 100644 --- a/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare-iOS.xcscheme +++ b/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare-iOS.xcscheme @@ -1,6 +1,6 @@ Date: Tue, 27 Feb 2018 15:52:38 -0800 Subject: [PATCH 62/92] add support for delegated selected text color --- TimesSquare/TSQCalendarRowCell.m | 28 +++++++++++++++++++--------- TimesSquare/TSQCalendarView.h | 2 ++ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index b78acbe..be08cc2 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -201,11 +201,15 @@ - (void)updateAppearanceForButton:(TSQCalendarDayButton *)button // prefer the delegate date color over everything else; this will always be // used if the delegate returns a color UIColor *delegateDateColor = nil; - if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:dateColorForDate:)]) - { + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:dateColorForDate:)]) { delegateDateColor = [self.calendarView.delegate calendarView:self.calendarView dateColorForDate:date]; } - + + UIColor *delegateSelectedDateColor = nil; + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:selectedDateColorForDate:)]) { + delegateSelectedDateColor = [self.calendarView.delegate calendarView:self.calendarView selectedDateColorForDate:date]; + } + // if the delegate doesn't return a date color, fall back to some sane defaults, // which can still be overridden in subclasses switch (button.type) @@ -225,7 +229,11 @@ - (void)updateAppearanceForButton:(TSQCalendarDayButton *)button break; case CalendarButtonTypeSelected: - dateColor = [self selectedTextColor]; + if (delegateSelectedDateColor) { + dateColor = delegateSelectedDateColor; + } else { + dateColor = [self selectedTextColor]; + } break; case CalendarButtonTypeInitialDay: @@ -247,8 +255,7 @@ - (void)updateAppearanceForButton:(TSQCalendarDayButton *)button // prefer the delegate date shadow color over everything else; this will // always be used if the delegate returns a color UIColor *delegateDateShadowColor = nil; - if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:dateShadowColorForDate:)]) - { + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:dateShadowColorForDate:)]) { delegateDateShadowColor = [self.calendarView.delegate calendarView:self.calendarView dateShadowColorForDate:date]; } @@ -310,12 +317,15 @@ - (void)updateAppearanceForButton:(TSQCalendarDayButton *)button // ** BACKGROUND IMAGE **/ - UIImage *backgroundImage = nil; + UIImage *delegateBackgroundImage = nil; if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:backgroundImageForDate:)]) { - backgroundImage = [self.calendarView.delegate calendarView:self.calendarView backgroundImageForDate:date]; + delegateBackgroundImage = [self.calendarView.delegate calendarView:self.calendarView backgroundImageForDate:date]; } - if (backgroundImage == nil && [button isForToday]) { + UIImage *backgroundImage = nil; + if (delegateBackgroundImage != nil) { + backgroundImage = delegateBackgroundImage; + } else if ([button isForToday]) { backgroundImage = [self todayBackgroundImage]; } [button setBackgroundImage:backgroundImage forState:UIControlStateNormal]; diff --git a/TimesSquare/TSQCalendarView.h b/TimesSquare/TSQCalendarView.h index 1c0c3a4..b34b62b 100644 --- a/TimesSquare/TSQCalendarView.h +++ b/TimesSquare/TSQCalendarView.h @@ -169,6 +169,8 @@ - (UIColor*)calendarView: (TSQCalendarView *)calendarView subtitleColorForDate: (NSDate*) date; +- (UIColor*)calendarView: (TSQCalendarView *)calendarView selectedDateColorForDate: (NSDate*) date; + - (UIImage*)calendarView: (TSQCalendarView *)calendarView backgroundImageForDate: (NSDate*) date; - (NSDictionary*)calendarView: (TSQCalendarView *)calendarView additionalDateTextAttributesForDate: (NSDate*) date; From 110c96bb5c067a82eaed7c40f7e211f1a50fe7ab Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Thu, 1 Mar 2018 00:18:24 -0800 Subject: [PATCH 63/92] add foreground image view to TSQCalendarDayButton --- TimesSquare/TSQCalendarDayButton.h | 1 + TimesSquare/TSQCalendarDayButton.m | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/TimesSquare/TSQCalendarDayButton.h b/TimesSquare/TSQCalendarDayButton.h index d2bab7f..0423382 100644 --- a/TimesSquare/TSQCalendarDayButton.h +++ b/TimesSquare/TSQCalendarDayButton.h @@ -23,6 +23,7 @@ typedef NS_ENUM(NSInteger, CalendarButtonType) { @property (nonatomic, strong) UILabel *subtitleLabel; @property (nonatomic, strong) UILabel *subtitleSymbolLabel; @property (nonatomic, strong) UIImageView *iconImageView; +@property (nonatomic, strong) UIImageView *foregroundImageView; - (BOOL)isForToday; - (BOOL)isForDay:(NSDate *)date; diff --git a/TimesSquare/TSQCalendarDayButton.m b/TimesSquare/TSQCalendarDayButton.m index d91a11f..74759c3 100644 --- a/TimesSquare/TSQCalendarDayButton.m +++ b/TimesSquare/TSQCalendarDayButton.m @@ -36,6 +36,10 @@ - (instancetype)initWithFrame:(CGRect)frame self.iconImageView.userInteractionEnabled = NO; [self addSubview:self.iconImageView]; + self.foregroundImageView = [[UIImageView alloc] initWithFrame:CGRectZero]; + self.foregroundImageView.userInteractionEnabled = NO; + [self addSubview:self.foregroundImageView]; + [self registerForNotifications]; } return self; @@ -56,6 +60,7 @@ - (void)layoutSubviews self.subtitleLabel.hidden = !([self.subtitleLabel.text length] > 0); self.subtitleSymbolLabel.hidden = !([self.subtitleSymbolLabel.text length] > 0); self.iconImageView.hidden = (self.iconImageView.image == nil); + self.foregroundImageView.hidden = (self.foregroundImageView.image == nil); CGFloat iconWidth = self.iconImageView.image.size.width; CGFloat iconHeight = self.iconImageView.image.size.height; @@ -103,8 +108,6 @@ - (void)layoutSubviews if (! self.iconImageView.hidden) { - self.iconImageView.hidden = NO; - CGFloat midX = CGRectGetMidX(self.bounds); CGFloat originX = midX - iconWidth/2.0f; @@ -123,6 +126,10 @@ - (void)layoutSubviews iconHeight); self.iconImageView.frame = CGRectIntegral(iconFrame); } + + if (self.foregroundImageView.hidden == false) { + self.foregroundImageView.frame = self.bounds; + } } #pragma mark - Observations @@ -153,6 +160,11 @@ - (void)registerForNotifications forKeyPath:@"image" options:NSKeyValueObservingOptionNew context:nil]; + + [self.foregroundImageView addObserver:self + forKeyPath:@"image" + options:NSKeyValueObservingOptionNew + context:nil]; } - (void)unregisterForNotifications From 40a277d167dedbca9dde97ce6f7f37742a8409a8 Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Thu, 1 Mar 2018 00:21:03 -0800 Subject: [PATCH 64/92] add ability to delete to set foreground image on button --- TimesSquare/TSQCalendarRowCell.m | 8 ++++++++ TimesSquare/TSQCalendarView.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index be08cc2..d834323 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -329,6 +329,14 @@ - (void)updateAppearanceForButton:(TSQCalendarDayButton *)button backgroundImage = [self todayBackgroundImage]; } [button setBackgroundImage:backgroundImage forState:UIControlStateNormal]; + + // ** FOREGROUND IMAGE **/ + + UIImage *forgroundImage = nil; + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:foregroundImageForDate:)]) { + forgroundImage = [self.calendarView.delegate calendarView:self.calendarView foregroundImageForDate:date]; + } + button.foregroundImageView.image = forgroundImage; } - (void)updateTitleForButton:(TSQCalendarDayButton *)button diff --git a/TimesSquare/TSQCalendarView.h b/TimesSquare/TSQCalendarView.h index b34b62b..7970691 100644 --- a/TimesSquare/TSQCalendarView.h +++ b/TimesSquare/TSQCalendarView.h @@ -173,6 +173,8 @@ - (UIImage*)calendarView: (TSQCalendarView *)calendarView backgroundImageForDate: (NSDate*) date; +- (UIImage*)calendarView: (TSQCalendarView *)calendarView foregroundImageForDate: (NSDate*) date; + - (NSDictionary*)calendarView: (TSQCalendarView *)calendarView additionalDateTextAttributesForDate: (NSDate*) date; /** Tells the delegate that a particular date was selected. From 4e516d15e9ebe469e6326ae1419a1ff8bf8d74dc Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Thu, 1 Mar 2018 01:04:19 -0800 Subject: [PATCH 65/92] provide button size to delegate method for fetching background and foreground images --- TimesSquare/TSQCalendarRowCell.m | 8 ++++---- TimesSquare/TSQCalendarView.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index d834323..043d89c 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -318,8 +318,8 @@ - (void)updateAppearanceForButton:(TSQCalendarDayButton *)button // ** BACKGROUND IMAGE **/ UIImage *delegateBackgroundImage = nil; - if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:backgroundImageForDate:)]) { - delegateBackgroundImage = [self.calendarView.delegate calendarView:self.calendarView backgroundImageForDate:date]; + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:backgroundImageForDate:size:)]) { + delegateBackgroundImage = [self.calendarView.delegate calendarView:self.calendarView backgroundImageForDate:date size:button.bounds.size]; } UIImage *backgroundImage = nil; @@ -333,8 +333,8 @@ - (void)updateAppearanceForButton:(TSQCalendarDayButton *)button // ** FOREGROUND IMAGE **/ UIImage *forgroundImage = nil; - if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:foregroundImageForDate:)]) { - forgroundImage = [self.calendarView.delegate calendarView:self.calendarView foregroundImageForDate:date]; + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:foregroundImageForDate:size:)]) { + forgroundImage = [self.calendarView.delegate calendarView:self.calendarView foregroundImageForDate:date size:button.bounds.size]; } button.foregroundImageView.image = forgroundImage; } diff --git a/TimesSquare/TSQCalendarView.h b/TimesSquare/TSQCalendarView.h index 7970691..c301598 100644 --- a/TimesSquare/TSQCalendarView.h +++ b/TimesSquare/TSQCalendarView.h @@ -171,9 +171,9 @@ - (UIColor*)calendarView: (TSQCalendarView *)calendarView selectedDateColorForDate: (NSDate*) date; -- (UIImage*)calendarView: (TSQCalendarView *)calendarView backgroundImageForDate: (NSDate*) date; +- (UIImage*)calendarView: (TSQCalendarView *)calendarView backgroundImageForDate: (NSDate*) date size:(CGSize)size; -- (UIImage*)calendarView: (TSQCalendarView *)calendarView foregroundImageForDate: (NSDate*) date; +- (UIImage*)calendarView: (TSQCalendarView *)calendarView foregroundImageForDate: (NSDate*) date size:(CGSize)size; - (NSDictionary*)calendarView: (TSQCalendarView *)calendarView additionalDateTextAttributesForDate: (NSDate*) date; From f81aada42f1a4eb7897e7b3e362c30e850b68921 Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Thu, 1 Mar 2018 03:50:53 -0800 Subject: [PATCH 66/92] remove foreground image --- TimesSquare/TSQCalendarDayButton.h | 1 - TimesSquare/TSQCalendarDayButton.m | 14 -------------- TimesSquare/TSQCalendarRowCell.m | 8 -------- TimesSquare/TSQCalendarView.h | 2 -- 4 files changed, 25 deletions(-) diff --git a/TimesSquare/TSQCalendarDayButton.h b/TimesSquare/TSQCalendarDayButton.h index 0423382..d2bab7f 100644 --- a/TimesSquare/TSQCalendarDayButton.h +++ b/TimesSquare/TSQCalendarDayButton.h @@ -23,7 +23,6 @@ typedef NS_ENUM(NSInteger, CalendarButtonType) { @property (nonatomic, strong) UILabel *subtitleLabel; @property (nonatomic, strong) UILabel *subtitleSymbolLabel; @property (nonatomic, strong) UIImageView *iconImageView; -@property (nonatomic, strong) UIImageView *foregroundImageView; - (BOOL)isForToday; - (BOOL)isForDay:(NSDate *)date; diff --git a/TimesSquare/TSQCalendarDayButton.m b/TimesSquare/TSQCalendarDayButton.m index 74759c3..31116c2 100644 --- a/TimesSquare/TSQCalendarDayButton.m +++ b/TimesSquare/TSQCalendarDayButton.m @@ -36,10 +36,6 @@ - (instancetype)initWithFrame:(CGRect)frame self.iconImageView.userInteractionEnabled = NO; [self addSubview:self.iconImageView]; - self.foregroundImageView = [[UIImageView alloc] initWithFrame:CGRectZero]; - self.foregroundImageView.userInteractionEnabled = NO; - [self addSubview:self.foregroundImageView]; - [self registerForNotifications]; } return self; @@ -60,7 +56,6 @@ - (void)layoutSubviews self.subtitleLabel.hidden = !([self.subtitleLabel.text length] > 0); self.subtitleSymbolLabel.hidden = !([self.subtitleSymbolLabel.text length] > 0); self.iconImageView.hidden = (self.iconImageView.image == nil); - self.foregroundImageView.hidden = (self.foregroundImageView.image == nil); CGFloat iconWidth = self.iconImageView.image.size.width; CGFloat iconHeight = self.iconImageView.image.size.height; @@ -126,10 +121,6 @@ - (void)layoutSubviews iconHeight); self.iconImageView.frame = CGRectIntegral(iconFrame); } - - if (self.foregroundImageView.hidden == false) { - self.foregroundImageView.frame = self.bounds; - } } #pragma mark - Observations @@ -160,11 +151,6 @@ - (void)registerForNotifications forKeyPath:@"image" options:NSKeyValueObservingOptionNew context:nil]; - - [self.foregroundImageView addObserver:self - forKeyPath:@"image" - options:NSKeyValueObservingOptionNew - context:nil]; } - (void)unregisterForNotifications diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 043d89c..6fedc96 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -328,15 +328,7 @@ - (void)updateAppearanceForButton:(TSQCalendarDayButton *)button } else if ([button isForToday]) { backgroundImage = [self todayBackgroundImage]; } - [button setBackgroundImage:backgroundImage forState:UIControlStateNormal]; - // ** FOREGROUND IMAGE **/ - - UIImage *forgroundImage = nil; - if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:foregroundImageForDate:size:)]) { - forgroundImage = [self.calendarView.delegate calendarView:self.calendarView foregroundImageForDate:date size:button.bounds.size]; - } - button.foregroundImageView.image = forgroundImage; } - (void)updateTitleForButton:(TSQCalendarDayButton *)button diff --git a/TimesSquare/TSQCalendarView.h b/TimesSquare/TSQCalendarView.h index c301598..cda4988 100644 --- a/TimesSquare/TSQCalendarView.h +++ b/TimesSquare/TSQCalendarView.h @@ -173,8 +173,6 @@ - (UIImage*)calendarView: (TSQCalendarView *)calendarView backgroundImageForDate: (NSDate*) date size:(CGSize)size; -- (UIImage*)calendarView: (TSQCalendarView *)calendarView foregroundImageForDate: (NSDate*) date size:(CGSize)size; - - (NSDictionary*)calendarView: (TSQCalendarView *)calendarView additionalDateTextAttributesForDate: (NSDate*) date; /** Tells the delegate that a particular date was selected. From c2d0d8c501506da44cf99c2e6961345a2c948d18 Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Thu, 1 Mar 2018 04:06:19 -0800 Subject: [PATCH 67/92] track isInitialDay on button --- TimesSquare/TSQCalendarDayButton.h | 2 ++ TimesSquare/TSQCalendarRowCell.m | 1 + 2 files changed, 3 insertions(+) diff --git a/TimesSquare/TSQCalendarDayButton.h b/TimesSquare/TSQCalendarDayButton.h index d2bab7f..abdde6c 100644 --- a/TimesSquare/TSQCalendarDayButton.h +++ b/TimesSquare/TSQCalendarDayButton.h @@ -24,6 +24,8 @@ typedef NS_ENUM(NSInteger, CalendarButtonType) { @property (nonatomic, strong) UILabel *subtitleSymbolLabel; @property (nonatomic, strong) UIImageView *iconImageView; +@property (nonatomic, assign) BOOL isInitialDay; + - (BOOL)isForToday; - (BOOL)isForDay:(NSDate *)date; diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 6fedc96..6ab6bb6 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -631,6 +631,7 @@ - (void)selectColumnForDate:(NSDate *)date isInitialDay:(BOOL)isInitialDay self.selectedButton.day = dayButton.day; self.selectedButton.type = isInitialDay ? CalendarButtonTypeInitialDay : CalendarButtonTypeSelected; self.selectedButton.enabled = isInitialDay; + self.selectedButton.isInitialDay = isInitialDay; [self updateAppearanceForButton:self.selectedButton]; [self updateSubtitlesForButton:self.selectedButton]; From bb4bb0b94230157978f74fe773646916bd9f4448 Mon Sep 17 00:00:00 2001 From: Toland Hon Date: Thu, 1 Mar 2018 04:07:30 -0800 Subject: [PATCH 68/92] correctly handle selected button's background image --- TimesSquare/TSQCalendarRowCell.m | 40 ++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 6ab6bb6..bf7cf95 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -314,8 +314,11 @@ - (void)updateAppearanceForButton:(TSQCalendarDayButton *)button // can extend later to support other icons button.iconImageView.image = icon; button.iconImageView.tintColor = iconTintColor; +} - // ** BACKGROUND IMAGE **/ +- (void)updateBackgroundImageForButton:(TSQCalendarDayButton *)button +{ + NSDate *date = button.day; UIImage *delegateBackgroundImage = nil; if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:backgroundImageForDate:size:)]) { @@ -325,10 +328,13 @@ - (void)updateAppearanceForButton:(TSQCalendarDayButton *)button UIImage *backgroundImage = nil; if (delegateBackgroundImage != nil) { backgroundImage = delegateBackgroundImage; + } else if (button.type == CalendarButtonTypeSelected) { + backgroundImage = button.isInitialDay ? [self initialDayBackgroundImage] : [self selectedBackgroundImage]; } else if ([button isForToday]) { backgroundImage = [self todayBackgroundImage]; } + [button setBackgroundImage:backgroundImage forState:UIControlStateNormal]; } - (void)updateTitleForButton:(TSQCalendarDayButton *)button @@ -581,14 +587,25 @@ - (void)layoutSubviews; - (void)layoutViewsForColumnAtIndex:(NSUInteger)index inRect:(CGRect)rect; { - UIButton *dayButton = self.dayButtons[index]; - UIButton *notThisMonthButton = self.notThisMonthButtons[index]; - - dayButton.frame = rect; - notThisMonthButton.frame = rect; - + // find buttons that we need to update the frame + NSMutableArray *buttons = [NSMutableArray new]; + if (index < self.dayButtons.count) { + [buttons addObject:self.dayButtons[index]]; + } + if (index < self.notThisMonthButtons.count) { + [buttons addObject:self.notThisMonthButtons[index]]; + } if (self.indexOfSelectedButton == (NSInteger)index) { - self.selectedButton.frame = rect; + [buttons addObject:self.selectedButton]; + } + + for (TSQCalendarDayButton *button in buttons) { + if (CGRectEqualToRect(button.frame, rect) == NO) { + button.frame = rect; + + // image views are dependant on button size so they need to be regenerated + [self updateBackgroundImageForButton:button]; + } } } @@ -622,10 +639,6 @@ - (void)selectColumnForDate:(NSDate *)date isInitialDay:(BOOL)isInitialDay self.indexOfSelectedButton = newIndexOfSelectedButton; if (newIndexOfSelectedButton >= 0) { - // update background image - UIImage *backgroundImage = isInitialDay ? [self initialDayBackgroundImage] : [self selectedBackgroundImage]; - [self.selectedButton setBackgroundImage:backgroundImage forState:UIControlStateNormal]; - // update selected button colors TSQCalendarDayButton *dayButton = self.dayButtons[newIndexOfSelectedButton]; self.selectedButton.day = dayButton.day; @@ -635,6 +648,9 @@ - (void)selectColumnForDate:(NSDate *)date isInitialDay:(BOOL)isInitialDay [self updateAppearanceForButton:self.selectedButton]; [self updateSubtitlesForButton:self.selectedButton]; + // update background image + [self updateBackgroundImageForButton:self.selectedButton]; + // update selected button text self.selectedButton.hidden = NO; self.selectedButton.enabled = YES; From 8905f1b5e10e91b278e9fd3811934a5533eea822 Mon Sep 17 00:00:00 2001 From: Michael Joe Date: Sat, 16 Feb 2019 10:36:04 -0800 Subject: [PATCH 69/92] update accessibilityLabels for disabled days. --- TimesSquare/TSQCalendarRowCell.m | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index bf7cf95..bc0446f 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -351,7 +351,11 @@ - (void)updateTitleForButton:(TSQCalendarDayButton *)button // add accessibility label NSString *accessibilityLabel = [self.accessibilityFormatter stringFromDate:date]; - [button setAccessibilityLabel:accessibilityLabel]; + if (button.type == 1) { + [button setAccessibilityLabel:[NSString stringWithFormat:@"%@ Disabled", accessibilityLabel]]; + } else { + [button setAccessibilityLabel:accessibilityLabel]; + } // check if we should use an attributed string NSDictionary *additionalAttributes = nil; From e59dfce10c10a331bac01ac28d2686be023f03fd Mon Sep 17 00:00:00 2001 From: Malcolm Goldiner Date: Wed, 24 Jun 2020 17:03:29 -0700 Subject: [PATCH 70/92] fix(reuse): clear button images on reuse and before layout pass --- TimesSquare/TSQCalendarRowCell.m | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index bc0446f..bfa09b4 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -604,6 +604,8 @@ - (void)layoutViewsForColumnAtIndex:(NSUInteger)index inRect:(CGRect)rect; } for (TSQCalendarDayButton *button in buttons) { + [self clearButtonImages:button]; + if (CGRectEqualToRect(button.frame, rect) == NO) { button.frame = rect; @@ -703,4 +705,19 @@ - (void)setFirstOfMonth:(NSDate *)firstOfMonth; self.monthOfBeginningDate = 0; } +- (void)prepareForReuse { + [super prepareForReuse]; + + for (TSQCalendarDayButton *button in self.dayButtons) { + [self clearButtonImages:button]; + } +} + +- (void)clearButtonImages:(UIButton *)button +{ + [button setBackgroundImage:nil forState:UIControlStateNormal]; + [button setBackgroundImage:nil forState:UIControlStateDisabled]; + [button setBackgroundImage:nil forState:UIControlStateSelected]; +} + @end From ca6b2620e069ddb142d556cf438db675dfdc74ea Mon Sep 17 00:00:00 2001 From: Malcolm Goldiner Date: Wed, 24 Jun 2020 17:07:44 -0700 Subject: [PATCH 71/92] fix(reuse): only remove images in frame --- TimesSquare/TSQCalendarRowCell.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index bfa09b4..0228b75 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -604,11 +604,12 @@ - (void)layoutViewsForColumnAtIndex:(NSUInteger)index inRect:(CGRect)rect; } for (TSQCalendarDayButton *button in buttons) { - [self clearButtonImages:button]; + if (CGRectEqualToRect(button.frame, rect) == NO) { button.frame = rect; - + [self clearButtonImages:button]; + // image views are dependant on button size so they need to be regenerated [self updateBackgroundImageForButton:button]; } From c05fc7541b0586c2c9780b6acb60f0fe3eba26ee Mon Sep 17 00:00:00 2001 From: Malcolm Goldiner Date: Wed, 24 Jun 2020 17:15:51 -0700 Subject: [PATCH 72/92] feat(reuse): add back in reuse call outside of loop --- TimesSquare/TSQCalendarRowCell.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 0228b75..826da37 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -603,9 +603,8 @@ - (void)layoutViewsForColumnAtIndex:(NSUInteger)index inRect:(CGRect)rect; [buttons addObject:self.selectedButton]; } + [self prepareForReuse]; for (TSQCalendarDayButton *button in buttons) { - - if (CGRectEqualToRect(button.frame, rect) == NO) { button.frame = rect; [self clearButtonImages:button]; From d4b6b2c7cb126d1c58cb1a035cc361aa6f1077a4 Mon Sep 17 00:00:00 2001 From: Malcolm Goldiner Date: Wed, 24 Jun 2020 17:24:21 -0700 Subject: [PATCH 73/92] fix(reuse): remove duplicate reuse --- TimesSquare/TSQCalendarRowCell.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 826da37..373b61d 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -603,11 +603,10 @@ - (void)layoutViewsForColumnAtIndex:(NSUInteger)index inRect:(CGRect)rect; [buttons addObject:self.selectedButton]; } - [self prepareForReuse]; for (TSQCalendarDayButton *button in buttons) { + [button setBackgroundImage:nil forState:UIControlStateNormal]; if (CGRectEqualToRect(button.frame, rect) == NO) { button.frame = rect; - [self clearButtonImages:button]; // image views are dependant on button size so they need to be regenerated [self updateBackgroundImageForButton:button]; From c70315b83b2f28dc83bfe5065b65b29e17995068 Mon Sep 17 00:00:00 2001 From: Malcolm Goldiner Date: Thu, 25 Jun 2020 11:31:26 -0700 Subject: [PATCH 74/92] fix(reuse): attempt 2 --- TimesSquare/TSQCalendarRowCell.h | 2 ++ TimesSquare/TSQCalendarRowCell.m | 24 ++++++++++++++++++++---- TimesSquare/TSQCalendarView.m | 5 +++++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.h b/TimesSquare/TSQCalendarRowCell.h index a62a99d..7bcaead 100644 --- a/TimesSquare/TSQCalendarRowCell.h +++ b/TimesSquare/TSQCalendarRowCell.h @@ -123,4 +123,6 @@ This is white by default. */ - (void)selectColumnForInitialDate:(NSDate *)date; +- (void)refreshImages; + @end diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 373b61d..c909f13 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -344,7 +344,8 @@ - (void)updateTitleForButton:(TSQCalendarDayButton *)button if (date == nil) { return; } - + + [self updateBackgroundImageForButton:button]; NSString *title = [self.dayFormatter stringFromDate:date]; [button setTitle:title forState:UIControlStateNormal]; [button setTitle:title forState:UIControlStateDisabled]; @@ -604,10 +605,9 @@ - (void)layoutViewsForColumnAtIndex:(NSUInteger)index inRect:(CGRect)rect; } for (TSQCalendarDayButton *button in buttons) { - [button setBackgroundImage:nil forState:UIControlStateNormal]; if (CGRectEqualToRect(button.frame, rect) == NO) { button.frame = rect; - +// [self clearButtonImages:button]; // image views are dependant on button size so they need to be regenerated [self updateBackgroundImageForButton:button]; } @@ -707,8 +707,24 @@ - (void)setFirstOfMonth:(NSDate *)firstOfMonth; - (void)prepareForReuse { [super prepareForReuse]; +// for (TSQCalendarDayButton *button in self.dayButtons) { +// [self clearButtonImages:button]; +// } + + NSLog(@"HERE"); + + [self refreshImages]; +} + +- (void)refreshImages { for (TSQCalendarDayButton *button in self.dayButtons) { - [self clearButtonImages:button]; + [self updateBackgroundImageForButton:button]; + + if (button.currentBackgroundImage != nil) { + NSLog(@"Button with image refreshed"); + } else { + NSLog(@"Wasted refresh"); + } } } diff --git a/TimesSquare/TSQCalendarView.m b/TimesSquare/TSQCalendarView.m index 58770be..ea222f8 100644 --- a/TimesSquare/TSQCalendarView.m +++ b/TimesSquare/TSQCalendarView.m @@ -190,6 +190,8 @@ - (void)updateSelectedDate:(NSDate *)date isInitialDate:(BOOL)isInitialDate [self.tableView scrollToRowAtIndexPath:newIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES]; } } + + [dateRowCell refreshImages]; } - (BOOL)scrollEnabled @@ -326,6 +328,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N cell = [[[self rowCellClass] alloc] initWithCalendar:self.calendar reuseIdentifier:identifier]; cell.backgroundColor = self.backgroundColor; cell.calendarView = self; + [cell refreshImages]; } return cell; } @@ -350,6 +353,8 @@ - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)ce BOOL isBottomRow = indexPath.row == [self tableView:tableView numberOfRowsInSection:indexPath.section] - 1; [(TSQCalendarRowCell *)cell setBottomRow:isBottomRow]; + + [(TSQCalendarRowCell *)cell refreshImages]; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath; From c292e643869b033d43dbb3dfa218d27a22b4d935 Mon Sep 17 00:00:00 2001 From: Malcolm Goldiner Date: Thu, 25 Jun 2020 12:12:46 -0700 Subject: [PATCH 75/92] fix(reuse): remove extra reloads --- TimesSquare/TSQCalendarView.m | 3 --- 1 file changed, 3 deletions(-) diff --git a/TimesSquare/TSQCalendarView.m b/TimesSquare/TSQCalendarView.m index ea222f8..1a624ef 100644 --- a/TimesSquare/TSQCalendarView.m +++ b/TimesSquare/TSQCalendarView.m @@ -190,8 +190,6 @@ - (void)updateSelectedDate:(NSDate *)date isInitialDate:(BOOL)isInitialDate [self.tableView scrollToRowAtIndexPath:newIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES]; } } - - [dateRowCell refreshImages]; } - (BOOL)scrollEnabled @@ -328,7 +326,6 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N cell = [[[self rowCellClass] alloc] initWithCalendar:self.calendar reuseIdentifier:identifier]; cell.backgroundColor = self.backgroundColor; cell.calendarView = self; - [cell refreshImages]; } return cell; } From 9933f3a1afc3c5940c99bdbcea4cf70ab08588b2 Mon Sep 17 00:00:00 2001 From: Malcolm Goldiner Date: Thu, 25 Jun 2020 12:46:18 -0700 Subject: [PATCH 76/92] fix(reuse): update reuse --- TimesSquare/TSQCalendarRowCell.m | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index c909f13..7c6a90f 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -704,35 +704,10 @@ - (void)setFirstOfMonth:(NSDate *)firstOfMonth; self.monthOfBeginningDate = 0; } -- (void)prepareForReuse { - [super prepareForReuse]; - -// for (TSQCalendarDayButton *button in self.dayButtons) { -// [self clearButtonImages:button]; -// } - - NSLog(@"HERE"); - - [self refreshImages]; -} - - (void)refreshImages { for (TSQCalendarDayButton *button in self.dayButtons) { [self updateBackgroundImageForButton:button]; - - if (button.currentBackgroundImage != nil) { - NSLog(@"Button with image refreshed"); - } else { - NSLog(@"Wasted refresh"); - } } } -- (void)clearButtonImages:(UIButton *)button -{ - [button setBackgroundImage:nil forState:UIControlStateNormal]; - [button setBackgroundImage:nil forState:UIControlStateDisabled]; - [button setBackgroundImage:nil forState:UIControlStateSelected]; -} - @end From f639b67b4c3a6bb9a304b4dd2961fac3b78d98fa Mon Sep 17 00:00:00 2001 From: Malcolm Goldiner Date: Thu, 25 Jun 2020 15:46:13 -0700 Subject: [PATCH 77/92] feat(Experience): RO-8459 remove commented out lines and extra reloads --- TimesSquare/TSQCalendarRowCell.m | 5 ----- 1 file changed, 5 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 7c6a90f..2f365ae 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -345,7 +345,6 @@ - (void)updateTitleForButton:(TSQCalendarDayButton *)button return; } - [self updateBackgroundImageForButton:button]; NSString *title = [self.dayFormatter stringFromDate:date]; [button setTitle:title forState:UIControlStateNormal]; [button setTitle:title forState:UIControlStateDisabled]; @@ -607,7 +606,6 @@ - (void)layoutViewsForColumnAtIndex:(NSUInteger)index inRect:(CGRect)rect; for (TSQCalendarDayButton *button in buttons) { if (CGRectEqualToRect(button.frame, rect) == NO) { button.frame = rect; -// [self clearButtonImages:button]; // image views are dependant on button size so they need to be regenerated [self updateBackgroundImageForButton:button]; } @@ -653,9 +651,6 @@ - (void)selectColumnForDate:(NSDate *)date isInitialDay:(BOOL)isInitialDay [self updateAppearanceForButton:self.selectedButton]; [self updateSubtitlesForButton:self.selectedButton]; - // update background image - [self updateBackgroundImageForButton:self.selectedButton]; - // update selected button text self.selectedButton.hidden = NO; self.selectedButton.enabled = YES; From 8f38ab43090d1a657ea7a210b3f255272acff2ce Mon Sep 17 00:00:00 2001 From: Malcolm Goldiner Date: Thu, 25 Jun 2020 15:59:19 -0700 Subject: [PATCH 78/92] fix(reuse): adding back reuse 1 at a time --- TimesSquare/TSQCalendarRowCell.m | 1 + 1 file changed, 1 insertion(+) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 2f365ae..85eb760 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -345,6 +345,7 @@ - (void)updateTitleForButton:(TSQCalendarDayButton *)button return; } + [self updateBackgroundImageForButton:button]; NSString *title = [self.dayFormatter stringFromDate:date]; [button setTitle:title forState:UIControlStateNormal]; [button setTitle:title forState:UIControlStateDisabled]; From 9569343154742197cf358ee417230ed7d2dcdabb Mon Sep 17 00:00:00 2001 From: Malcolm Goldiner Date: Thu, 25 Jun 2020 16:08:40 -0700 Subject: [PATCH 79/92] fix(reuse): avoid unneeded change --- TimesSquare/TSQCalendarRowCell.m | 3 +++ 1 file changed, 3 insertions(+) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 85eb760..128dadc 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -652,6 +652,9 @@ - (void)selectColumnForDate:(NSDate *)date isInitialDay:(BOOL)isInitialDay [self updateAppearanceForButton:self.selectedButton]; [self updateSubtitlesForButton:self.selectedButton]; + // update background image + [self updateBackgroundImageForButton:self.selectedButton]; + // update selected button text self.selectedButton.hidden = NO; self.selectedButton.enabled = YES; From 438d4a01d732977aa0426b2029d725f3d8963c5e Mon Sep 17 00:00:00 2001 From: Malcolm Goldiner Date: Thu, 25 Jun 2020 16:36:08 -0700 Subject: [PATCH 80/92] fix(reuse): reuse tuning --- TimesSquare/TSQCalendarView.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TimesSquare/TSQCalendarView.m b/TimesSquare/TSQCalendarView.m index 1a624ef..9ac5934 100644 --- a/TimesSquare/TSQCalendarView.m +++ b/TimesSquare/TSQCalendarView.m @@ -351,7 +351,7 @@ - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)ce BOOL isBottomRow = indexPath.row == [self tableView:tableView numberOfRowsInSection:indexPath.section] - 1; [(TSQCalendarRowCell *)cell setBottomRow:isBottomRow]; - [(TSQCalendarRowCell *)cell refreshImages]; +// [(TSQCalendarRowCell *)cell refreshImages]; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath; From 0ddf321389799fa412a3cf0db53cdbbae5c20e0d Mon Sep 17 00:00:00 2001 From: Malcolm Goldiner Date: Thu, 25 Jun 2020 17:14:51 -0700 Subject: [PATCH 81/92] fix(image setting): cleanup --- TimesSquare/TSQCalendarRowCell.h | 2 -- TimesSquare/TSQCalendarRowCell.m | 6 ------ TimesSquare/TSQCalendarView.m | 2 -- 3 files changed, 10 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.h b/TimesSquare/TSQCalendarRowCell.h index 7bcaead..a62a99d 100644 --- a/TimesSquare/TSQCalendarRowCell.h +++ b/TimesSquare/TSQCalendarRowCell.h @@ -123,6 +123,4 @@ This is white by default. */ - (void)selectColumnForInitialDate:(NSDate *)date; -- (void)refreshImages; - @end diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 128dadc..00ae795 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -703,10 +703,4 @@ - (void)setFirstOfMonth:(NSDate *)firstOfMonth; self.monthOfBeginningDate = 0; } -- (void)refreshImages { - for (TSQCalendarDayButton *button in self.dayButtons) { - [self updateBackgroundImageForButton:button]; - } -} - @end diff --git a/TimesSquare/TSQCalendarView.m b/TimesSquare/TSQCalendarView.m index 9ac5934..58770be 100644 --- a/TimesSquare/TSQCalendarView.m +++ b/TimesSquare/TSQCalendarView.m @@ -350,8 +350,6 @@ - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)ce BOOL isBottomRow = indexPath.row == [self tableView:tableView numberOfRowsInSection:indexPath.section] - 1; [(TSQCalendarRowCell *)cell setBottomRow:isBottomRow]; - -// [(TSQCalendarRowCell *)cell refreshImages]; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath; From e287b1fd2302a7077e454a3d509bf2d43a32b0ac Mon Sep 17 00:00:00 2001 From: Malcolm Goldiner Date: Mon, 29 Jun 2020 13:15:42 -0700 Subject: [PATCH 82/92] fix(duplication); don't show the same icon if date is shown in 2 months --- TimesSquare/TSQCalendarRowCell.m | 33 ++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 00ae795..a0d32a3 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -318,23 +318,26 @@ - (void)updateAppearanceForButton:(TSQCalendarDayButton *)button - (void)updateBackgroundImageForButton:(TSQCalendarDayButton *)button { - NSDate *date = button.day; + if (button.type != CalendarButtonTypeOtherMonth) + { + NSDate *date = button.day; - UIImage *delegateBackgroundImage = nil; - if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:backgroundImageForDate:size:)]) { - delegateBackgroundImage = [self.calendarView.delegate calendarView:self.calendarView backgroundImageForDate:date size:button.bounds.size]; - } + UIImage *delegateBackgroundImage = nil; + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:backgroundImageForDate:size:)]) { + delegateBackgroundImage = [self.calendarView.delegate calendarView:self.calendarView backgroundImageForDate:date size:button.bounds.size]; + } - UIImage *backgroundImage = nil; - if (delegateBackgroundImage != nil) { - backgroundImage = delegateBackgroundImage; - } else if (button.type == CalendarButtonTypeSelected) { - backgroundImage = button.isInitialDay ? [self initialDayBackgroundImage] : [self selectedBackgroundImage]; - } else if ([button isForToday]) { - backgroundImage = [self todayBackgroundImage]; - } + UIImage *backgroundImage = nil; + if (delegateBackgroundImage != nil) { + backgroundImage = delegateBackgroundImage; + } else if (button.type == CalendarButtonTypeSelected) { + backgroundImage = button.isInitialDay ? [self initialDayBackgroundImage] : [self selectedBackgroundImage]; + } else if ([button isForToday]) { + backgroundImage = [self todayBackgroundImage]; + } - [button setBackgroundImage:backgroundImage forState:UIControlStateNormal]; + [button setBackgroundImage:backgroundImage forState:UIControlStateNormal]; + } } - (void)updateTitleForButton:(TSQCalendarDayButton *)button @@ -345,6 +348,8 @@ - (void)updateTitleForButton:(TSQCalendarDayButton *)button return; } + + [self updateBackgroundImageForButton:button]; NSString *title = [self.dayFormatter stringFromDate:date]; [button setTitle:title forState:UIControlStateNormal]; From 3dbfb7fbba9cba41bb5d4cb040c30fae8d252129 Mon Sep 17 00:00:00 2001 From: Malcolm Goldiner Date: Mon, 29 Jun 2020 13:26:21 -0700 Subject: [PATCH 83/92] fix(current day): fine tune showing background image for current day to prevent duplicate --- TimesSquare/TSQCalendarRowCell.m | 6 +++--- TimesSquare/TSQCalendarView.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index a0d32a3..7f606d9 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -318,13 +318,13 @@ - (void)updateAppearanceForButton:(TSQCalendarDayButton *)button - (void)updateBackgroundImageForButton:(TSQCalendarDayButton *)button { - if (button.type != CalendarButtonTypeOtherMonth) + if (button.type != CalendarButtonTypeOtherMonth && button.isInitialDay) { NSDate *date = button.day; UIImage *delegateBackgroundImage = nil; - if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:backgroundImageForDate:size:)]) { - delegateBackgroundImage = [self.calendarView.delegate calendarView:self.calendarView backgroundImageForDate:date size:button.bounds.size]; + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:backgroundImageForDate:size:isInThisMonth:)]) { + delegateBackgroundImage = [self.calendarView.delegate calendarView:self.calendarView backgroundImageForDate:date size:button.bounds.size isInThisMonth:button.type == CalendarButtonTypeOtherMonth]; } UIImage *backgroundImage = nil; diff --git a/TimesSquare/TSQCalendarView.h b/TimesSquare/TSQCalendarView.h index cda4988..ef9b8e7 100644 --- a/TimesSquare/TSQCalendarView.h +++ b/TimesSquare/TSQCalendarView.h @@ -171,7 +171,7 @@ - (UIColor*)calendarView: (TSQCalendarView *)calendarView selectedDateColorForDate: (NSDate*) date; -- (UIImage*)calendarView: (TSQCalendarView *)calendarView backgroundImageForDate: (NSDate*) date size:(CGSize)size; +- (UIImage*)calendarView: (TSQCalendarView *)calendarView backgroundImageForDate: (NSDate*) date size:(CGSize)size isInThisMonth:(BOOL)thisMonth; - (NSDictionary*)calendarView: (TSQCalendarView *)calendarView additionalDateTextAttributesForDate: (NSDate*) date; From 5ea08b0528f9243acb141574108c91805f8271ae Mon Sep 17 00:00:00 2001 From: Malcolm Goldiner Date: Mon, 29 Jun 2020 13:32:32 -0700 Subject: [PATCH 84/92] fix(duplicate icons): use parameter for current month --- TimesSquare/TSQCalendarRowCell.m | 35 +++++++++++++++----------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 7f606d9..3e38977 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -318,26 +318,23 @@ - (void)updateAppearanceForButton:(TSQCalendarDayButton *)button - (void)updateBackgroundImageForButton:(TSQCalendarDayButton *)button { - if (button.type != CalendarButtonTypeOtherMonth && button.isInitialDay) - { - NSDate *date = button.day; - - UIImage *delegateBackgroundImage = nil; - if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:backgroundImageForDate:size:isInThisMonth:)]) { - delegateBackgroundImage = [self.calendarView.delegate calendarView:self.calendarView backgroundImageForDate:date size:button.bounds.size isInThisMonth:button.type == CalendarButtonTypeOtherMonth]; - } - - UIImage *backgroundImage = nil; - if (delegateBackgroundImage != nil) { - backgroundImage = delegateBackgroundImage; - } else if (button.type == CalendarButtonTypeSelected) { - backgroundImage = button.isInitialDay ? [self initialDayBackgroundImage] : [self selectedBackgroundImage]; - } else if ([button isForToday]) { - backgroundImage = [self todayBackgroundImage]; - } - - [button setBackgroundImage:backgroundImage forState:UIControlStateNormal]; + NSDate *date = button.day; + + UIImage *delegateBackgroundImage = nil; + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:backgroundImageForDate:size:isInThisMonth:)]) { + delegateBackgroundImage = [self.calendarView.delegate calendarView:self.calendarView backgroundImageForDate:date size:button.bounds.size isInThisMonth:button.type != CalendarButtonTypeOtherMonth]; } + + UIImage *backgroundImage = nil; + if (delegateBackgroundImage != nil) { + backgroundImage = delegateBackgroundImage; + } else if (button.type == CalendarButtonTypeSelected) { + backgroundImage = button.isInitialDay ? [self initialDayBackgroundImage] : [self selectedBackgroundImage]; + } else if ([button isForToday]) { + backgroundImage = [self todayBackgroundImage]; + } + + [button setBackgroundImage:backgroundImage forState:UIControlStateNormal]; } - (void)updateTitleForButton:(TSQCalendarDayButton *)button From a79856cfc9d088caf52d4366a7cbb03ec8f680b0 Mon Sep 17 00:00:00 2001 From: Malcolm Goldiner Date: Mon, 29 Jun 2020 14:10:08 -0700 Subject: [PATCH 85/92] fix(duplicate background): fix this month logic for current day --- TimesSquare/TSQCalendarRowCell.m | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 3e38977..624860d 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -322,7 +322,13 @@ - (void)updateBackgroundImageForButton:(TSQCalendarDayButton *)button UIImage *delegateBackgroundImage = nil; if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:backgroundImageForDate:size:isInThisMonth:)]) { - delegateBackgroundImage = [self.calendarView.delegate calendarView:self.calendarView backgroundImageForDate:date size:button.bounds.size isInThisMonth:button.type != CalendarButtonTypeOtherMonth]; + + + BOOL thisMonth = button.type != CalendarButtonTypeOtherMonth || (button.type == button.isInitialDay && button.isSelected); + + NSLog(@"%ld", (long)button.buttonType); + + delegateBackgroundImage = [self.calendarView.delegate calendarView:self.calendarView backgroundImageForDate:date size:button.bounds.size isInThisMonth:thisMonth]; } UIImage *backgroundImage = nil; From 17093307a3491a59881c51332edbbf98d8bccb5f Mon Sep 17 00:00:00 2001 From: Malcolm Goldiner Date: Mon, 29 Jun 2020 14:33:49 -0700 Subject: [PATCH 86/92] fix(initial day): remove logging and set background image again for initial day after selection --- TimesSquare/TSQCalendarRowCell.m | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 624860d..1b685bf 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -322,11 +322,7 @@ - (void)updateBackgroundImageForButton:(TSQCalendarDayButton *)button UIImage *delegateBackgroundImage = nil; if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:backgroundImageForDate:size:isInThisMonth:)]) { - - - BOOL thisMonth = button.type != CalendarButtonTypeOtherMonth || (button.type == button.isInitialDay && button.isSelected); - - NSLog(@"%ld", (long)button.buttonType); + BOOL thisMonth = button.type != CalendarButtonTypeOtherMonth; delegateBackgroundImage = [self.calendarView.delegate calendarView:self.calendarView backgroundImageForDate:date size:button.bounds.size isInThisMonth:thisMonth]; } @@ -351,8 +347,6 @@ - (void)updateTitleForButton:(TSQCalendarDayButton *)button return; } - - [self updateBackgroundImageForButton:button]; NSString *title = [self.dayFormatter stringFromDate:date]; [button setTitle:title forState:UIControlStateNormal]; @@ -576,9 +570,14 @@ - (void)setBottomRow:(BOOL)bottomRow; - (IBAction)dateButtonPressed:(id)sender; { + BOOL initialNilDateState = self.calendarView.selectedDate == nil; TSQCalendarDayButton *dayButton = (TSQCalendarDayButton *)sender; NSDate *selectedDate = dayButton.day; self.calendarView.selectedDate = selectedDate; + + if (initialNilDateState && dayButton.isInitialDay) { + [self updateBackgroundImageForButton:dayButton]; + } } - (void)layoutSubviews; From fd80e2f3bce0bb9a88db2df3943e83d507102d53 Mon Sep 17 00:00:00 2001 From: Malcolm Goldiner Date: Mon, 29 Jun 2020 14:40:26 -0700 Subject: [PATCH 87/92] fix(duplicate): fix current day selection --- TimesSquare/TSQCalendarRowCell.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 1b685bf..d5b3b71 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -575,7 +575,7 @@ - (IBAction)dateButtonPressed:(id)sender; NSDate *selectedDate = dayButton.day; self.calendarView.selectedDate = selectedDate; - if (initialNilDateState && dayButton.isInitialDay) { + if (initialNilDateState && [dayButton.day isEqualToDate:self.calendarView.initialDate]) { [self updateBackgroundImageForButton:dayButton]; } } From 61c8a9b4235ebbd05c7e3e8c94b94ba3d6e8077e Mon Sep 17 00:00:00 2001 From: Malcolm Goldiner Date: Tue, 30 Jun 2020 17:20:44 -0700 Subject: [PATCH 88/92] fix(deselection): clean up selection state setting and add function for deselecting previously selected cell and getting the new background image --- TimesSquare/TSQCalendarRowCell.h | 2 ++ TimesSquare/TSQCalendarRowCell.m | 43 ++++++++++++++++---------------- TimesSquare/TSQCalendarView.h | 2 +- TimesSquare/TSQCalendarView.m | 1 + 4 files changed, 25 insertions(+), 23 deletions(-) diff --git a/TimesSquare/TSQCalendarRowCell.h b/TimesSquare/TSQCalendarRowCell.h index a62a99d..e272a5e 100644 --- a/TimesSquare/TSQCalendarRowCell.h +++ b/TimesSquare/TSQCalendarRowCell.h @@ -123,4 +123,6 @@ This is white by default. */ - (void)selectColumnForInitialDate:(NSDate *)date; +- (void)deselectColumnForDate:(NSDate *)date; + @end diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index d5b3b71..1b995ea 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -316,27 +316,19 @@ - (void)updateAppearanceForButton:(TSQCalendarDayButton *)button button.iconImageView.tintColor = iconTintColor; } -- (void)updateBackgroundImageForButton:(TSQCalendarDayButton *)button +- (void)updateBackgroundImageForButton:(TSQCalendarDayButton *)button isSelected:(BOOL)isSelected { NSDate *date = button.day; UIImage *delegateBackgroundImage = nil; - if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:backgroundImageForDate:size:isInThisMonth:)]) { + if ([self.calendarView.delegate respondsToSelector:@selector(calendarView:backgroundImageForDate:size:isInThisMonth:isSelected:)]) { BOOL thisMonth = button.type != CalendarButtonTypeOtherMonth; - delegateBackgroundImage = [self.calendarView.delegate calendarView:self.calendarView backgroundImageForDate:date size:button.bounds.size isInThisMonth:thisMonth]; + delegateBackgroundImage = [self.calendarView.delegate calendarView:self.calendarView backgroundImageForDate:date size:button.bounds.size isInThisMonth:thisMonth isSelected:isSelected]; } - UIImage *backgroundImage = nil; - if (delegateBackgroundImage != nil) { - backgroundImage = delegateBackgroundImage; - } else if (button.type == CalendarButtonTypeSelected) { - backgroundImage = button.isInitialDay ? [self initialDayBackgroundImage] : [self selectedBackgroundImage]; - } else if ([button isForToday]) { - backgroundImage = [self todayBackgroundImage]; - } - - [button setBackgroundImage:backgroundImage forState:UIControlStateNormal]; + + [button setBackgroundImage:delegateBackgroundImage forState:UIControlStateNormal]; } - (void)updateTitleForButton:(TSQCalendarDayButton *)button @@ -346,8 +338,8 @@ - (void)updateTitleForButton:(TSQCalendarDayButton *)button if (date == nil) { return; } - - [self updateBackgroundImageForButton:button]; + + [self updateBackgroundImageForButton:button isSelected:self.selectedButton == button]; NSString *title = [self.dayFormatter stringFromDate:date]; [button setTitle:title forState:UIControlStateNormal]; [button setTitle:title forState:UIControlStateDisabled]; @@ -570,14 +562,10 @@ - (void)setBottomRow:(BOOL)bottomRow; - (IBAction)dateButtonPressed:(id)sender; { - BOOL initialNilDateState = self.calendarView.selectedDate == nil; TSQCalendarDayButton *dayButton = (TSQCalendarDayButton *)sender; NSDate *selectedDate = dayButton.day; self.calendarView.selectedDate = selectedDate; - - if (initialNilDateState && [dayButton.day isEqualToDate:self.calendarView.initialDate]) { - [self updateBackgroundImageForButton:dayButton]; - } + [self updateBackgroundImageForButton:dayButton isSelected:YES]; } - (void)layoutSubviews; @@ -615,7 +603,7 @@ - (void)layoutViewsForColumnAtIndex:(NSUInteger)index inRect:(CGRect)rect; if (CGRectEqualToRect(button.frame, rect) == NO) { button.frame = rect; // image views are dependant on button size so they need to be regenerated - [self updateBackgroundImageForButton:button]; + [self updateBackgroundImageForButton:button isSelected:[self.calendarView.selectedDate isEqualToDate:button.day]]; } } } @@ -625,6 +613,17 @@ - (void)selectColumnForDate:(NSDate *)date; [self selectColumnForDate:date isInitialDay:NO]; } +- (void)deselectColumnForDate:(NSDate *)date +{ + for (TSQCalendarDayButton *button in self.dayButtons) { + if ([button.day isEqualToDate:date]) + { + [self updateBackgroundImageForButton:button isSelected:NO]; + break; + } + } +} + - (void)selectColumnForInitialDate:(NSDate *)date { [self selectColumnForDate:date isInitialDay:YES]; @@ -660,7 +659,7 @@ - (void)selectColumnForDate:(NSDate *)date isInitialDay:(BOOL)isInitialDay [self updateSubtitlesForButton:self.selectedButton]; // update background image - [self updateBackgroundImageForButton:self.selectedButton]; + [self updateBackgroundImageForButton:self.selectedButton isSelected:NO]; // update selected button text self.selectedButton.hidden = NO; diff --git a/TimesSquare/TSQCalendarView.h b/TimesSquare/TSQCalendarView.h index ef9b8e7..2dd54ff 100644 --- a/TimesSquare/TSQCalendarView.h +++ b/TimesSquare/TSQCalendarView.h @@ -171,7 +171,7 @@ - (UIColor*)calendarView: (TSQCalendarView *)calendarView selectedDateColorForDate: (NSDate*) date; -- (UIImage*)calendarView: (TSQCalendarView *)calendarView backgroundImageForDate: (NSDate*) date size:(CGSize)size isInThisMonth:(BOOL)thisMonth; +- (UIImage*)calendarView: (TSQCalendarView *)calendarView backgroundImageForDate: (NSDate*) date size:(CGSize)size isInThisMonth:(BOOL)thisMonth isSelected:(BOOL)isSelected; - (NSDictionary*)calendarView: (TSQCalendarView *)calendarView additionalDateTextAttributesForDate: (NSDate*) date; diff --git a/TimesSquare/TSQCalendarView.m b/TimesSquare/TSQCalendarView.m index 58770be..5c499f5 100644 --- a/TimesSquare/TSQCalendarView.m +++ b/TimesSquare/TSQCalendarView.m @@ -156,6 +156,7 @@ - (void)setInitialDate:(NSDate *)initialDate - (void)updateSelectedDate:(NSDate *)date isInitialDate:(BOOL)isInitialDate { + [[self cellForRowAtDate:_selectedDate] deselectColumnForDate:self.selectedDate]; // clear existing selected cells [[self cellForRowAtDate:_selectedDate] selectColumnForDate:nil]; [[self cellForRowAtDate:_initialDate] selectColumnForDate:nil]; From 523f2d46a425724f3cd16f97e0be6b4b0928a4cb Mon Sep 17 00:00:00 2001 From: Malcolm Goldiner Date: Wed, 1 Jul 2020 09:57:45 -0700 Subject: [PATCH 89/92] fix(selection): consistent selection check --- TimesSquare/TSQCalendarRowCell.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 1b995ea..5001715 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -339,7 +339,7 @@ - (void)updateTitleForButton:(TSQCalendarDayButton *)button return; } - [self updateBackgroundImageForButton:button isSelected:self.selectedButton == button]; + [self updateBackgroundImageForButton:button isSelected:[self.calendarView.selectedDate isEqualToDate:button.day]]; NSString *title = [self.dayFormatter stringFromDate:date]; [button setTitle:title forState:UIControlStateNormal]; [button setTitle:title forState:UIControlStateDisabled]; From a6e92a33749f8e80ed0cdff7215f55312331f031 Mon Sep 17 00:00:00 2001 From: Jagdeep Manik Date: Tue, 25 Jan 2022 17:06:50 -0800 Subject: [PATCH 90/92] fix(crash): Fixed exception due to adding nil to array --- TimesSquare/TSQCalendarRowCell.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 5001715..69a08ca 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -595,7 +595,7 @@ - (void)layoutViewsForColumnAtIndex:(NSUInteger)index inRect:(CGRect)rect; if (index < self.notThisMonthButtons.count) { [buttons addObject:self.notThisMonthButtons[index]]; } - if (self.indexOfSelectedButton == (NSInteger)index) { + if (self.indexOfSelectedButton == (NSInteger)index && self.selectedButton) { [buttons addObject:self.selectedButton]; } From 46e34914e4dc1ddd877f9ff5846e02724437c995 Mon Sep 17 00:00:00 2001 From: Jagdeep Manik Date: Wed, 26 Jan 2022 11:41:43 -0800 Subject: [PATCH 91/92] build: Updated project settings for best xcframework support --- TimesSquare.xcodeproj/project.pbxproj | 23 +++++++++++----- .../TimesSquare Documentation.xcscheme | 8 +----- .../xcschemes/TimesSquare-iOS.xcscheme | 26 +++++++------------ .../xcschemes/TimesSquare.xcscheme | 8 +----- 4 files changed, 28 insertions(+), 37 deletions(-) diff --git a/TimesSquare.xcodeproj/project.pbxproj b/TimesSquare.xcodeproj/project.pbxproj index 40ad1ec..acf3560 100644 --- a/TimesSquare.xcodeproj/project.pbxproj +++ b/TimesSquare.xcodeproj/project.pbxproj @@ -275,7 +275,7 @@ A806805216700FD70071C71E /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0920; + LastUpgradeCheck = 1320; ORGANIZATIONNAME = Square; TargetAttributes = { 5C4733981AC3575B00269A66 = { @@ -288,6 +288,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, ); mainGroup = A806805016700FD70071C71E; @@ -370,7 +371,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; INFOPLIST_FILE = "TimesSquare-iOS/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; @@ -378,7 +379,6 @@ PRODUCT_NAME = TimesSquare; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; - VALID_ARCHS = "arm64 armv7 armv7s i386"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; @@ -412,14 +412,13 @@ GCC_WARN_UNUSED_FUNCTION = YES; INFOPLIST_FILE = "TimesSquare-iOS/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.square.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = TimesSquare; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; - VALID_ARCHS = "arm64 armv7 armv7s i386"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; @@ -429,18 +428,22 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -466,7 +469,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; ONLY_ACTIVE_ARCH = YES; PUBLIC_HEADERS_FOLDER_PATH = "include/$(PRODUCT_NAME)"; RUN_CLANG_STATIC_ANALYZER = YES; @@ -478,18 +481,22 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -507,7 +514,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; PUBLIC_HEADERS_FOLDER_PATH = "include/$(PRODUCT_NAME)"; RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = iphoneos; @@ -544,6 +551,7 @@ A81E05F91682A0E000E79A2B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; DEBUGGING_SYMBOLS = YES; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; @@ -560,6 +568,7 @@ A81E05FA1682A0E000E79A2B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; diff --git a/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare Documentation.xcscheme b/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare Documentation.xcscheme index 358a044..b461875 100644 --- a/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare Documentation.xcscheme +++ b/TimesSquare.xcodeproj/xcshareddata/xcschemes/TimesSquare Documentation.xcscheme @@ -1,6 +1,6 @@ - - - - + + + + @@ -54,23 +62,11 @@ - - - - - - - - - - - - Date: Wed, 26 Jan 2022 12:00:26 -0800 Subject: [PATCH 92/92] fix(ios15): Renamed variable to avoid clash with iOS 15 subtitle label --- TimesSquare/TSQCalendarDayButton.h | 2 +- TimesSquare/TSQCalendarDayButton.m | 36 +++++++++++++++--------------- TimesSquare/TSQCalendarRowCell.m | 8 +++---- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/TimesSquare/TSQCalendarDayButton.h b/TimesSquare/TSQCalendarDayButton.h index abdde6c..be43110 100644 --- a/TimesSquare/TSQCalendarDayButton.h +++ b/TimesSquare/TSQCalendarDayButton.h @@ -20,7 +20,7 @@ typedef NS_ENUM(NSInteger, CalendarButtonType) { @property (nonatomic, assign) CalendarButtonType type; @property (nonatomic, strong) NSDate *day; -@property (nonatomic, strong) UILabel *subtitleLabel; +@property (nonatomic, strong) UILabel *tsqSubtitleLabel; @property (nonatomic, strong) UILabel *subtitleSymbolLabel; @property (nonatomic, strong) UIImageView *iconImageView; diff --git a/TimesSquare/TSQCalendarDayButton.m b/TimesSquare/TSQCalendarDayButton.m index 31116c2..d10a034 100644 --- a/TimesSquare/TSQCalendarDayButton.m +++ b/TimesSquare/TSQCalendarDayButton.m @@ -21,12 +21,12 @@ - (instancetype)initWithFrame:(CGRect)frame self.type = CalendarButtonTypeNormalDay; [self setTitleEdgeInsets:UIEdgeInsetsMake(-10, 0, 0, 0)]; - self.subtitleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; - self.subtitleLabel.textAlignment = NSTextAlignmentCenter; - self.subtitleLabel.userInteractionEnabled = NO; - self.subtitleLabel.adjustsFontSizeToFitWidth = NO; - self.subtitleLabel.lineBreakMode = NSLineBreakByTruncatingTail; - [self addSubview:self.subtitleLabel]; + self.tsqSubtitleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + self.tsqSubtitleLabel.textAlignment = NSTextAlignmentCenter; + self.tsqSubtitleLabel.userInteractionEnabled = NO; + self.tsqSubtitleLabel.adjustsFontSizeToFitWidth = NO; + self.tsqSubtitleLabel.lineBreakMode = NSLineBreakByTruncatingTail; + [self addSubview:self.tsqSubtitleLabel]; self.subtitleSymbolLabel = [[UILabel alloc] initWithFrame:CGRectZero]; self.subtitleSymbolLabel.userInteractionEnabled = NO; @@ -53,17 +53,17 @@ - (void)layoutSubviews CGFloat midX = CGRectGetMidX(self.bounds); CGFloat subtitleCenterY = 0.75f * CGRectGetMaxY(self.bounds); - self.subtitleLabel.hidden = !([self.subtitleLabel.text length] > 0); + self.tsqSubtitleLabel.hidden = !([self.tsqSubtitleLabel.text length] > 0); self.subtitleSymbolLabel.hidden = !([self.subtitleSymbolLabel.text length] > 0); self.iconImageView.hidden = (self.iconImageView.image == nil); CGFloat iconWidth = self.iconImageView.image.size.width; CGFloat iconHeight = self.iconImageView.image.size.height; - if (! self.subtitleLabel.hidden) + if (! self.tsqSubtitleLabel.hidden) { CGSize maxSubtitleSize = [self maxSubtitleSize]; - CGSize sizeThatFits = [self.subtitleLabel sizeThatFits:maxSubtitleSize]; + CGSize sizeThatFits = [self.tsqSubtitleLabel sizeThatFits:maxSubtitleSize]; CGFloat subtitleWidth = fminf(sizeThatFits.width, maxSubtitleSize.width); CGFloat subtitleHeight = fminf(sizeThatFits.height, maxSubtitleSize.height); @@ -74,7 +74,7 @@ - (void)layoutSubviews floorf(originY), subtitleWidth, subtitleHeight); - self.subtitleLabel.frame = CGRectIntegral(subtitleFrame); + self.tsqSubtitleLabel.frame = CGRectIntegral(subtitleFrame); } if (! self.subtitleSymbolLabel.hidden) @@ -87,11 +87,11 @@ - (void)layoutSubviews CGFloat originX = CGRectGetMaxX(self.bounds) - TSQCalendarRowCellSubtitleBuffer; CGFloat originY = subtitleCenterY - symbolHeight/2.0f; - if (! self.subtitleLabel.hidden) + if (! self.tsqSubtitleLabel.hidden) { // when subtitle is showing, shift symbol to right of subtitle CGFloat symbolBuffer = (TSQCalendarRowCellSubtitleBuffer - symbolWidth)/2.0f; - originX = CGRectGetMaxX(self.subtitleLabel.frame) + symbolBuffer; + originX = CGRectGetMaxX(self.tsqSubtitleLabel.frame) + symbolBuffer; } CGRect symbolFrame = CGRectMake(floorf(originX), @@ -108,11 +108,11 @@ - (void)layoutSubviews CGFloat originX = midX - iconWidth/2.0f; CGFloat originY = subtitleCenterY - iconHeight/2.0f; - if (! self.subtitleLabel.hidden) + if (! self.tsqSubtitleLabel.hidden) { // when subtitle is showing, shift icon to left of subtitle CGFloat iconBuffer = (TSQCalendarRowCellSubtitleBuffer - iconWidth)/2.0f; - originX = self.subtitleLabel.frame.origin.x - iconWidth - iconBuffer; + originX = self.tsqSubtitleLabel.frame.origin.x - iconWidth - iconBuffer; } CGRect iconFrame = CGRectMake(floorf(originX), @@ -127,12 +127,12 @@ - (void)layoutSubviews - (void)registerForNotifications { - [self.subtitleLabel addObserver:self + [self.tsqSubtitleLabel addObserver:self forKeyPath:@"font" options:NSKeyValueObservingOptionNew context:nil]; - [self.subtitleLabel addObserver:self + [self.tsqSubtitleLabel addObserver:self forKeyPath:@"text" options:NSKeyValueObservingOptionNew context:nil]; @@ -155,8 +155,8 @@ - (void)registerForNotifications - (void)unregisterForNotifications { - [self.subtitleLabel removeObserver:self forKeyPath:@"font"]; - [self.subtitleLabel removeObserver:self forKeyPath:@"text"]; + [self.tsqSubtitleLabel removeObserver:self forKeyPath:@"font"]; + [self.tsqSubtitleLabel removeObserver:self forKeyPath:@"text"]; [self.subtitleSymbolLabel removeObserver:self forKeyPath:@"font"]; [self.subtitleSymbolLabel removeObserver:self forKeyPath:@"text"]; [self.iconImageView removeObserver:self forKeyPath:@"image"]; diff --git a/TimesSquare/TSQCalendarRowCell.m b/TimesSquare/TSQCalendarRowCell.m index 69a08ca..1d4538b 100644 --- a/TimesSquare/TSQCalendarRowCell.m +++ b/TimesSquare/TSQCalendarRowCell.m @@ -115,7 +115,7 @@ - (void)configureButton:(TSQCalendarDayButton *)button [self updateAppearanceForButton:button]; button.titleLabel.font = [self dayOfMonthFont]; - button.subtitleLabel.font = [self subtitleFont]; + button.tsqSubtitleLabel.font = [self subtitleFont]; button.subtitleSymbolLabel.font = [self subtitleFont]; button.titleLabel.shadowOffset = self.shadowOffset; button.adjustsImageWhenDisabled = NO; @@ -481,9 +481,9 @@ - (void)updateSubtitlesForButton:(TSQCalendarDayButton *)button } } - button.subtitleLabel.text = subtitle; + button.tsqSubtitleLabel.text = subtitle; button.subtitleSymbolLabel.text = subtitleSymbol; - button.subtitleLabel.textColor = subtitleColor; + button.tsqSubtitleLabel.textColor = subtitleColor; button.subtitleSymbolLabel.textColor = subtitleColor; } @@ -665,7 +665,7 @@ - (void)selectColumnForDate:(NSDate *)date isInitialDay:(BOOL)isInitialDay self.selectedButton.hidden = NO; self.selectedButton.enabled = YES; [self updateTitleForButton:self.selectedButton]; - self.selectedButton.subtitleLabel.text = dayButton.subtitleLabel.text; + self.selectedButton.tsqSubtitleLabel.text = dayButton.tsqSubtitleLabel.text; self.selectedButton.subtitleSymbolLabel.text = dayButton.subtitleSymbolLabel.text; } else { self.selectedButton.hidden = YES;