GYZCustomCalendarPickerView.m 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. //
  2. // GYZCustomCalendarPickerView.m
  3. // GYZCalendarPicker
  4. //
  5. // Created by GYZ on 16/6/22.
  6. // Copyright © 2016年 GYZ. All rights reserved.
  7. //
  8. #import "GYZCustomCalendarPickerView.h"
  9. @interface GYZCustomCalendarPickerView (Private)
  10. - (void)_setYears;
  11. - (void)_setMonthsInYear:(NSUInteger)_year;
  12. - (void)_setDaysInMonth:(NSString *)_month year:(NSUInteger)_year;
  13. - (void)changeMonths;
  14. - (void)changeDays;
  15. @end
  16. @implementation GYZCustomCalendarPickerView{
  17. UIPickerView *_pickerView;
  18. UILabel *_titleLabel;
  19. UIView *_datePickerView;//datePicker背景
  20. UIButton *_calendarBtn;
  21. NSMutableArray *years;//第一列的数据容器
  22. NSMutableArray *months;//第二列的数据容器
  23. NSMutableArray *days;//第三列的数据容器
  24. IDJCalendar *cal;//日期类
  25. }
  26. - (instancetype)initWithTitle:(NSString *)title
  27. {
  28. self = [super initWithFrame:CGRectZero];
  29. if (self)
  30. {
  31. self.frame = CGRectMake(0, 0, kScreenWidth, kScreenHeight);
  32. self.backgroundColor = kColor(0, 0, 0, 0.4);
  33. self.userInteractionEnabled = YES;
  34. UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hide)];
  35. [self addGestureRecognizer:tapGesture];
  36. [self createView:title];
  37. }
  38. return self;
  39. }
  40. -(void)createView:(NSString *)title{
  41. //生成日期选择器
  42. _datePickerView=[[UIView alloc] initWithFrame:CGRectMake(0,HEIGHT(self)-256,WIDTH(self),255)];
  43. _datePickerView.backgroundColor=[UIColor whiteColor];
  44. _datePickerView.userInteractionEnabled = YES;
  45. [self addSubview:_datePickerView];
  46. UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(pickerViewClick)];
  47. [_datePickerView addGestureRecognizer:tapGesture];
  48. UIButton *dateCancleButton=[[UIButton alloc] initWithFrame:CGRectMake(PADDING,0,44,44)];
  49. [dateCancleButton addTarget:self action:@selector(dateCancleClick) forControlEvents:UIControlEventTouchUpInside];
  50. [dateCancleButton setTitle:Localized(@"UU_custom_cancle") forState:UIControlStateNormal];
  51. [dateCancleButton.titleLabel setFont:k15Font];
  52. [dateCancleButton setTitleColor:HexColor(@"#999999") forState:UIControlStateNormal];
  53. // [dateCancleButton setImage:IMAGE(@"icon_x_cancle") forState:UIControlStateNormal];
  54. // [dateCancleButton setImageEdgeInsets:UIEdgeInsetsMake(12, 12, 12,12)];
  55. [_datePickerView addSubview:dateCancleButton];
  56. UIButton *dateConfirmButton=[[UIButton alloc] initWithFrame:CGRectMake(WIDTH(self)-44 - PADDING,Y(dateCancleButton),WIDTH(dateCancleButton),HEIGHT(dateCancleButton))];
  57. [dateConfirmButton addTarget:self action:@selector(dateConfirmClick) forControlEvents:UIControlEventTouchUpInside];
  58. [dateConfirmButton.titleLabel setFont:k15Font];
  59. [dateConfirmButton setTitleColor:HexColor(@"#1084D1") forState:UIControlStateNormal];
  60. [dateConfirmButton setTitle:Localized(@"UU_custom_sure") forState:UIControlStateNormal];
  61. [_datePickerView addSubview:dateConfirmButton];
  62. _titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(MaxX(dateCancleButton), Y(dateCancleButton), kScreenWidth - MaxX(dateCancleButton)*2, HEIGHT(dateCancleButton))];
  63. _titleLabel.font = k18Font;
  64. _titleLabel.text = title;
  65. _titleLabel.textColor = [UIColor blackColor];
  66. _titleLabel.textAlignment = NSTextAlignmentCenter;
  67. [_datePickerView addSubview:_titleLabel];
  68. UIView *lineView = [[UIView alloc]initWithFrame:CGRectMake(0, MaxY(dateCancleButton), WIDTH(self), kLineHeight)];
  69. lineView.backgroundColor = UIColorFromRGB(0xe5e5e5);
  70. [_datePickerView addSubview:lineView];
  71. _pickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0, MaxY(lineView) , WIDTH(lineView), 216)];
  72. _pickerView.backgroundColor = [UIColor whiteColor];
  73. [_pickerView setShowsSelectionIndicator:YES];
  74. [_pickerView setDelegate:self];
  75. [_pickerView setDataSource:self];
  76. [_datePickerView addSubview:_pickerView];
  77. UIView *lineView1 = [[UIView alloc]initWithFrame:CGRectMake(0, MaxY(_pickerView), WIDTH(lineView), kLineHeight)];
  78. lineView1.backgroundColor = UIColorFromRGB(0xe5e5e5);
  79. [_datePickerView addSubview:lineView1];
  80. _calendarBtn = [[UIButton alloc]initWithFrame:CGRectMake(WIDTH(self)*0.75, MaxY(lineView1), WIDTH(self)*0.25, HEIGHT(dateCancleButton))];
  81. [_calendarBtn setTitle:@"农历" forState:UIControlStateNormal];
  82. [_calendarBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
  83. [_calendarBtn setTitleColor:[UIColor greenColor] forState:UIControlStateSelected];
  84. [_calendarBtn setImage:IMAGE(@"icon_xyk") forState:UIControlStateNormal];
  85. [_calendarBtn setImage:IMAGE(@"icon_xyk_selected") forState:UIControlStateSelected];
  86. [_calendarBtn.titleLabel setFont:k15Font];
  87. // [_datePickerView addSubview:_calendarBtn];
  88. // [_calendarBtn addTarget:self action:@selector(selectCalendarClick:) forControlEvents:UIControlEventTouchUpInside];
  89. }
  90. -(void)setCalendarType:(CalendarType)calendarType{
  91. _calendarType = calendarType;
  92. if (calendarType == GregorianCalendar) {
  93. cal=[[IDJCalendar alloc]initWithYearStart:YEAR_START end:YEAR_END];
  94. } else if (calendarType == ChineseCalendar){
  95. cal=[[IDJChineseCalendar alloc]initWithYearStart:YEAR_START end:YEAR_END];
  96. }
  97. [self _setYears];
  98. [self _setMonthsInYear:[cal.year intValue]];
  99. [self _setDaysInMonth:cal.month year:[cal.year intValue]];
  100. [_pickerView reloadAllComponents];
  101. if (calendarType == GregorianCalendar) {
  102. [_pickerView selectRow:[years indexOfObject:cal.year] inComponent:0 animated:YES];
  103. } else if (calendarType == ChineseCalendar) {
  104. [_pickerView selectRow:[years indexOfObject:[NSString stringWithFormat:@"%@-%@-%@", cal.era, ((IDJChineseCalendar *)cal).jiazi, cal.year]] inComponent:0 animated:YES];
  105. }
  106. [_pickerView selectRow:[months indexOfObject:cal.month] inComponent:1 animated:YES];
  107. [_pickerView selectRow:[days indexOfObject:cal.day] inComponent:2 animated:YES];
  108. }
  109. #pragma mark - pickerview
  110. - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
  111. {
  112. return 3;
  113. }
  114. - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
  115. {
  116. switch (component) {
  117. case 0:
  118. return years.count;
  119. break;
  120. case 1:
  121. return months.count;
  122. break;
  123. case 2:
  124. return days.count;
  125. break;
  126. default:
  127. return 0;
  128. break;
  129. }
  130. }
  131. -(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
  132. {
  133. UILabel *mycom1 = [[UILabel alloc] init];
  134. mycom1.textAlignment = NSTextAlignmentCenter;
  135. mycom1.backgroundColor = [UIColor clearColor];
  136. // mycom1.frame = CGRectMake(0, 0, 90, 50);
  137. [mycom1 setFont:YBLBFont(18)];
  138. switch (component) {
  139. case 0:{
  140. NSString *str=[years objectAtIndex:row];
  141. if (self.calendarType == ChineseCalendar) {
  142. NSArray *array=[str componentsSeparatedByString:@"-"];
  143. str=[NSString stringWithFormat:@"%@/%@", [((IDJChineseCalendar *)cal).chineseYears objectAtIndex:[[array objectAtIndex:1]intValue]-1], [array objectAtIndex:2]];
  144. }
  145. mycom1.text=[NSString stringWithFormat:@"%@", str];
  146. break;
  147. }
  148. case 1:{
  149. NSString *str=[NSString stringWithFormat:@"%@", [months objectAtIndex:row]];
  150. if (self.calendarType == ChineseCalendar) {
  151. NSArray *array=[str componentsSeparatedByString:@"-"];
  152. if ([[array objectAtIndex:0]isEqualToString:@"a"]) {
  153. mycom1.text=[((IDJChineseCalendar *)cal).chineseMonths objectAtIndex:[[array objectAtIndex:1]intValue]-1];
  154. } else {
  155. mycom1.text=[NSString stringWithFormat:@"%@%@", @"闰", [((IDJChineseCalendar *)cal).chineseMonths objectAtIndex:[[array objectAtIndex:1]intValue]-1]];
  156. }
  157. } else {
  158. mycom1.text=[NSString stringWithFormat:@"%@%@", str, @"月"];
  159. }
  160. break;
  161. }
  162. case 2:{
  163. if (self.calendarType == GregorianCalendar) {
  164. int day=[[days objectAtIndex:row]intValue];
  165. int weekday=[IDJCalendarUtil weekDayWithSolarYear:[cal.year intValue] month:cal.month day:day];
  166. mycom1.text=[NSString stringWithFormat:@"%d %@", day, [cal.weekdays objectAtIndex:weekday]];
  167. } else {
  168. NSString *jieqi=[[IDJCalendarUtil jieqiWithYear:[cal.year intValue]]objectForKey:[NSString stringWithFormat:@"%@-%d", cal.month, [[days objectAtIndex:row]intValue]]];
  169. if (!jieqi) {
  170. mycom1.text=[NSString stringWithFormat:@"%@", [((IDJChineseCalendar *)cal).chineseDays objectAtIndex:[[days objectAtIndex:row]intValue]-1]];
  171. } else {
  172. //DLog(@"%@-%d-%@", cal.month, [[days objectAtIndex:cell]intValue], jieqi);
  173. mycom1.text=[NSString stringWithFormat:@"%@", jieqi];
  174. }
  175. }
  176. break;
  177. }
  178. default:
  179. break;
  180. }
  181. return mycom1;
  182. }
  183. -(CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component
  184. {
  185. switch (component) {
  186. case 0:
  187. return 90;
  188. break;
  189. case 1:
  190. return 50;
  191. break;
  192. case 2:
  193. return 70;
  194. break;
  195. default:
  196. return 90;
  197. break;
  198. }
  199. }
  200. - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
  201. {
  202. switch (component) {
  203. case 0:{
  204. NSString *str=[years objectAtIndex:row];
  205. if (self.calendarType == ChineseCalendar) {
  206. NSArray *array=[str componentsSeparatedByString:@"-"];
  207. str=[array objectAtIndex:2];
  208. NSString *pYear=[cal.year copy];
  209. cal.era=[array objectAtIndex:0];
  210. ((IDJChineseCalendar *)cal).jiazi=[array objectAtIndex:1];
  211. cal.year=str;
  212. //因为用户可能从2011年滚动,最后放手的时候,滚回了2011年,所以需要判断与上一次选中的年份是否不同,再联动月份的滚轮
  213. if (![pYear isEqualToString:cal.year]) {
  214. [self changeMonths];
  215. }
  216. } else {
  217. cal.year=str;
  218. //因为公历的每年都是12个月,所以当年份变化的时候,只需要后面的天数联动
  219. [self changeDays];
  220. }
  221. break;
  222. }
  223. case 1:{
  224. NSString *pMonth=[cal.month copy];
  225. NSString *str=[months objectAtIndex:row];
  226. cal.month=str;
  227. if (![pMonth isEqualToString:cal.month]) {
  228. //联动天数的滚轮
  229. [self changeDays];
  230. }
  231. break;
  232. }
  233. case 2:{
  234. cal.day=[days objectAtIndex:row];
  235. break;
  236. }
  237. default:
  238. break;
  239. }
  240. if (self.calendarType == GregorianCalendar) {
  241. cal.weekday=[NSString stringWithFormat:@"%d", [IDJCalendarUtil weekDayWithSolarYear:[cal.year intValue] month:cal.month day:[cal.day intValue]]];
  242. } else {
  243. cal.weekday=[NSString stringWithFormat:@"%d", [IDJCalendarUtil weekDayWithChineseYear:[cal.year intValue] month:cal.month day:[cal.day intValue]]];
  244. ((IDJChineseCalendar *)cal).animal=[IDJCalendarUtil animalWithJiazi:[((IDJChineseCalendar *)cal).jiazi intValue]];
  245. }
  246. }
  247. #pragma mark -Calendar Data Handle-
  248. //动态改变农历月份列表,因为公历的月份只有12个月,不需要跟随年份滚轮联动
  249. - (void)changeMonths{
  250. if (self.calendarType == ChineseCalendar) {
  251. [self _setMonthsInYear:[cal.year intValue]];
  252. [_pickerView reloadComponent:1];
  253. int cell=[months indexOfObject:cal.month];
  254. if (cell==NSNotFound) {
  255. cell=0;
  256. cal.month=[months objectAtIndex:0];
  257. }
  258. [_pickerView selectRow:cell inComponent:1 animated:YES];
  259. //月份改变之后,天数进行联动
  260. [self changeDays];
  261. }
  262. }
  263. //动态改变日期列表
  264. - (void)changeDays{
  265. [self _setDaysInMonth:cal.month year:[cal.year intValue]];
  266. [_pickerView reloadComponent:2];
  267. int cell=[days indexOfObject:cal.day];
  268. //假如用户上次选择的是1月31日,当月份变为2月的时候,第三列的滚轮不可能再选中31日,我们设置默认的值为第一个。
  269. if (cell==NSNotFound) {
  270. cell=0;
  271. cal.day=[days objectAtIndex:0];
  272. }
  273. [_pickerView selectRow:cell inComponent:2 animated:YES];
  274. }
  275. #pragma mark -Fill init Data-
  276. //填充年份
  277. - (void)_setYears {
  278. years = [[NSMutableArray alloc]init];
  279. years=[cal yearsInRange];
  280. }
  281. //填充月份
  282. - (void)_setMonthsInYear:(NSUInteger)_year {
  283. months = [[NSMutableArray alloc]init];
  284. months=[cal monthsInYear:_year];
  285. }
  286. //填充天数
  287. - (void)_setDaysInMonth:(NSString *)_month year:(NSUInteger)_year {
  288. days = [[NSMutableArray alloc]init];
  289. days=[cal daysInMonth:_month year:_year];
  290. }
  291. - (void)selectCalendarClick:(UIButton *)sender {
  292. sender.selected = !sender.selected;
  293. if (sender.selected) {
  294. self.calendarType = ChineseCalendar;
  295. } else {
  296. self.calendarType = GregorianCalendar;
  297. }
  298. }
  299. - (void)show {
  300. UIWindow *window = [[UIApplication sharedApplication].windows objectAtIndex:0];
  301. [window addSubview:self];
  302. [self addAnimation];
  303. }
  304. - (void)hide {
  305. [self removeAnimation];
  306. }
  307. - (void)addAnimation {
  308. [UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
  309. [_datePickerView setFrame:CGRectMake(0, self.frame.size.height - _datePickerView.frame.size.height, kScreenWidth, _datePickerView.frame.size.height)];
  310. // self.alpha = 0.7;
  311. } completion:^(BOOL finished) {
  312. }];
  313. }
  314. - (void)removeAnimation {
  315. [UIView animateWithDuration:0.2 animations:^{
  316. [_datePickerView setFrame:CGRectMake(0, kScreenHeight, kScreenWidth, 0)];
  317. self.alpha = 0;
  318. } completion:^(BOOL finished) {
  319. if (finished) {
  320. [self removeFromSuperview];
  321. }
  322. }];
  323. }
  324. //确定选择
  325. -(void)dateConfirmClick{
  326. if (self.delegate) {
  327. if ([self.delegate respondsToSelector:@selector(notifyNewCalendar:)] == YES) {
  328. NSString *year =[NSString stringWithFormat:@"%@",cal.year];
  329. NSString *month = [cal.month intValue] > 9 ? cal.month:[NSString stringWithFormat:@"0%@",cal.month];
  330. NSString *day = [cal.day intValue] > 9 ? cal.day:[NSString stringWithFormat:@"0%@",cal.day];
  331. NSString *timeDate=[NSString stringWithFormat:@"%@%@%@",year,month,day];
  332. NSDate *senddate = [NSDate date];
  333. NSDateFormatter* formatter1=[[NSDateFormatter alloc]init];
  334. formatter1.dateFormat = @"yyyyMMdd";
  335. NSString* dateString = [formatter1 stringFromDate:senddate];
  336. if ([dateString isEqualToString:timeDate])
  337. {
  338. // cal.weekday= [NSString stringWithFormat:@"%d",[cal.weekday intValue]-1];
  339. }
  340. [self.delegate notifyNewCalendar:cal];
  341. }
  342. }
  343. [self removeAnimation];
  344. }
  345. //取消选择
  346. -(void)dateCancleClick{
  347. [self removeAnimation];
  348. }
  349. -(void)pickerViewClick{
  350. }
  351. @end