1. 程式人生 > >iOS之自定義簡單的日曆控制元件

iOS之自定義簡單的日曆控制元件

iOS並沒有系統日曆控制元件,但是說白了就是基於UICollectionView的封裝,對於UICollectionView我就不說他的建立了,主要難在資料的處理,下面我就說一下處理資料的思路:

我將資料分為三部分進行處理:如下圖:


- (NSDateComponents *)components:(NSCalendarUnit)unitFlags fromDate:(NSDate *)date;//該方法可以以date獲取到星期,

- (NSRange)rangeOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(

NSDate *)date;//可以獲取到某一個月的天數範圍。


程式碼實現:

@property (nonatomic, strong) NSCalendar *calendar;
@property (nonatomic, assign) NSInteger day;//天
@property (nonatomic, assign) NSInteger month;//月
@property (nonatomic, assign) NSInteger year;//年
@property (nonatomic, strong) NSMutableArray *dayArray;
NSDateComponents *nowCompoents =[self.calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:[NSDate date]];
        self.year = nowCompoents.year;
        self.month = nowCompoents.month;
        self.day = nowCompoents.day;
        self.dayArray = [[NSMutableArray alloc] init];
- (NSArray *)setDayArr {
    
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd"];
    NSDate * nowDate = [dateFormatter dateFromString:[NSString stringWithFormat:@"%ld-%ld-%ld",_year,_month,_day]];
    //本月的天數範圍
    NSRange dayRange = [_calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:nowDate];
    //上個月的天數範圍
    NSRange lastdayRange = [_calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:[self setLastMonthWithDay]];
    //本月第一天的NSDate物件
    NSDate *nowMonthfirst = [dateFormatter dateFromString:[NSString stringWithFormat:@"%ld-%ld-%d",_year,_month,1]];
    //本月第一天是星期幾
    NSDateComponents * components = [_calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitWeekday fromDate:nowMonthfirst];
    //本月最後一天的NSDate物件
    NSDate * nextDay = [dateFormatter dateFromString:[NSString stringWithFormat:@"%ld-%ld-%ld",_year,_month,dayRange.length]];
    NSDateComponents * lastDay = [_calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitWeekday fromDate:nextDay];
    //上個月遺留的天數
    for (NSInteger i = lastdayRange.length - components.weekday + 2; i <= lastdayRange.length; i++) {
        NSString * string = [NSString stringWithFormat:@"%ld",i];
        [self.dayArray addObject:string];
    }
    //本月的總天數
    for (NSInteger i = 1; i <= dayRange.length ; i++) {
        NSString * string = [NSString stringWithFormat:@"%ld",i];
        [self.dayArray addObject:string];
    }
    //下個月空出的天數
    for (NSInteger i = 1; i <= (7 - lastDay.weekday); i++) {
        NSString * string = [NSString stringWithFormat:@"%ld",i];
        [self.dayArray addObject:string];
    }
    self.index = components.weekday - 2 + self.day;
    self.block(_year, _month);
    return self.dayArray;
}
//返回上個月第一天的NSDate物件
- (NSDate *)setLastMonthWithDay {
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd"];
    NSDate * date = nil;
    if (self.month != 1) {
        
        date = [dateFormatter dateFromString:[NSString stringWithFormat:@"%ld-%ld-%d",self.year,self.month-1,01]];
        
    }else{
        
        date = [dateFormatter dateFromString:[NSString stringWithFormat:@"%ld-%d-%d",self.year - 1,12,01]];
    }
    return date;
}

//下個月的資料
- (NSArray *)nextMonthDataArr {
    [self.dayArray removeAllObjects];
    if (_month == 12) {
        _month = 1;
        _year ++;
    }else {
        _month ++;
    }
    return [self setDayArr];
}

//上個月的資料
- (NSArray *)lastMonthDataArr {
    [self.dayArray removeAllObjects];
    if (_month == 1) {
        _month = 12;
        _year --;
    }else {
        _month --;
    }
    return [self setDayArr];
}

demo下載連結:https://github.com/baopan/Calendar