FSCalendar日历选择器,
需求说明:
1.需自定义日历顶部,左右小按钮可点击切换月份
2.当天文字颜色为主色调,选中为含有背景色
3.日历样式只显示当月时间
4.周六、周日文字与其他日期颜色不同
5.点击已过去的时间不可创建
//
// XYCalendarTableViewCell.h
//
// Created by [email protected] on 2020/1/14.
// Copyright © 2020 xy. All rights reserved.
//
#import
#import
NS_ASSUME_NONNULL_BEGIN
@interface XYCalendarTableViewCell : UITableViewCell
@property (weak, nonatomic) IBOutlet FSCalendar *calendar;
@property (weak, nonatomic) IBOutlet UIButton *contentBut;//xxxx年xx月
@property (nonatomic, strong) NSCalendar *chineseCalendar;//系统日历
@property (nonatomic, strong) NSDateFormatter *formatter;
// 时间戳传递出去
@property (nonatomic, copy) void(^CalendarClickBlock)(BOOL compareResult,NSInteger timestamp);
@end
NS_ASSUME_NONNULL_END
//
// XYCalendarTableViewCell.m
// yishopformerchants
//
// Created by [email protected] on 2020/1/14.
// Copyright © 2020 xy. All rights reserved.
//
#import "XYCalendarTableViewCell.h"
@implementation XYCalendarTableViewCell
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
self.selectionStyle = UITableViewCellSelectionStyleNone;
// 设置日历格式为公历
self.chineseCalendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
// 设置日历翻页
self.calendar.pagingEnabled = YES;
self.calendar.scrollEnabled = YES;
// 设置语言
// 设置为中文
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"];
// 设置周次是中文显示
_calendar.locale = locale;
// 当不显示头的时候设置
// _calendar.headerHeight = 0.0f;
// 设置周次为一,二
_calendar.appearance.caseOptions = FSCalendarCaseOptionsWeekdayUsesSingleUpperCase;
// 设置默认选中日期是今天
// [_calendar selectDate:[NSDate date]];
//月份模式时,只显示当前月份
// FSCalendarPlaceholderTypeFillHeadTail 显示当前月与其余月份天数
self.calendar.placeholderType = FSCalendarPlaceholderTypeNone;
// 设置选中日期是今天
// [self.calendar selectDate:[NSDate date] scrollToDate:YES];
// 设置今天文字颜色
self.calendar.appearance.titleTodayColor = MAIN_GREEN;
// 设置今天背景颜色
self.calendar.appearance.todayColor = [UIColor whiteColor];
// 设置周(日、一、二、三、四)字体颜色
self.calendar.appearance.weekdayTextColor = [UIColor darkGrayColor];
// 设置周六、周日下文字颜色
self.calendar.appearance.titleWeekendColor = [UIColor grayColor];
self.calendar.appearance.subtitleWeekendColor = [UIColor yellowColor];
// 设置头部高度
self.calendar.headerHeight = 0;
//这个属性控制"上个月"和"下个月"标签在静止时刻的透明度
// self.calendar.appearance.headerMinimumDissolvedAlpha = 0;
//设置头部字体颜色
self.calendar.appearance.headerTitleColor = [UIColor darkGrayColor];
// 设置头部日期格式
self.calendar.appearance.headerDateFormat = @"yyyy年MM月";
self.calendar.calendarHeaderView.
// 设置选中后背景颜色
self.calendar.appearance.selectionColor = MAIN_GREEN;
// 设置单元格圆角
// 1.0=圆,0.0=正方形,0.0-1.0之间的值为圆角
self.calendar.appearance.borderRadius = 0.4;
self.calendar.delegate = self;
self.calendar.dataSource = self;
//设置翻页方式为水平
self.calendar.scrollDirection = FSCalendarScrollDirectionHorizontal;
//设置是否用户多选
// self.calendar.allowsMultipleSelection = NO;
// self.calendar.appearance.caseOptions = FSCalendarCaseOptionsHeaderUsesUpperCase|FSCalendarCaseOptionsWeekdayUsesSingleUpperCase;
[self setUpContentButtonTitle];
}
- (IBAction)leftButton:(UIButton *)sender {
NSDate *previousMonth = [self.chineseCalendar dateByAddingUnit:NSCalendarUnitMonth value:-1 toDate:self.calendar.currentPage options:0];
[self.calendar setCurrentPage:previousMonth animated:YES];
[self setUpContentButtonTitle];
}
- (IBAction)rightButton:(UIButton *)sender {
NSDate *nextMonthDate = [self.chineseCalendar dateByAddingUnit:NSCalendarUnitMonth value:1 toDate:self.calendar.currentPage options:NSCalendarMatchNextTime];
[self.calendar setCurrentPage:nextMonthDate animated:YES];
[self setUpContentButtonTitle];
}
// 设置年月日期
- (void)setUpContentButtonTitle {
NSCalendar *calendar = [NSCalendar currentCalendar];
NSUInteger unitFlags = NSYearCalendarUnit | //年
NSMonthCalendarUnit | //月份
NSDayCalendarUnit | //日
NSHourCalendarUnit | //小时
NSMinuteCalendarUnit | //分钟
NSSecondCalendarUnit; // 秒
NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:self.calendar.currentPage];
NSInteger year = [dateComponent year];
NSInteger month = [dateComponent month];
[self.contentBut setTitle:[NSString stringWithFormat:@"%ld年%ld月",year,month] forState:UIControlStateNormal];
}
//选中某一天进行相关操作
- (void)calendar:(FSCalendar *)calendar didSelectDate:(NSDate *)date {
//...
}
//取消选中的日期进行相关操作
- (void)calendar:(FSCalendar *)calendar didDeselectDate:(NSDate *)date {
//...
}
#pragma mark FSCalendarDelegateAppearance
//1 时间选择事件
-(void)calendar:(FSCalendar *)calendar didSelectDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)monthPosition
{
// 当前点击的日期与当天对比
NSInteger result = [self compareOneDay:date withAnotherDay:[NSDate date]];
NSInteger timestamp = [self getNowTimestampWithDate:date];
// 在点击的日期之前
if (result == -1) {
if (self.CalendarClickBlock) {
self.CalendarClickBlock(NO, timestamp);
}
} else {
if (self.CalendarClickBlock) {
self.CalendarClickBlock(YES, timestamp);
}
}
}
// 日期圆点显示
- (NSInteger)calendar:(FSCalendar *)calendar numberOfEventsForDate:(NSDate *)date{
// 要标记的日期显示圆点3个其他不显示
// if ([[self.formatter stringFromDate:date] isEqualToString:[self.formatter stringFromDate:self.DifferenceDate]]) {
// return 3;
// } else {
//特殊日期标记
// _Calendar.appearance.eventDefaultColor=[UIColor blueColor];//
// NSArray*events = [self eventsForDate:date];
// return events.count;
return 0;
// }
// return 2;
}
- (int)compareOneDay:(NSDate *)currentDay withAnotherDay:(NSDate *)BaseDay {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"YYYY-MM-dd hh:mm:ss"];
NSString *currentDayStr = [dateFormatter stringFromDate:currentDay];
NSString *BaseDayStr = [dateFormatter stringFromDate:BaseDay];
NSDate *dateA = [dateFormatter dateFromString:currentDayStr];
NSDate *dateB = [dateFormatter dateFromString:BaseDayStr];
NSComparisonResult result = [dateA compare:dateB];
NSLog(@"date1 : %@, date2 : %@", currentDay, BaseDay);
if (result == NSOrderedDescending) {
//NSLog(@"Date1 is in the future");
return 1;
}
else if (result == NSOrderedAscending){
//NSLog(@"Date1 is in the past");
return -1;
}
//NSLog(@"Both dates are the same");
return 0;
}
//获取当前传入的时间戳
#pragma mark - 获取传入的时间戳
- (NSInteger)getNowTimestampWithDate:(NSDate *)date {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateStyle:NSDateFormatterMediumStyle];
[formatter setTimeStyle:NSDateFormatterShortStyle];
[formatter setDateFormat:@"YYYY-MM-dd hh:mm:ss"]; // ----------设置你想要的格式,hh与HH的区别:分别表示12小时制,24小时制
//设置时区,这个对于时间的处理有时很重要
NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Beijing"];
[formatter setTimeZone:timeZone];
NSDate *datenow = date;
//HHLog(@"设备当前的时间:%@", [formatter stringFromDate:datenow]);
//时间转时间戳的方法:
NSInteger timeSp = [[NSNumber numberWithDouble:[datenow timeIntervalSince1970]] integerValue];
//HHLog(@"设备当前的时间戳:%ld",(long)timeSp); //时间戳的值
return timeSp;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
@end
踩坑总结:
NSDate *nextMonthDate = [self.chineseCalendar dateByAddingUnit:NSCalendarUnitMonth value:1 toDate:self.calendar.currentPage options:NSCalendarMatchNextTime];
[self.calendar setCurrentPage:nextMonthDate animated:YES];
点击后一个月份后,打印出来currentPage为当月1日,nextMonthDate为当月31日,跳转下个月不正确,后来发现是因为日历类型设置错了,实际应为公历
错误:
self.chineseCalendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierChinese];
正确:
self.chineseCalendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];