1、创建一个集成PickerView的View
.h文件
#import
NS_ASSUME_NONNULL_BEGIN
@protocol LYDateIntervalSelectorPickerDelegate
-(void)dateWithSelect:(NSDate *)date;
@end
@interface LYDateIntervalSelectorPicker : UIPickerView
-(instancetype)initWithDatePickerView;
@property (nonatomic, assign) id pvDelegate;
@property (nonatomic, strong, readonly) NSDate *date;
@end
NS_ASSUME_NONNULL_END
.m文件
#import "LYDateIntervalSelectorPicker.h"
static CGFloat rowsHeight = 44.0;
@interface LYDateIntervalSelectorPicker ()
@property (nonatomic, strong) NSIndexPath *todayIndexPath;
@property (nonatomic, strong) NSArray *months;
@property (nonatomic, strong) NSArray *years;
@property (nonatomic, strong) NSArray *days;
@property (nonatomic, strong) NSCalendar *calendar;
@end
@implementation LYDateIntervalSelectorPicker
-(instancetype)initWithDatePickerView{
self = [super init];
if (self) {
self.delegate = self;
self.dataSource = self;
self.years = [self nameOfYears];
self.months = [self nameOfMonths];
self.days = [self nameOfDays];
self.todayIndexPath = [self todayPath];
[self selectCurrentDate];
}
return self;
}
- (void)selectCurrentDate{
NSIndexPath *selectIndexPath = [self todayPath];
//设置当前年份
[self selectRow:selectIndexPath.section
inComponent:0
animated:YES];
[self pickerView:self didSelectRow:selectIndexPath.row inComponent:0];
selectIndexPath = [self todayPath];
//设置当前月份
[self selectRow:selectIndexPath.row
inComponent:1
animated:YES];
[self pickerView:self didSelectRow:selectIndexPath.row inComponent:1];
//设置当前日期
CGFloat day = [[[self currentDayName] substringToIndex:[self currentDayName].length] floatValue] - 1;
[self selectRow:day inComponent:2 animated:YES];
[self pickerView:self didSelectRow:day inComponent:2];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
//获取当前选中的是几号
NSInteger currert = [pickerView selectedRowInComponent:2] + 1;
//判断二月份最大天数和30号和31号
if (currert > [self daysCountWithSelectDate]) {
[pickerView selectRow:[self daysCountWithSelectDate] inComponent:2 animated:NO];
}
if (component == 0 || component == 1) {
self.days = [self nameOfDays];
[pickerView reloadComponent:1];
[pickerView reloadComponent:2];
}
if ([self.pvDelegate respondsToSelector:@selector(dateWithSelect:)]) {
[self.pvDelegate dateWithSelect:[self date]];
}
}
-(NSDate *)date{
NSString *year = [self.years objectAtIndex:([self selectedRowInComponent:0])];
NSString *month = [self.months objectAtIndex:([self selectedRowInComponent:1])];
NSString *day = [self.days objectAtIndex:([self selectedRowInComponent:2]) % self.days.count];
NSDateFormatter *formatter = [NSDateFormatter new];
[formatter setDateFormat:@"yyyy年M月d日"];
NSString *dateString = [NSString stringWithFormat:@"%@%@%@", year, month, day];
NSDate *date = [formatter dateFromString:dateString];
return date;
}
#pragma mark - UIPickerViewDelegate
-(CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component{
return [self componentWidth];
}
-(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{
UILabel *returnView = [self labelForComponent:component];
returnView.text = [self titleForRow:row forComponent:component];
return returnView;
}
-(CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component{
return rowsHeight;
}
#pragma mark - UIPickerViewDataSource
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 3;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
if(component == 0){
return self.years.count;
}else if (component == 1) {
return self.months.count;
}else {
return self.days.count;
}
}
-(CGFloat)componentWidth{
return self.bounds.size.width / 3;
}
-(NSString *)titleForRow:(NSInteger)row forComponent:(NSInteger)component{
if(component == 0) {
return [self.years objectAtIndex:(row)];
}else if(component == 1) {
return [self.months objectAtIndex:(row)];
}else {
NSInteger DayCount = self.days.count;
return [self.days objectAtIndex:(row % DayCount)];
}
}
-(UILabel *)labelForComponent:(NSInteger)component{
CGRect frame = CGRectMake(0, 0, [self componentWidth], rowsHeight);
UILabel *label = [[UILabel alloc] initWithFrame:frame];
label.textAlignment = NSTextAlignmentCenter;
label.backgroundColor = [UIColor clearColor];
label.userInteractionEnabled = NO;
return label;
}
#pragma mark --------- 华丽的分割线 ---------
//当前时间
-(NSIndexPath *)todayPath{
CGFloat row = 0.f;
CGFloat section = 0.f;
NSString *year = [self currentYearName];
NSString *month = [self currentMonthName];
for(NSString *cellYear in self.years) {
if([cellYear isEqualToString:year]) {
section = [self.years indexOfObject:cellYear];
break;
}
}
for(NSString *cellMonth in self.months) {
if([cellMonth isEqualToString:month]) {
row = [self.months indexOfObject:cellMonth];
break;
}
}
return [NSIndexPath indexPathForRow:row inSection:section];
}
//年份数组
-(NSArray *)nameOfYears{
NSMutableArray *years = [NSMutableArray array];
NSInteger currentYear = [[[self currentYearName] substringToIndex:4] integerValue];
for(NSInteger year = currentYear - 5; year <= currentYear; year++) {
NSString *yearStr = [NSString stringWithFormat:@"%li年", (long)year];
[years addObject:yearStr];
}
return years;
}
//月份数组
-(NSArray *)nameOfMonths{
return @[@"1月", @"2月", @"3月", @"4月", @"5月", @"6月", @"7月", @"8月", @"9月", @"10月", @"11月", @"12月"];
}
//日期数组
-(NSArray *)nameOfDays{
NSUInteger numberOfDaysInMonth = [self daysCountWithSelectDate];
NSMutableArray *tempArr = [NSMutableArray array];
for (int i = 1; i < numberOfDaysInMonth + 1 ; i ++) {
NSString *day = [NSString stringWithFormat:@"%d日",i];
[tempArr addObject:day];
}
return tempArr;
}
//根据当前年月获取当前月天数
-(NSInteger)daysCountWithSelectDate{
self.calendar = [NSCalendar currentCalendar];
NSRange range = [self.calendar rangeOfUnit:NSCalendarUnitDay
inUnit:NSCalendarUnitMonth
forDate:[self monthDate]];
return range.length;
}
//根据当前年月返回日期
-(NSDate *)monthDate{
NSString *year = [self.years objectAtIndex:([self selectedRowInComponent:0])];
NSString *month = [self.months objectAtIndex:([self selectedRowInComponent:1])];
NSDateFormatter *formatter = [NSDateFormatter new];
[formatter setDateFormat:@"yyyy年M月"];
NSDate *date = [formatter dateFromString:[NSString stringWithFormat:@"%@%@", year, month]];
return date;
}
//当前年份
-(NSString *)currentYearName{
NSDateFormatter *formatter = [NSDateFormatter new];
[formatter setDateFormat:@"yyyy年"];
return [formatter stringFromDate:[NSDate date]];
}
//当前月份
-(NSString *)currentMonthName{
NSDateFormatter *formatter = [NSDateFormatter new];
NSLocale *usLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"];
[formatter setLocale:usLocale];
[formatter setDateFormat:@"M月"];
return [formatter stringFromDate:[NSDate date]];
}
//当前日期
-(NSString *)currentDayName{
NSDateFormatter *formatter = [NSDateFormatter new];
[formatter setDateFormat:@"d日"];
return [formatter stringFromDate:[NSDate date]];
}
@end
2、创建一个View
.h文件
#import
#import "LYDateIntervalSelectorPicker.h"
NS_ASSUME_NONNULL_BEGIN
@interface LYDateIntervalSelectorView : UIView
//单例
+(LYDateIntervalSelectorView *)initClient;
-(void)datePickerCompleteBlock:(void (^)(NSDate *startDate, NSDate *endDate))completeBlock;
@end
NS_ASSUME_NONNULL_END
.m文件 — 引入头文件
#import "LYDateIntervalSelectorPicker.h"
#import "LYDateIntervalSelectorView.h"
#import "LYDateIntervalSelectorPicker.h"
static CGFloat whiteViewHeight = 400.f;
static CGFloat pickerHeight = 250.f;
//时间回调
typedef void (^ DateBlock)(NSDate *, NSDate *);
@interface LYDateIntervalSelectorView ()
{
CGFloat height;
CGFloat width;
}
//白色背景
@property (nonatomic, strong) UIView *whiteView;
@property (nonatomic, copy) DateBlock dateBlock;
//开始时间
@property (nonatomic, strong) UIButton *bStart;
//结束时间
@property (nonatomic, strong) UIButton *bEnd;
//开始时间date
@property (nonatomic, strong) NSDate *startDate;
//结束时间date
@property (nonatomic, strong) NSDate *endDate;
//选择器
@property (nonatomic, strong) LYDateIntervalSelectorPicker *selectorPicker;
//区分当前操作时间——开始时间或结束时间
@property (nonatomic) BOOL timeType;
@end
@implementation LYDateIntervalSelectorView
+(LYDateIntervalSelectorView *)initClient{
static LYDateIntervalSelectorView *client = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
client = [[self alloc] initWithFrame:[UIScreen mainScreen].bounds];
[client createUI];
});
return client;
}
-(void)datePickerCompleteBlock:(void (^)(NSDate *startDate, NSDate *endDate))completeBlock{
_dateBlock = completeBlock;
[self show];
}
#pragma mark - 创建布局
-(void)createUI{
height = [UIScreen mainScreen].bounds.size.height;
width = [UIScreen mainScreen].bounds.size.width;
//默认时间
self.endDate = [NSDate date];
self.startDate = [NSDate date];
//取消手势
UITapGestureRecognizer *cancelTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapCancelAction)];
[self addGestureRecognizer:cancelTap];
//白色背景
self.whiteView = [[UIView alloc]initWithFrame:CGRectMake(0, height, width, whiteViewHeight)];
self.whiteView.backgroundColor = [UIColor whiteColor];
[self addSubview:self.whiteView];
//完成
UIButton *bConfirm = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, width, 40)];
[bConfirm setTitle:@"完成" forState:0];
[bConfirm setTitleColor:[UIColor cyanColor] forState:0];
[bConfirm addTarget:self action:@selector(buttonConfirm) forControlEvents:UIControlEventTouchUpInside];
[self.whiteView addSubview:bConfirm];
CGFloat edge = 20.f;
CGFloat labelWidth = (width - edge * 5) / 2;
//开始时间
_bStart = [[UIButton alloc]initWithFrame:CGRectMake(20, CGRectGetMaxY(bConfirm.frame) + edge * 2, labelWidth, 40)];
[_bStart setTitle:[self dateFormatWithDate:[NSDate date]] forState:0];
[_bStart setTitleColor:[UIColor cyanColor] forState:0];
_bStart.tag = 1000;
[_bStart addTarget:self action:@selector(buttonTypeTimeSelect:) forControlEvents:UIControlEventTouchUpInside];
[self.whiteView addSubview:_bStart];
UIImageView *ivLineStart = [[UIImageView alloc]initWithFrame:CGRectMake(CGRectGetMinX(_bStart.frame), CGRectGetMaxY(_bStart.frame), CGRectGetWidth(_bStart.frame), 1)];
ivLineStart.backgroundColor = [UIColor lightGrayColor];
[self.whiteView addSubview:ivLineStart];
//至
UILabel *lFromTo = [[UILabel alloc]initWithFrame:CGRectMake(CGRectGetMaxX(_bStart.frame) + edge, CGRectGetMinY(_bStart.frame), edge, CGRectGetHeight(_bStart.frame))];
lFromTo.text = @"至";
lFromTo.textColor = [UIColor blackColor];
lFromTo.textAlignment = NSTextAlignmentCenter;
lFromTo.font = [UIFont systemFontOfSize:16];
[self.whiteView addSubview:lFromTo];
//结束时间
_bEnd = [[UIButton alloc]initWithFrame:CGRectMake(CGRectGetMaxX(lFromTo.frame) + edge, CGRectGetMinY(_bStart.frame), CGRectGetWidth(_bStart.frame), CGRectGetHeight(_bStart.frame))];
[_bEnd setTitle:[self dateFormatWithDate:[NSDate date]] forState:0];
[_bEnd setTitleColor:[UIColor lightGrayColor] forState:0];
_bEnd.tag = 1001;
[_bEnd addTarget:self action:@selector(buttonTypeTimeSelect:) forControlEvents:UIControlEventTouchUpInside];
[self.whiteView addSubview:_bEnd];
UIImageView *ivLineEnd = [[UIImageView alloc]initWithFrame:CGRectMake(CGRectGetMinX(_bEnd.frame), CGRectGetMaxY(_bEnd.frame), CGRectGetWidth(ivLineStart.frame), CGRectGetHeight(ivLineStart.frame))];
ivLineEnd.backgroundColor = [UIColor lightGrayColor];
[self.whiteView addSubview:ivLineEnd];
//选择器
self.selectorPicker = [[LYDateIntervalSelectorPicker alloc]initWithDatePickerView];
self.selectorPicker.frame = CGRectMake(0, whiteViewHeight - pickerHeight, width, pickerHeight);
self.selectorPicker.pvDelegate = self;
[self.whiteView addSubview:self.selectorPicker];
}
-(void)buttonTypeTimeSelect:(UIButton *)sender{
if (sender.tag - 1000 == 0) {
[_bStart setTitleColor:[UIColor cyanColor] forState:0];
[_bEnd setTitleColor:[UIColor lightGrayColor] forState:0];
self.timeType = NO;
}else{
[_bStart setTitleColor:[UIColor lightGrayColor] forState:0];
[_bEnd setTitleColor:[UIColor cyanColor] forState:0];
self.timeType = YES;
}
}
-(void)dateWithSelect:(NSDate *)date{
//时间转时间戳
NSString *time = [self dateFormatWithDate:date];
//选择结束时间
if (self.timeType) {
self.endDate = date;
[_bEnd setTitle:time forState:0];
}
//选择开始时间
else{
self.startDate = date;
[_bStart setTitle:time forState:0];
}
}
-(void)buttonConfirm{
//开始时间的时间戳
NSInteger sDate = [self timestampWithDate:self.startDate];
//结束时间的时间戳
NSInteger eDate = [self timestampWithDate:self.endDate];
//开始时间的时间戳大于结束时间的时间戳是不对的,直接return,提示时间不对
if (sDate > eDate) {
NSLog(@"时间不对");
return;
}
if (_dateBlock) {
_dateBlock(self.startDate,self.endDate);
}
}
//显示手势
-(void)show{
[[UIApplication sharedApplication].keyWindow addSubview:self];
self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0];
[UIView animateWithDuration:0.25 animations:^{
self.whiteView.frame = CGRectMake(0, self->height - whiteViewHeight, self->width, whiteViewHeight);
self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.4];
}];
}
//取消手势
-(void)tapCancelAction{
[UIView animateWithDuration:0.2 animations:^{
self.whiteView.frame = CGRectMake(0, self->height, self->width, whiteViewHeight);
self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0];
} completion:^(BOOL finished) {
[self removeFromSuperview];
}];
}
//时间格式
-(NSString *)dateFormatWithDate:(NSDate *)date{
NSString *formatStr = @"yyyy-MM-dd";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:formatStr];
return [dateFormatter stringFromDate:date];
}
//时间转时间戳
-(NSInteger)timestampWithDate:(NSDate *)date{
return [date timeIntervalSince1970] / 1000;
}
@end
3、创建一个Controller
.h文件
#import
NS_ASSUME_NONNULL_BEGIN
@interface DateSelectorController : UIViewController
@end
NS_ASSUME_NONNULL_END
.m文件 —— 引入头文件
#import "LYDateIntervalSelectorView.h"
#import "DateSelectorController.h"
#import "LYDateIntervalSelectorView.h"
@interface DateSelectorController ()
@end
@implementation DateSelectorController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor whiteColor];
[[LYDateIntervalSelectorView initClient] datePickerCompleteBlock:^(NSDate * _Nonnull startDate, NSDate * _Nonnull endDate) {
NSString *formatStr = @"yyyy年MM月dd日";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:formatStr];
NSLog(@"ss %@",[dateFormatter stringFromDate:startDate]);
NSLog(@"ee %@",[dateFormatter stringFromDate:endDate]);
}];
}
@end
4、效果图
5、全剧终
我也是服了有些人了,Demo