首页 > 代码库 > 使用 UIPickerView 制作的日历
使用 UIPickerView 制作的日历
@implementation CalendarByDicViewController- (void)viewDidLoad{ [super viewDidLoad]; self.view.backgroundColor = [UIColor colorWithRed:0.93 green:0.93 blue:0.93 alpha:1]; UILabel *lab = [[UILabel alloc] initWithFrame:CGRectMake(110, 50, 100, 33)]; lab.text = @"日 历"; lab.textAlignment = NSTextAlignmentCenter; lab.textColor = [UIColor colorWithRed:155/255.0 green:155/255.0 blue:155/255.0 alpha:1]; lab.font = [UIFont boldSystemFontOfSize:24]; [self.view addSubview:lab]; UIPickerView *pickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 100, 320, 50)]; pickerView.backgroundColor = [UIColor whiteColor]; [self.view addSubview:pickerView]; pickerView.dataSource = self; pickerView.delegate = self; //存储年份的数组 NSMutableArray *yearArray = [[NSMutableArray alloc] initWithCapacity:50]; for (int i = 0; i < 50; i ++) { [yearArray addObject:[NSString stringWithFormat:@"%d", START_YEAR + i]]; } //存储月份的数组 NSMutableArray *monthArray = [[NSMutableArray alloc] initWithCapacity:12]; for (int i = 0; i < 12; i ++) { [monthArray addObject:[NSString stringWithFormat:@"%d", i + 1]]; } //存储天数的数组 NSMutableArray *dayArray = [[NSMutableArray alloc] initWithCapacity:31]; for (int i = 0; i < 31; i ++) { [dayArray addObject:[NSString stringWithFormat:@"%d", i + 1]]; } //将年、月、日都存放进字典 _dataDic = [[NSDictionary alloc] initWithObjectsAndKeys:yearArray, @"year", monthArray, @"month", dayArray, @"day", nil]; //计算今天的日期 NSDate *date = [NSDate date]; date = [date dateByAddingTimeInterval:8 * 60 * 60]; NSString *today = [date description]; int yearNow = [[today substringToIndex:4] intValue]; int monthNow = [[today substringWithRange:NSMakeRange(5, 2)] intValue]; int dayNow = [[today substringWithRange:NSMakeRange(8, 2)] intValue]; //日期指定到今天,让日历默认显示今天的日期 [pickerView selectRow:(yearNow - START_YEAR) inComponent:0 animated:NO]; [pickerView selectRow:(monthNow - 1) inComponent:1 animated:NO]; [pickerView selectRow:(dayNow - 1) inComponent:2 animated:NO];}- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{ return _dataDic.count; //设置选择器的列数,即显示年、月、日三列}- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{ NSArray *keyArray = [_dataDic allKeys]; NSArray *contentArray = [_dataDic objectForKey:keyArray[component]]; //显示每月的天数跟年份和月份都有关系,所以需要判断条件 if (component == 2) { int month = [pickerView selectedRowInComponent:1] + 1; int year = [pickerView selectedRowInComponent:0] + START_YEAR; switch (month) { //每个月的天数不一样 case 4: case 6: case 9: case 11: { contentArray = [contentArray subarrayWithRange:NSMakeRange(0, 30)];//4、6、9、11月的天数是30天 return contentArray.count; } case 2: { if ( [self isLeapYear:year]) { //如果是闰年,二月有 29 天 contentArray = [contentArray subarrayWithRange:NSMakeRange(0, 29)]; } else { //不是闰年,二月只有 28 天 contentArray = [contentArray subarrayWithRange:NSMakeRange(0, 28)]; } return contentArray.count; } default: return contentArray.count; //1、3、5、7、8、10、12 月的天数都是31天 } } return contentArray.count; //返回每列的行数}- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component{ return 100; //设置每列的宽度}- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component{ return 50; //设置每行的高度}//设置所在列每行的显示标题,与设置所在列的行数一样,天数的标题设置仍旧需要非一番功夫- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{ NSArray *keyArray = [_dataDic allKeys]; NSArray *contentArray = [_dataDic objectForKey:keyArray[component]]; if (component == 2) { int month = [pickerView selectedRowInComponent:1] + 1; int year = [pickerView selectedRowInComponent:0] +START_YEAR; switch (month) { case 4: case 6: case 9: case 11: { contentArray = [contentArray subarrayWithRange:NSMakeRange(0, 30)]; return contentArray[row]; } case 2: { if ( [self isLeapYear:year]) { //闰年 contentArray = [contentArray subarrayWithRange:NSMakeRange(0, 29)]; } else { contentArray = [contentArray subarrayWithRange:NSMakeRange(0, 28)]; } return contentArray[row]; } default: return contentArray[row]; } } return contentArray[row];}//当选择的行数改变时触发的方法- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{ //第一列的被选择行变化,即年份改变,则刷新月份和天数 if (component == 0) { [pickerView reloadAllComponents]; //刷新月份与日期 //下面是将月份和天数都定位到第一行 [pickerView selectRow:0 inComponent:1 animated:YES]; [pickerView selectRow:0 inComponent:2 animated:YES]; } //第二列的被选择行变化,即月份发生变化,刷新天这列的内容 if (component == 1) { [pickerView reloadAllComponents]; [pickerView selectRow:0 inComponent:2 animated:YES]; }//需要这些条件的原因是年份和月份的变化,都会引起每月的天数的变化,他们之间是有联系的,要掌握好他们之间的对应关系}//判断是否闰年- (BOOL)isLeapYear:(int)year{ if ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0))) { return YES; //是闰年返回 YES } return NO; //不是闰年,返回 NO}@end
写这个程序的时候,数组越界的问题快把我给整疯了,回头检查代码的时候一直没找到问题出在哪了,后来重新理了遍思路,其实想法是没错的,估计是来回倒腾就出错了。这时候就需要自己静下心来在重新梳理一遍,大问题没有,这种小错误也是要命的。
代码中用到了字典,也可以直接用数组实现,不过像尝试一下字典,在代码方面也没有简洁多少...
使用 UIPickerView 制作的日历
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。