使用 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

写这个程序的时候,数组越界的问题快把我给整疯了,回头检查代码的时候一直没找到问题出在哪了,后来重新理了遍思路,其实想法是没错的,估计是来回倒腾就出错了。这时候就需要自己静下心来在重新梳理一遍,大问题没有,这种小错误也是要命的。

代码中用到了字典,也可以直接用数组实现,不过像尝试一下字典,在代码方面也没有简洁多少...

你可能感兴趣的:(view)