zoukankan      html  css  js  c++  java
  • 使用 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

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

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

  • 相关阅读:
    迭代器在LinkedList上的删除
    java多线程:CopyOnWriteArrayList
    vs中代码编译通过,但还是有红色波浪线
    vs中项目属性配置
    TortoiseGit安装与配置
    DC(device context)
    weak_ptr 使用
    C++ 中shared_ptr循环引用计数问题
    for_each与lambda表达式联合使用
    new 和 make_shared 在内存上的区别
  • 原文地址:https://www.cnblogs.com/hyhl23/p/4189220.html
Copyright © 2011-2022 走看看