KBDatePickerView.og.m 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. #import "KBDatePickerView.h"
  2. @interface KBDatePickerView () {
  3. NSDate *_currentDate;
  4. }
  5. @property UIStackView *datePickerStackView;
  6. @property UITableView *monthTable;
  7. @property UITableView *dayTable;
  8. @property UITableView *yearTable;
  9. @property UILabel *monthLabel;
  10. @property UILabel *dayLabel;
  11. @property UILabel *yearLabel;
  12. @property UILabel *datePickerLabel;
  13. @end
  14. @implementation KBDatePickerView
  15. - (NSDate *)date {
  16. if (!_currentDate){
  17. [self setDate:[NSDate date]];
  18. }
  19. return _currentDate;
  20. }
  21. - (NSCalendar *)calendar {
  22. return [NSCalendar currentCalendar];
  23. }
  24. - (void)setDate:(NSDate *)date {
  25. _currentDate = date;
  26. //_dateLabel.text = date.description;
  27. [self scrollToCurrentDateAnimated:true];
  28. }
  29. - (id)init {
  30. self = [super init];
  31. if (![self date]){
  32. [self setDate:[NSDate date]];
  33. }
  34. _showDateLabel = true;
  35. [self layoutViews];
  36. return self;
  37. }
  38. - (void)scrollToCurrentDateAnimated:(BOOL)animated {
  39. NSDateComponents *components = [[self calendar] components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:self.date];
  40. [_monthTable selectRowAtIndexPath:[NSIndexPath indexPathForRow:components.month-1 inSection:0] animated:animated scrollPosition:UITableViewScrollPositionTop];
  41. [_dayTable selectRowAtIndexPath:[NSIndexPath indexPathForRow:components.day-1 inSection:0] animated:animated scrollPosition:UITableViewScrollPositionTop];
  42. [_yearTable selectRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0] animated:animated scrollPosition:UITableViewScrollPositionTop];
  43. }
  44. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  45. if (tableView == _monthTable){
  46. return [self calendar].monthSymbols.count;
  47. } else if (tableView == _dayTable){
  48. NSRange days = [[self calendar] rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:self.date];
  49. return days.length;
  50. } else {
  51. return 3;
  52. }
  53. }
  54. - (void)tableView:(UITableView *)tableView didUpdateFocusInContext:(UITableViewFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator {
  55. [coordinator addCoordinatedAnimations:^{
  56. NSIndexPath *ip = context.nextFocusedIndexPath;
  57. NSLog(@"[KBDatePicker] next ip: %@", ip);
  58. [tableView selectRowAtIndexPath:ip animated:false scrollPosition:UITableViewScrollPositionTop];
  59. } completion:^{
  60. }];
  61. }
  62. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  63. UITableViewCell *cell = nil;
  64. if (tableView == _monthTable){
  65. cell = [tableView dequeueReusableCellWithIdentifier:@"month"];
  66. if (!cell){
  67. cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"month"];
  68. }
  69. cell.textLabel.text = [[self calendar] monthSymbols][indexPath.row];
  70. cell.textLabel.textAlignment = NSTextAlignmentCenter;
  71. } else if (tableView == _dayTable){
  72. cell = [tableView dequeueReusableCellWithIdentifier:@"day"];
  73. if (!cell){
  74. cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"day"];
  75. }
  76. cell.textLabel.text = [NSString stringWithFormat:@"%lu", indexPath.row + 1];
  77. cell.textLabel.textAlignment = NSTextAlignmentCenter;
  78. } else {
  79. cell = [tableView dequeueReusableCellWithIdentifier:@"year"];
  80. if (!cell){
  81. cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"year"];
  82. }
  83. NSInteger year = [[self calendar] component:NSCalendarUnitYear fromDate:self.date];
  84. cell.textLabel.text = [NSString stringWithFormat:@"%lu", year - 1 + indexPath.row];
  85. cell.textLabel.textAlignment = NSTextAlignmentCenter;
  86. }
  87. return cell;
  88. }
  89. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  90. NSDateComponents *components = [[self calendar] components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:self.date];
  91. if (tableView == _monthTable){
  92. NSInteger month = indexPath.row + 1;
  93. components.month = month;
  94. NSDate *newDate = nil;
  95. do {
  96. newDate = [[self calendar] dateFromComponents:components];
  97. components.day -= 1;
  98. } while (newDate == nil || ([[self calendar] component:NSCalendarUnitMonth fromDate:newDate] != month));
  99. [self setDate:newDate];
  100. [[self dayTable] reloadData];
  101. [[self yearTable] reloadData];
  102. } else if (tableView == _dayTable){
  103. components.day = indexPath.row + 1;
  104. NSDate *newDate = [[self calendar] dateFromComponents:components];
  105. if (newDate){
  106. [self setDate:newDate];
  107. [[self monthTable] reloadData];
  108. [[self yearTable] reloadData];
  109. }
  110. } else {
  111. NSInteger year = [[self calendar] component:NSCalendarUnitYear fromDate:self.date];
  112. components.year = year - 1 + indexPath.row;
  113. NSDate *newDate = nil;
  114. do {
  115. newDate = [[self calendar] dateFromComponents:components];
  116. components.day -= 1;
  117. } while (newDate == nil || ([[self calendar] component:NSCalendarUnitMonth fromDate:newDate] != components.month));
  118. [self setDate:newDate];
  119. [[self monthTable] reloadData];
  120. [[self yearTable] reloadData];
  121. }
  122. if (self.itemSelectedBlock){
  123. self.itemSelectedBlock(self.date);
  124. }
  125. if (self.showDateLabel){
  126. self.datePickerLabel.hidden = false;
  127. self.datePickerLabel.text = self.date.description;
  128. } else {
  129. self.datePickerLabel.hidden = true;
  130. }
  131. }
  132. - (CGSize)sizeThatFits:(CGSize)size {
  133. //CGSize sup = [super sizeThatFits:size];
  134. return CGSizeMake(720, 128+81+60+40);
  135. }
  136. - (void)layoutViews {
  137. self.monthLabel = [[UILabel alloc] init];
  138. self.monthLabel.translatesAutoresizingMaskIntoConstraints = false;
  139. self.monthLabel.text = @"Month";
  140. self.yearLabel = [[UILabel alloc] init];
  141. self.yearLabel.translatesAutoresizingMaskIntoConstraints = false;
  142. self.yearLabel.text = @"Year";
  143. self.dayLabel = [[UILabel alloc] init];
  144. self.dayLabel.translatesAutoresizingMaskIntoConstraints = false;
  145. self.dayLabel.text = @"Day";
  146. self.monthTable = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
  147. self.yearTable = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
  148. self.dayTable = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
  149. self.monthTable.delegate = self;
  150. self.monthTable.dataSource = self;
  151. self.yearTable.delegate = self;
  152. self.yearTable.dataSource = self;
  153. self.dayTable.delegate = self;
  154. self.dayTable.dataSource = self;
  155. self.datePickerStackView = [[UIStackView alloc] initWithArrangedSubviews:@[self.monthTable, self.dayTable, self.yearTable]];
  156. self.datePickerStackView.translatesAutoresizingMaskIntoConstraints = false;
  157. self.datePickerStackView.spacing = 10;
  158. self.datePickerStackView.axis = UILayoutConstraintAxisHorizontal;
  159. self.datePickerStackView.alignment = UIStackViewAlignmentFill;
  160. self.datePickerStackView.distribution = UIStackViewDistributionFillEqually;
  161. [self.datePickerStackView.widthAnchor constraintEqualToConstant:720].active = true;
  162. [self.datePickerStackView.heightAnchor constraintEqualToConstant:128].active = true;
  163. [self addSubview:self.datePickerStackView];
  164. [self addSubview:self.monthLabel];
  165. [self addSubview:self.yearLabel];
  166. [self addSubview:self.dayLabel];
  167. [self.datePickerStackView.centerXAnchor constraintEqualToAnchor:self.centerXAnchor].active = true;
  168. [self.datePickerStackView.topAnchor constraintEqualToAnchor:self.dayLabel.bottomAnchor constant:60].active = true;
  169. [self.monthLabel.topAnchor constraintEqualToAnchor:self.topAnchor constant:20].active = true;
  170. [self.dayLabel.topAnchor constraintEqualToAnchor:self.topAnchor constant:20].active = true;
  171. [self.dayLabel.centerXAnchor constraintEqualToAnchor:self.dayTable.centerXAnchor].active = true;
  172. [self.monthLabel.centerXAnchor constraintEqualToAnchor:self.monthTable.centerXAnchor].active = true;
  173. [self.yearLabel.centerXAnchor constraintEqualToAnchor:self.yearTable.centerXAnchor].active = true;
  174. [self.yearLabel.topAnchor constraintEqualToAnchor:self.topAnchor constant:20].active = true;
  175. [self.monthLabel.topAnchor constraintEqualToAnchor:self.topAnchor constant:20].active = true;
  176. self.datePickerLabel = [[UILabel alloc] init];
  177. self.datePickerLabel.translatesAutoresizingMaskIntoConstraints = false;
  178. self.datePickerLabel.hidden = !_showDateLabel;
  179. [self addSubview:self.datePickerLabel];
  180. [self.datePickerLabel.centerXAnchor constraintEqualToAnchor:self.centerXAnchor].active = true;
  181. [self.datePickerLabel.topAnchor constraintEqualToAnchor:self.datePickerStackView.bottomAnchor constant:80].active = true;
  182. }
  183. @end