Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion ASDayPicker.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@

#import <UIKit/UIKit.h>

static NSInteger DAY_PICKER_WEEKDAY_SUNDAY_FIRST = 1;
static NSInteger DAY_PICKER_WEEKDAY_MONDAY_FIRST = 2;

@interface ASDayPicker : UIView

//Custom the first day of the weekday, dufault is sunday
@property (nonatomic, assign) NSInteger firstWeekday;

// Represents the currently selected date. KVO observable.
@property (nonatomic, strong) NSDate *selectedDate;

Expand Down Expand Up @@ -53,10 +58,13 @@

@property (nonatomic, strong) UIColor *selectedDateTextColor;

//Use this array to set color for every date
@property (strong, nonatomic) NSArray *dateCustomColors;

#pragma mark - Helpers

// Returns weekday names truncated to specified length.
// Supply nil for localeIdentifier to use the system language.
+ (NSArray*)weekdayTitlesWithLocaleIdentifier:(NSString*)localeIdentifier length:(NSUInteger)length uppercase:(BOOL)uppercase;
+ (NSArray*)weekdayTitlesWithLocaleIdentifier:(NSString*)localeIdentifier length:(NSUInteger)length uppercase:(BOOL)uppercase firstWeekday:(NSInteger)firstWeekday;

@end
86 changes: 51 additions & 35 deletions ASDayPicker.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,17 @@ @interface ASDayPicker()<UIScrollViewDelegate> {

NSMutableArray *_days;
UIButton *_lastSelectedButton;

NSMutableArray *_dateButtons;
}
@end

@implementation ASDayPicker

