-
Notifications
You must be signed in to change notification settings - Fork 237
Show an event marker for particular dates #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| // | ||
| // TSQCalendarButton.h | ||
| // TimesSquare | ||
| // | ||
| // Created by Simon Booth on 10/05/2013. | ||
| // Licensed to Square, Inc. under one or more contributor license agreements. | ||
| // See the LICENSE file distributed with this work for the terms under | ||
| // which Square, Inc. licenses this file to you. | ||
|
|
||
|
|
||
| #import <UIKit/UIKit.h> | ||
| #import "TSQCalendarRowCell.h" | ||
|
|
||
| /** The `TSQCalendarRowButton` class is a button that represents single day in the calendar. | ||
|
|
||
| The button contains an additional label which is used to display an event marker. | ||
| */ | ||
| @interface TSQCalendarRowButton : UIButton | ||
|
|
||
| /** A label used to display an event marker | ||
|
|
||
| The marker is shown using the bullet character '•' | ||
|
|
||
| */ | ||
| @property (nonatomic, strong, readonly) UILabel *subtitleLabel; | ||
|
|
||
| /** Configures the button according to the given row's properties | ||
|
|
||
| The button is set up using the text color and shadow offset of the row | ||
|
|
||
| */ | ||
| - (void)configureWithRowCell:(TSQCalendarRowCell *)rowCell; | ||
|
|
||
| @end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| // | ||
| // TSQCalendarButton.m | ||
| // TimesSquare | ||
| // | ||
| // Created by Simon Booth on 10/05/2013. | ||
| // Licensed to Square, Inc. under one or more contributor license agreements. | ||
| // See the LICENSE file distributed with this work for the terms under | ||
| // which Square, Inc. licenses this file to you. | ||
|
|
||
| #import "TSQCalendarRowButton.h" | ||
|
|
||
|
|
||
| @implementation TSQCalendarRowButton | ||
|
|
||
| - (id)initWithFrame:(CGRect)frame; | ||
| { | ||
| self = [super initWithFrame:frame]; | ||
| if (self) { | ||
| self.titleLabel.font = [UIFont boldSystemFontOfSize:19.f]; | ||
| self.adjustsImageWhenDisabled = NO; | ||
| [self setTitleShadowColor:[UIColor whiteColor] forState:UIControlStateNormal]; | ||
|
|
||
| _subtitleLabel = [[UILabel alloc] init]; | ||
| _subtitleLabel.backgroundColor = [UIColor clearColor]; | ||
| _subtitleLabel.font = self.titleLabel.font; | ||
| _subtitleLabel.textAlignment = UITextAlignmentCenter; | ||
| [self addSubview:_subtitleLabel]; | ||
|
|
||
| [self updateSubtitleLabel]; | ||
| } | ||
| return self; | ||
| } | ||
|
|
||
| - (void)configureWithRowCell:(TSQCalendarRowCell *)rowCell; | ||
| { | ||
| [self setTitleColor:rowCell.textColor forState:UIControlStateNormal]; | ||
| self.titleLabel.shadowOffset = rowCell.shadowOffset; | ||
| [self updateSubtitleLabel]; | ||
| } | ||
|
|
||
| - (void)layoutSubviews; | ||
| { | ||
| [super layoutSubviews]; | ||
|
|
||
| CGRect subtitleFrame = self.bounds; | ||
| subtitleFrame.origin.y = subtitleFrame.size.height - 15; | ||
| subtitleFrame.size.height = 15; | ||
| self.subtitleLabel.frame = subtitleFrame; | ||
| } | ||
|
|
||
| - (void)updateSubtitleLabel; | ||
| { | ||
| self.subtitleLabel.textColor = self.currentTitleColor; | ||
| self.subtitleLabel.shadowColor = self.currentTitleShadowColor; | ||
| self.subtitleLabel.shadowOffset = self.titleLabel.shadowOffset; | ||
| } | ||
|
|
||
| - (void)setTitleShadowColor:(UIColor *)color forState:(UIControlState)state; | ||
| { | ||
| [super setTitleShadowColor:color forState:state]; | ||
| [self updateSubtitleLabel]; | ||
| } | ||
|
|
||
| - (void)setTitleColor:(UIColor *)color forState:(UIControlState)state; | ||
| { | ||
| [super setTitleColor:color forState:state]; | ||
| [self updateSubtitleLabel]; | ||
| } | ||
|
|
||
| - (void)setHighlighted:(BOOL)highlighted; | ||
| { | ||
| [super setHighlighted:highlighted]; | ||
| [self updateSubtitleLabel]; | ||
| } | ||
|
|
||
| - (void)setSelected:(BOOL)selected; | ||
| { | ||
| [super setSelected:selected]; | ||
| [self updateSubtitleLabel]; | ||
| } | ||
|
|
||
| @end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,14 +9,14 @@ | |
|
|
||
| #import "TSQCalendarRowCell.h" | ||
| #import "TSQCalendarView.h" | ||
|
|
||
| #import "TSQCalendarRowButton.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) TSQCalendarRowButton *todayButton; | ||
| @property (nonatomic, strong) TSQCalendarRowButton *selectedButton; | ||
|
|
||
| @property (nonatomic, assign) NSInteger indexOfTodayButton; | ||
| @property (nonatomic, assign) NSInteger indexOfSelectedButton; | ||
|
|
@@ -42,24 +42,23 @@ - (id)initWithCalendar:(NSCalendar *)calendar reuseIdentifier:(NSString *)reuseI | |
| return self; | ||
| } | ||
|
|
||
| - (void)configureButton:(UIButton *)button; | ||
| - (Class)rowButtonClass; | ||
| { | ||
| button.titleLabel.font = [UIFont boldSystemFontOfSize:19.f]; | ||
| button.titleLabel.shadowOffset = self.shadowOffset; | ||
| button.adjustsImageWhenDisabled = NO; | ||
| [button setTitleColor:self.textColor forState:UIControlStateNormal]; | ||
| [button setTitleShadowColor:[UIColor whiteColor] forState:UIControlStateNormal]; | ||
| if (!_rowButtonClass) { | ||
| self.rowButtonClass = [TSQCalendarRowButton class]; | ||
| } | ||
| return _rowButtonClass; | ||
| } | ||
|
|
||
| - (void)createDayButtons; | ||
| { | ||
| NSMutableArray *dayButtons = [NSMutableArray arrayWithCapacity:self.daysInWeek]; | ||
| for (NSUInteger index = 0; index < self.daysInWeek; index++) { | ||
| UIButton *button = [[UIButton alloc] initWithFrame:self.contentView.bounds]; | ||
| TSQCalendarRowButton *button = [[self.rowButtonClass alloc] initWithFrame:self.contentView.bounds]; | ||
| [button addTarget:self action:@selector(dateButtonPressed:) forControlEvents:UIControlEventTouchDown]; | ||
| [dayButtons addObject:button]; | ||
| [self.contentView addSubview:button]; | ||
| [self configureButton:button]; | ||
| [button configureWithRowCell:self]; | ||
| [button setTitleColor:[self.textColor colorWithAlphaComponent:0.5f] forState:UIControlStateDisabled]; | ||
| } | ||
| self.dayButtons = dayButtons; | ||
|
|
@@ -69,10 +68,10 @@ - (void)createNotThisMonthButtons; | |
| { | ||
| NSMutableArray *notThisMonthButtons = [NSMutableArray arrayWithCapacity:self.daysInWeek]; | ||
| for (NSUInteger index = 0; index < self.daysInWeek; index++) { | ||
| UIButton *button = [[UIButton alloc] initWithFrame:self.contentView.bounds]; | ||
| TSQCalendarRowButton *button = [[self.rowButtonClass alloc] initWithFrame:self.contentView.bounds]; | ||
| [notThisMonthButtons addObject:button]; | ||
| [self.contentView addSubview:button]; | ||
| [self configureButton:button]; | ||
| [button configureWithRowCell:self]; | ||
|
|
||
| button.enabled = NO; | ||
| UIColor *backgroundPattern = [UIColor colorWithPatternImage:[self notThisMonthBackgroundImage]]; | ||
|
|
@@ -84,9 +83,9 @@ - (void)createNotThisMonthButtons; | |
|
|
||
| - (void)createTodayButton; | ||
| { | ||
| self.todayButton = [[UIButton alloc] initWithFrame:self.contentView.bounds]; | ||
| self.todayButton = [[self.rowButtonClass alloc] initWithFrame:self.contentView.bounds]; | ||
| [self.contentView addSubview:self.todayButton]; | ||
| [self configureButton:self.todayButton]; | ||
| [self.todayButton configureWithRowCell:self]; | ||
| [self.todayButton addTarget:self action:@selector(todayButtonPressed:) forControlEvents:UIControlEventTouchDown]; | ||
|
|
||
| [self.todayButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; | ||
|
|
@@ -98,9 +97,9 @@ - (void)createTodayButton; | |
|
|
||
| - (void)createSelectedButton; | ||
| { | ||
| self.selectedButton = [[UIButton alloc] initWithFrame:self.contentView.bounds]; | ||
| self.selectedButton = [[self.rowButtonClass alloc] initWithFrame:self.contentView.bounds]; | ||
| [self.contentView addSubview:self.selectedButton]; | ||
| [self configureButton:self.selectedButton]; | ||
| [self.selectedButton configureWithRowCell:self]; | ||
|
|
||
| [self.selectedButton setAccessibilityTraits:UIAccessibilityTraitSelected|self.selectedButton.accessibilityTraits]; | ||
|
|
||
|
|
@@ -127,11 +126,14 @@ - (void)setBeginningDate:(NSDate *)date; | |
|
|
||
| for (NSUInteger index = 0; index < self.daysInWeek; index++) { | ||
| NSString *title = [self.dayFormatter stringFromDate:date]; | ||
| NSString *subTitle = [self.calendarView shouldDisplayEventMarkerForDate:date] ? @"•" : nil; | ||
| NSString *accessibilityLabel = [self.accessibilityFormatter stringFromDate:date]; | ||
| [self.dayButtons[index] setTitle:title forState:UIControlStateNormal]; | ||
| [self.dayButtons[index] setAccessibilityLabel:accessibilityLabel]; | ||
| [[self.dayButtons[index] subtitleLabel] setText:subTitle]; | ||
| [self.notThisMonthButtons[index] setTitle:title forState:UIControlStateNormal]; | ||
| [self.notThisMonthButtons[index] setAccessibilityLabel:accessibilityLabel]; | ||
| [[self.notThisMonthButtons[index] subtitleLabel] setText:subTitle]; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (Move these in to that extracted method, too.) |
||
|
|
||
| NSDateComponents *thisDateComponents = [self.calendar components:NSDayCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit fromDate:date]; | ||
|
|
||
|
|
@@ -147,9 +149,10 @@ - (void)setBeginningDate:(NSDate *)date; | |
| self.todayButton.hidden = NO; | ||
| [self.todayButton setTitle:title forState:UIControlStateNormal]; | ||
| [self.todayButton setAccessibilityLabel:accessibilityLabel]; | ||
| [self.todayButton.subtitleLabel setText:subTitle]; | ||
| self.indexOfTodayButton = index; | ||
| } else { | ||
| UIButton *button = self.dayButtons[index]; | ||
| TSQCalendarRowButton *button = self.dayButtons[index]; | ||
| button.enabled = ![self.calendarView.delegate respondsToSelector:@selector(calendarView:shouldSelectDate:)] || [self.calendarView.delegate calendarView:self.calendarView shouldSelectDate:date]; | ||
| button.hidden = NO; | ||
| } | ||
|
|
@@ -209,8 +212,8 @@ - (void)layoutSubviews; | |
|
|
||
| - (void)layoutViewsForColumnAtIndex:(NSUInteger)index inRect:(CGRect)rect; | ||
| { | ||
| UIButton *dayButton = self.dayButtons[index]; | ||
| UIButton *notThisMonthButton = self.notThisMonthButtons[index]; | ||
| TSQCalendarRowButton *dayButton = self.dayButtons[index]; | ||
| TSQCalendarRowButton *notThisMonthButton = self.notThisMonthButtons[index]; | ||
|
|
||
| dayButton.frame = rect; | ||
| notThisMonthButton.frame = rect; | ||
|
|
@@ -246,6 +249,7 @@ - (void)selectColumnForDate:(NSDate *)date; | |
| self.selectedButton.hidden = NO; | ||
| [self.selectedButton setTitle:[self.dayButtons[newIndexOfSelectedButton] currentTitle] forState:UIControlStateNormal]; | ||
| [self.selectedButton setAccessibilityLabel:[self.dayButtons[newIndexOfSelectedButton] accessibilityLabel]]; | ||
| [self.selectedButton.subtitleLabel setText:[[self.dayButtons[newIndexOfSelectedButton] subtitleLabel] text]]; | ||
| } else { | ||
| self.selectedButton.hidden = YES; | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -104,6 +104,15 @@ | |
| */ | ||
| - (void)scrollToDate:(NSDate *)date animated:(BOOL)animated; | ||
|
|
||
| /** Whether a particular date should display an event marker | ||
|
|
||
| This method passes straight through to the delegate | ||
|
|
||
| @param date The date being displayed. | ||
| @return Whether or not the date should display an event marker. | ||
| */ | ||
| - (BOOL)shouldDisplayEventMarkerForDate:(NSDate *)date; | ||
|
|
||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't need to be public, does it?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It needs to be visible from inside TSQCalendarRowCell - it's used at line 128: |
||
| @end | ||
|
|
||
| /** The methods in the `TSQCalendarViewDelegate` protocol allow the adopting delegate to either prevent a day from being selected or respond to it. | ||
|
|
@@ -131,4 +140,14 @@ | |
| */ | ||
| - (void)calendarView:(TSQCalendarView *)calendarView didSelectDate:(NSDate *)date; | ||
|
|
||
| /** @name Displaying event markers */ | ||
|
|
||
| /** Asks the delegate whether a particular date should display an event marker | ||
|
|
||
| @param calendarView The calendar view that is displaying a date. | ||
| @param date The date being displayed. | ||
| @return Whether or not the date should display an event marker. | ||
| */ | ||
| - (BOOL)calendarView:(TSQCalendarView *)calendarView shouldDisplayEventMarkerForDate:(NSDate *)date; | ||
|
|
||
| @end | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you extract this logic out? Have a
-setEventMarkerVisible:(BOOL)visible forColumnAtIndex:(NSUInteger)index;that does this and can be overridden by the subclass.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a look at this, and I ran into a problem in
-[selectColumnForDate:]where the day button's properties get copied to the selected button. Would it be OK instead to change the button class so it had aneventMarkerVisibleproperty?