ios自定义年月UIDatePicker 雨点打透心脏的1/2处 2022-06-08 23:36 371阅读 0赞 由于系统的UIDatePicker,只有年月日,没有年月,才进行自定义 使用 UIPickerView 进行封装 效果图: ![Image 1][] 有关DataTimeTool [点击打开链接][Link 1] CustomDataPickView.h #import <UIKit/UIKit.h> typedef NS_ENUM(NSUInteger,CustomDataPickViewType) { CustomDataPickViewTypeYearMonthDay,//年月日 CustomDataPickViewTypeYearMonth//年月 }; @protocol CustomDataPickViewDelegate <NSObject> @optional //CustomDataPickViewTypeYearMonthDay 回调 - (void)pickViewCallBack_year:(NSString *)year month:(NSString *)month day:(NSString *)day; //CustomDataPickViewTypeYearMonth 回调 - (void)pickViewCallBack_year:(NSString *)year month:(NSString *)month; //滚动pickView时 回调 - (void)pickViewScroollCallBack_year:(NSString *)year month:(NSString *)month day:(NSString *)day; @end @interface CustomDataPickView : UIView<UIPickerViewDataSource,UIPickerViewDelegate> { UIPickerView * pickView; } @property (nonatomic, weak) IBOutlet id<CustomDataPickViewDelegate> delegate; @property(nonatomic,unsafe_unretained)CustomDataPickViewType type; @property (nullable, nonatomic, strong) NSDate *minimumDate;//最小显示的日期 @property (nullable, nonatomic, strong) NSDate *maximumDate;//最大显示的日期 @property (nullable, nonatomic, strong) NSDate *defaultSelectDate;//默认选中的日期 - (void)show; - (void)startCallBack; @end CustomDataPickView.m #import "CustomDataPickView.h" #import "DataTimeTool.h" #import "Masonry.h" @interface CustomDataPickView () //保存年月日数据的array @property (nonatomic,strong) NSMutableArray *yearArray; @property (nonatomic,strong) NSMutableArray *monthArray; @property (nonatomic,strong) NSMutableArray *dayArray; //选中的当前行 @property (nonatomic,assign) int selectedRowYear; @property (nonatomic,assign) int selectedRowMonth; @property (nonatomic,assign) int selectedRowDay; //每个月的天数 @property (nonatomic,assign) int dayNumber; //应该跟新天数了,当月份或年份被选择过或是刚进入为true,需要刷新day @property (nonatomic,assign) Boolean dayShouldChangeEnable; @property (nonatomic,strong) NSString *year; @property (nonatomic,strong) NSString *month; @property (nonatomic,strong) NSString *day; @end @implementation CustomDataPickView //根据传递进入的dayNumber计算dayArray -(void)setDaysForMonth:(int) dayNumber{ self.dayArray = nil; self.dayArray = [NSMutableArray array]; for (int index=1; index<=_dayNumber; index++) { [_dayArray addObject:[@(index) stringValue]]; } } - (void)awakeFromNib { [super awakeFromNib]; [self commonInit]; } -(instancetype)init { if (self = [super init]) { [self commonInit]; } return self; } - (instancetype)initWithCoder:(NSCoder *)coder { self = [super initWithCoder:coder]; if (self) { [self commonInit]; } return self; } -(instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self commonInit]; } return self; } - (instancetype)initWithBtns:(NSArray *)btns vc:(UIViewController *)vc { self = [super init]; if (self) { //[self Btns:btns vc:vc]; } return self; } -(void)commonInit{ } -(void)initYesArr { self.yearArray = [NSMutableArray array]; NSString *maxYearStr = [DataTimeTool stringFromDate:self.maximumDate DateFormat:@"yyyy"]; NSString *minYearStr = [DataTimeTool stringFromDate:self.minimumDate DateFormat:@"yyyy"]; int difference = [maxYearStr intValue] - [minYearStr intValue]; if (difference<0 || difference==0) { [self.yearArray addObject:maxYearStr]; return; } for (int i = 0; i<=difference; i ++) { NSString *yesS = [NSString stringWithFormat:@"%d",[minYearStr intValue] + i]; [self.yearArray addObject:yesS]; } [self YearMonthEqual_pickerView:pickView inComponent:0 month:[self.month intValue] Year:[self.year intValue]]; } -(void)initDayArr { self.dayArray = [NSMutableArray array]; [self calculateDayWithMonth:[self.month intValue] andYear:[self.year intValue]]; } -(void)initMonthArr { self.monthArray = [NSMutableArray array]; NSString *maxMonthStr = [DataTimeTool stringFromDate:self.maximumDate DateFormat:@"MM"]; NSString *maxYearStr = [DataTimeTool stringFromDate:self.maximumDate DateFormat:@"yyyy"]; NSString *minMonthStr = [DataTimeTool stringFromDate:self.minimumDate DateFormat:@"MM"]; NSString *minYearStr = [DataTimeTool stringFromDate:self.minimumDate DateFormat:@"yyyy"]; if ([maxYearStr intValue] == [minYearStr intValue]) { for (int i = [minMonthStr intValue]; i<=[maxMonthStr intValue]; i++) { NSString *yesS = [NSString stringWithFormat:@"%d",i]; [self.monthArray addObject:yesS]; } return; } [self YearMonthEqual_pickerView:pickView inComponent:0 month:[self.month intValue] Year:[self.year intValue]]; } #pragma mark -- <UIPickerViewDataSource,UIPickerViewDelegate> - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{ if (self.type == CustomDataPickViewTypeYearMonth) { return 2; }else { return 3; } } - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{ if (component==0) { return self.yearArray.count; }else if(component==1){ return self.monthArray.count; } else{ return self.dayArray.count; } } - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{ if (component==0) { return [NSString stringWithFormat:@"%@年",[self.yearArray objectAtIndex:row]]; }else if(component==1){ return [NSString stringWithFormat:@"%@月",[self.monthArray objectAtIndex:row]]; }else { return [NSString stringWithFormat:@"%@日",[self.dayArray objectAtIndex:row]]; } } - (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{ UILabel* pickerLabel = (UILabel*)view; if (!pickerLabel){ pickerLabel = [[UILabel alloc] init]; [pickerLabel setBackgroundColor:[UIColor clearColor]]; [pickerLabel setFont:[UIFont boldSystemFontOfSize:20]]; pickerLabel.textAlignment = NSTextAlignmentCenter; } pickerLabel.text=[self pickerView:pickerView titleForRow:row forComponent:component]; return pickerLabel; } -(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{ if(component == 0){ _dayShouldChangeEnable = true; self.year = self.yearArray[row]; self.selectedRowYear = (int)row; [pickerView reloadComponent:0]; [self YearMonthEqual_pickerView:pickerView inComponent:0 month:[self.month intValue] Year:[self.year intValue]]; }else if(component==1){ _dayShouldChangeEnable = true; self.month = self.monthArray[row]; self.selectedRowMonth = (int)row; [pickerView reloadComponent:1]; [self YearMonthEqual_pickerView:pickerView inComponent:1 month:[self.month intValue] Year:[self.year intValue]]; }else{ self.day = _dayArray[row]; self.selectedRowDay = (int)row; [pickerView reloadComponent:2]; } if (self.type == CustomDataPickViewTypeYearMonthDay) { if(_dayShouldChangeEnable){ //调用计算天数的函数 [self calculateDayWithMonth:[self.month intValue] andYear:[self.year intValue]]; //由于更新的时候self.selectRowDay很可能大于 天数的最大值,比如self.selectRowDay为31,而天数最大值切换至了29,所以若超出,则需要将selectRowDay重新赋值 if(self.selectedRowDay > _dayNumber-1){ self.selectedRowDay = _dayNumber-1; } [pickerView reloadComponent:2]; _dayShouldChangeEnable = false; } } if ([self.delegate respondsToSelector:@selector(pickViewScroollCallBack_year:month:day:)]) { [self.delegate pickViewScroollCallBack_year:self.year month:self.month day:self.day]; } } -(void)YearMonthEqual_pickerView:(UIPickerView *)pickerView inComponent:(NSInteger)component month:(int)month Year:(int) year { NSString *maxYearStr = [DataTimeTool stringFromDate:self.maximumDate DateFormat:@"yyyy"]; NSString *maxMonthStr = [DataTimeTool stringFromDate:self.maximumDate DateFormat:@"MM"]; NSString *maxDayStr = [DataTimeTool stringFromDate:self.maximumDate DateFormat:@"dd"]; if (component == 0) { self.monthArray = [NSMutableArray array]; if ([maxYearStr intValue] != year) { NSString *minMonthStr = [DataTimeTool stringFromDate:self.minimumDate DateFormat:@"MM"]; for (int i = [minMonthStr intValue]; i<=12; i++) { NSString *yesS = [NSString stringWithFormat:@"%d",i]; [self.monthArray addObject:yesS]; } [pickerView reloadComponent:1]; }else { for (int i = 1; i<=[maxMonthStr intValue]; i++) { NSString *yesS = [NSString stringWithFormat:@"%d",i]; [self.monthArray addObject:yesS]; } if ([maxMonthStr intValue] < [self.month intValue]) { self.month = maxMonthStr; month = [maxMonthStr intValue]; } [pickerView reloadComponent:1]; } if ([maxYearStr intValue] == month && [maxMonthStr intValue] == year) { self.dayArray = [NSMutableArray array]; for (int i = 1; i<=[maxDayStr intValue]; i++) { NSString *yesS = [NSString stringWithFormat:@"%d",i]; [self.dayArray addObject:yesS]; } [pickerView reloadComponent:2]; } } } //根据month和year计算对应的天数 -(void)calculateDayWithMonth:(int) month andYear:(int) year{ float yearF = [self.year floatValue]/4; //能被4整除的是闰年 float yearI = (int)yearF; //若yearI和yearF不一样,也就是说没有被整除,则不是闰年 //当然以上计算没有包括:能被100整除,但不能被400整除的,不是闰年,因为2000年已过2100年还远.... switch (month) { case 1:_dayNumber = 31; break; case 2: if(yearF != yearI){_dayNumber = 28;}else{ _dayNumber = 29;}break; case 3:_dayNumber = 31;break; case 4:_dayNumber = 30;break; case 5:_dayNumber = 31;break; case 6:_dayNumber = 30;break; case 7:_dayNumber = 31;break; case 8:_dayNumber = 31;break; case 9:_dayNumber = 30;break; case 10:_dayNumber = 31;break; case 11:_dayNumber = 30;break; case 12:_dayNumber = 31;break; default:_dayNumber = 31;break; } NSString *maxYearStr = [DataTimeTool stringFromDate:self.maximumDate DateFormat:@"yyyy"]; NSString *maxMonthStr = [DataTimeTool stringFromDate:self.maximumDate DateFormat:@"MM"]; NSString *maxDayStr = [DataTimeTool stringFromDate:self.maximumDate DateFormat:@"dd"]; NSString *minYearStr = [DataTimeTool stringFromDate:self.minimumDate DateFormat:@"yyyy"]; NSString *minMonthStr = [DataTimeTool stringFromDate:self.minimumDate DateFormat:@"MM"]; NSString *minDayStr = [DataTimeTool stringFromDate:self.minimumDate DateFormat:@"dd"]; if ([minYearStr intValue] == year && [minMonthStr intValue] == month && [maxYearStr intValue] == year && [maxMonthStr intValue] == month) { self.dayArray = [NSMutableArray array]; for (int i = [minDayStr intValue]; i<=[maxDayStr intValue]; i++) { NSString *yesS = [NSString stringWithFormat:@"%d",i]; [self.dayArray addObject:yesS]; } return; } if ([minYearStr intValue] == year && [minMonthStr intValue] == month) { self.dayArray = [NSMutableArray array]; for (int i = [minDayStr intValue]; i<=_dayNumber; i++) { NSString *yesS = [NSString stringWithFormat:@"%d",i]; [self.dayArray addObject:yesS]; } return; } if ([maxYearStr intValue] == year && [maxMonthStr intValue] == month) { self.dayArray = [NSMutableArray array]; for (int i = 1; i<=[maxDayStr intValue]; i++) { NSString *yesS = [NSString stringWithFormat:@"%d",i]; [self.dayArray addObject:yesS]; } return; } [self setDaysForMonth:_dayNumber]; //此处调用函数,将dayArray重新赋值; } - (void)show{ self.month = [DataTimeTool stringFromDate:self.defaultSelectDate DateFormat:@"M"]; self.year = [DataTimeTool stringFromDate:self.defaultSelectDate DateFormat:@"y"]; [self initYesArr]; [self initMonthArr]; [self initDayArr]; if (!pickView) { pickView = [[UIPickerView alloc]initWithFrame:self.bounds]; pickView.backgroundColor = [UIColor whiteColor]; pickView.dataSource = self; pickView.delegate = self; [self addSubview:pickView]; [pickView mas_makeConstraints:^(MASConstraintMaker *make) { make.right.left.top.bottom.mas_equalTo(0); }]; } NSString *defaultYearStr = [DataTimeTool stringFromDate:self.defaultSelectDate DateFormat:@"y"]; NSUInteger yeasRow = [self.yearArray indexOfObject:defaultYearStr]; NSString *defaultMonthStr = [DataTimeTool stringFromDate:self.defaultSelectDate DateFormat:@"M"]; NSUInteger monthRow = [self.monthArray indexOfObject:defaultMonthStr]; NSString *defaultDayStr = [DataTimeTool stringFromDate:self.defaultSelectDate DateFormat:@"d"]; NSUInteger dayRow = [self.dayArray indexOfObject:defaultDayStr]; if (yeasRow < self.yearArray.count) { [pickView selectRow:yeasRow inComponent:0 animated:YES]; } if (monthRow < self.monthArray.count) { [pickView selectRow:monthRow inComponent:1 animated:YES]; } if (self.type == CustomDataPickViewTypeYearMonthDay) { if (dayRow < self.dayArray.count) { [pickView selectRow:dayRow inComponent:2 animated:YES]; } } } - (void)startCallBack{ NSInteger yearRow = [pickView selectedRowInComponent:0]; NSInteger monthRow = [pickView selectedRowInComponent:1]; if (self.type == CustomDataPickViewTypeYearMonth) { if ([_delegate respondsToSelector:@selector(pickViewCallBack_year:month:)]) { [_delegate pickViewCallBack_year:[self.yearArray objectAtIndex:yearRow] month:[self.monthArray objectAtIndex:monthRow]]; } } if (self.type == CustomDataPickViewTypeYearMonthDay) { NSInteger dayRow = [pickView selectedRowInComponent:2]; if ([_delegate respondsToSelector:@selector(pickViewCallBack_year:month:day:)]) { [_delegate pickViewCallBack_year:[self.yearArray objectAtIndex:yearRow] month:[self.monthArray objectAtIndex:monthRow] day:[self.dayArray objectAtIndex:dayRow]]; } } } @end 使用: CustomDataPickView *customDataPickView = [[CustomDataPickView alloc]initWithFrame:CGRectMake(0, 0, 400, 300)]; [self.view addSubview:customDataPickView]; customDataPickView.minimumDate = [DataTimeTool dateFromString:@"2012-1-1" DateFormat:@"yyyy-MM-dd"]; customDataPickView.maximumDate = [NSDate new]; customDataPickView.defaultSelectDate = [NSDate new]; customDataPickView.type = CustomDataPickViewTypeYearMonth; [customDataPickView show]; 我的业余技术微信公众号:YKJGZH,欢迎大家进入 [Image 1]: [Link 1]: http://blog.csdn.net/dashenid/article/details/77370632
还没有评论,来说两句吧...