- (void)setup {
//set first weekday to sunday
_firstWeekday = DAY_PICKER_WEEKDAY_SUNDAY_FIRST;

_calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

_edgeInsets = kDefaultInsets;
Expand All @@ -59,9 +64,7 @@ - (void)setup {
[self addSubview:l];
}

self.weekdayTitles = [ASDayPicker weekdayTitlesWithLocaleIdentifier:nil
length:1
uppercase:YES];
self.weekdayTitles = [ASDayPicker weekdayTitlesWithLocaleIdentifier:nil length:4 uppercase:YES firstWeekday:_firstWeekday];

self.selectedDateBackgroundImage = [ASDayPicker imageWithColor:self.tintColor];
self.selectedDateTextColor = [UIColor whiteColor];
Expand All @@ -74,6 +77,22 @@ - (void)setup {
[self setSelectedDate:[self dateWithoutTimeFromDate:[NSDate date]] recenter:NO];
}

- (void) resetDateBtnColor {
if (_dateCustomColors != nil && _dateCustomColors.count > 0 && _dateButtons != nil && _dateButtons.count > 0) {
NSInteger i = 0;
while (i < _dateButtons.count && i < _dateCustomColors.count) {
[((UIButton *) _dateButtons[i]) setTitleColor:((UIColor *) _dateCustomColors[i]) forState:UIControlStateNormal];
[((UIButton *) _dateButtons[i]) setTitleColor:((UIColor *) _dateCustomColors[i]) forState:UIControlStateHighlighted];
i++;
}
}
}

- (void) setDateCustomColors:(NSArray *)dateCustomColors {
_dateCustomColors = dateCustomColors;
[self resetDateBtnColor];
}

- (void)setSelectedDate:(NSDate *)selectedDate {
[self setSelectedDate:selectedDate recenter:YES];
}
Expand All @@ -85,7 +104,7 @@ - (void)setSelectedDate:(NSDate *)selectedDate recenter:(BOOL)recenter {
_selectedDate = selectedDate;

NSDateComponents *components = [_calendar components:NSWeekdayCalendarUnit fromDate:_selectedDate];
NSInteger d = components.weekday - 2;
NSInteger d = components.weekday - _firstWeekday;
if (d < 0) d = 7 + d;

_selectedWeekday = d;
Expand Down Expand Up @@ -216,12 +235,20 @@ - (void)dayButtonPressed:(UIButton*)sender {
sender.selected = YES;
_lastSelectedButton = sender;
[self setSelectedDate:_days[sender.tag] recenter:NO];

//set all button color to custom color, and then reset the selected button color
[self resetDateBtnColor];

//record the offset of the selected date for setting the selected weekday color
_scrollStartOffsetX = _daysScrollView.contentOffset.x;
}

- (void)recenter {
for (UIView *v in _daysScrollView.subviews) {
[v removeFromSuperview];
}
_dateButtons = nil;
_dateButtons = [NSMutableArray array];

_days = [NSMutableArray array];

Expand Down Expand Up @@ -260,6 +287,7 @@ - (void)recenter {
_lastSelectedButton = b;
}
[_daysScrollView addSubview:b];
[_dateButtons addObject:b];
}
}

Expand All @@ -268,6 +296,11 @@ - (void)recenter {
_daysScrollView.contentSize = CGSizeMake(pages * self.frame.size.width, self.frame.size.height);

_daysScrollView.contentOffset = CGPointMake(fromIndex != 0 ? self.frame.size.width : 0, 0);

//record the offset of the selected date for setting the selected weekday color
_scrollStartOffsetX = _daysScrollView.contentOffset.x;
//set custom date btn color
[self resetDateBtnColor];
}

- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
Expand All @@ -276,39 +309,16 @@ - (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
NSInteger dir = 0;
CGFloat dx = scrollView.contentOffset.x - _scrollStartOffsetX;
if (dx > 0) {
dir = 1;
} else if (dx < 0 ){
dir = -1;
}

if (dir != 0) {
NSDateComponents *weeks = [[NSDateComponents alloc] init];
weeks.day = dir * 7;
NSDate *date = [_calendar dateByAddingComponents:weeks toDate:_selectedDate options:0];

// Clip to range
if ((_startDate && [date compare:_startDate] == NSOrderedAscending)) {
date = _startDate;
} else if (_endDate && [date compare:_endDate] == NSOrderedDescending) {
date = _endDate;
}

[self setSelectedDate:date recenter:YES];
} else {
// Don't change the selected date automaticlly
if (scrollView.contentOffset.x == _scrollStartOffsetX) {
[UIView animateWithDuration:0.25f animations:^{
((UILabel*)_weekdayLabels[_selectedWeekday]).textColor = _selectedWeekdayTextColor;
[self recolorWeekdays];
}];
}

scrollView.userInteractionEnabled = YES;
}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
_scrollStartOffsetX = scrollView.contentOffset.x;

[UIView animateWithDuration:0.25f animations:^{
((UILabel*)_weekdayLabels[_selectedWeekday]).textColor = _weekdayTextColor;
}];
Expand All @@ -329,7 +339,7 @@ - (NSArray*)daysForWeekAtIndex:(NSInteger)i {
NSDate *d = [_calendar dateByAddingComponents:weeks toDate:_selectedDate options:0];

NSDateComponents *components = [_calendar components:NSWeekdayCalendarUnit fromDate:d];
NSInteger before = components.weekday - 2;
NSInteger before = components.weekday - _firstWeekday;
if (before < 0) before = 7 + before;
NSInteger after = 6 - before;

Expand Down Expand Up @@ -371,7 +381,7 @@ + (UIImage *)imageWithColor:(UIColor *)color {
return image;
}

+ (NSArray*)weekdayTitlesWithLocaleIdentifier:(NSString*)localeIdentifier length:(NSUInteger)length uppercase:(BOOL)uppercase {
+ (NSArray*)weekdayTitlesWithLocaleIdentifier:(NSString*)localeIdentifier length:(NSUInteger)length uppercase:(BOOL)uppercase firstWeekday:(NSInteger)firstWeekday{
// Get weekday titles from current calendar + locale:
NSDateFormatter *df = [[NSDateFormatter alloc] init];
df.locale = [[NSLocale alloc] initWithLocaleIdentifier:localeIdentifier ? localeIdentifier :[[NSLocale preferredLanguages] firstObject]];
Expand All @@ -384,8 +394,14 @@ + (NSArray*)weekdayTitlesWithLocaleIdentifier:(NSString*)localeIdentifier length
[wds addObject:clipped];
}

// ..finally, normalize so monday is at index 0
return [[wds subarrayWithRange:NSMakeRange(1, 6)]
arrayByAddingObjectsFromArray:[wds subarrayWithRange:NSMakeRange(0,1)]];
if (firstWeekday == DAY_PICKER_WEEKDAY_MONDAY_FIRST) {
// ..finally, normalize so monday is at index 0
return [[wds subarrayWithRange:NSMakeRange(1, 6)] arrayByAddingObjectsFromArray:[wds subarrayWithRange:NSMakeRange(0,1)]];
} else if (firstWeekday == DAY_PICKER_WEEKDAY_SUNDAY_FIRST) {
//above is an array of weekday title with monday on the first, but we need the sunday on the first, so just return the wds directly
return wds;
} else {
return wds;
}
}
@end
1 change: 1 addition & 0 deletions ASDayPickerSample/ASDayPickerSampleViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ - (void)viewDidLoad {
fourWeeks.day = 4 * 7;
NSDate *endDate = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]dateByAddingComponents:fourWeeks toDate:[NSDate date] options:0];
self.dayPicker.selectedDateBackgroundImage = [UIImage imageNamed:@"selection"];
[self.dayPicker setFirstWeekday:DAY_PICKER_WEEKDAY_MONDAY_FIRST];
[self.dayPicker setStartDate:[NSDate date] endDate:endDate];
[self.dayPicker addObserver:self forKeyPath:@"selectedDate" options:NSKeyValueObservingOptionInitial|NSKeyValueObservingOptionNew context:nil];
}
Expand Down