其他分享
首页 > 其他分享> > iOS开发之使用FSCalendar日历选择

iOS开发之使用FSCalendar日历选择

作者:互联网

FSCalendar日历选择器,
需求说明:
1.需自定义日历顶部,左右小按钮可点击切换月份
2.当天文字颜色为主色调,选中为含有背景色
3.日历样式只显示当月时间
4.周六、周日文字与其他日期颜色不同
5.点击已过去的时间不可创建

先上界面
在这里插入图片描述
我把它放在cell里处理的,这里可视需求而定

cell样式

//
//  XYCalendarTableViewCell.h
//
//  Created by daiwotaopaoba@icloud.com on 2020/1/14.
//  Copyright © 2020 xy. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <FSCalendar.h>

NS_ASSUME_NONNULL_BEGIN

@interface XYCalendarTableViewCell : UITableViewCell <FSCalendarDelegateAppearance,FSCalendarDelegate,FSCalendarDataSource>

@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 daiwotaopaoba@icloud.com 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

踩坑总结:

  1. 坑1
  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];
  1. 坑2
    处理时间需考虑时间差…时间戳传给后台时应打印查看是否是正确的。
带我逃跑吧 发布了118 篇原创文章 · 获赞 8 · 访问量 4万+ 私信 关注

标签:FSCalendar,appearance,self,日历,iOS,NSDate,设置,date,calendar
来源: https://blog.csdn.net/Simona_1973/article/details/103969454