//
// YUDatePicker.h
// YUDatePicker
//
// Created by yuzhx on 15/4/26.
// Copyright (c) 2015年 BruceYu. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "NSDate+YU.h"
#import "YUDateConfig.h"
typedef NS_ENUM(NSInteger, YUUIDatePickerMode) {
UIYUDatePickerModeTime, // Displays hour, minute, and optionally AM/PM designation depending on the locale setting (e.g. 6 | 53 | PM)
UIYUDatePickerModeDate, // Displays month, day, and year depending on the locale setting (e.g. November | 15 | 2007)
UIYUDatePickerModeDateAndTime, // Displays date, hour, minute, and optionally AM/PM designation depending on the locale setting (e.g. Wed Nov 15 | 6 | 53 | PM)
UIYUDatePickerModeCountDownTimer, // Displays hour and minute (e.g. 1 | 53)
UIYUDatePickerModeDateYYYYMMDDHHmm, // (e.g. 2015年 | 05月 | 01日 | 11時 | 59分)
};
NS_CLASS_AVAILABLE_IOS(6_0)@interface YUDatePicker : UIControl
@property (nonatomic) YUUIDatePickerMode datePickerMode; // default is UIXYDatePickerModeDateAndTime
@property (nonatomic, retain) NSLocale *locale; // default is [NSLocale currentLocale]. setting nil returns to default
@property (nonatomic, copy) NSCalendar *calendar; // default is [NSCalendar currentCalendar]. setting nil returns to default
@property (nonatomic, retain) NSTimeZone *timeZone; // default is nil. use current time zone or time zone from calendar
@property (nonatomic, retain) NSDate *date; // default is current date when picker created. Ignored in countdown timer mode. for that mode, picker starts at 0:00
@property (nonatomic, readonly) NSString *dateStr;//return current date Formatter yyyy-MM-dd HH:mm:ss
@property (nonatomic, retain) NSDate *minimumDate; // specify min/max date range. default is nil. When min > max, the values are ignored. Ignored in countdown timer mode
@property (nonatomic, retain) NSDate *maximumDate; // default is nil
@property (nonatomic) NSTimeInterval countDownDuration; // for UIDatePickerModeCountDownTimer, ignored otherwise. default is 0.0. limit is 23:59 (86,399 seconds). value being set is div 60 (drops remaining seconds).
@property (nonatomic) NSInteger minuteInterval; // display minutes wheel with interval. interval must be evenly divided into 60. default is 1. min is 1, max is 30
- (void)setDate:(NSDate *)date animated:(BOOL)animated; // if animated is YES, animate the wheels of time to display the new date
@property (nonatomic, assign) BOOL showToolbar;
@end
typedef void (^dateBlock)(YUDatePicker *date);
@interface YUDatePicker(YU)
-(void)showInView:(UIView *)view block:(dateBlock)dateBlock;
-(void)hidden;
@end
//
// YUDatePicker.m
// YUDatePicker
//
// Created by yuzhx on 15/4/26.
// Copyright (c) 2015年 BruceYu. All rights reserved.
//
#import "YUDatePicker.h"
#define XYNUMBEROFROWS 16384
#define XYROSE_NUMBER 99
#define PICKERHIGHR 216
#define TOOLBARHIGHT 44
@interface YUDatePicker()<UIPickerViewDelegate,UIPickerViewDataSource>
{
UIPickerView *PickerView;
}
@property (nonatomic) NSInteger yearIndex;
@property (nonatomic) NSInteger monthIndex;
@property (nonatomic) NSInteger dayIndex;
@property (nonatomic) NSInteger hourIndex;
@property (nonatomic) NSInteger minuteIndex;
@property (nonatomic) NSInteger secondIndex;
@property (nonatomic , strong) NSArray *amPmArray;
@property (nonatomic , strong) NSMutableArray *yearArray;
@property (nonatomic , strong) NSMutableArray *monthArray;
@property (nonatomic , strong) NSMutableArray *dayArray;
@property (nonatomic , strong) NSMutableArray *hourArray;
@property (nonatomic , strong) NSMutableArray *minuteArray;
@property(nonatomic,strong)NSDate *currentDate;
@property (strong, nonatomic)UIToolbar *actionToolbar;
@end
@implementation YUDatePicker
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor whiteColor];
if (self.frame.size.height<216 || self.frame.size.width<320)
{
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, PICKERHIGHR);
}
}
return self;
}
- (instancetype)init
{
self = [super init];
if (self) {
self.frame = CGRectMake(0, 0, 0, PICKERHIGHR);
}
return self;
}
-(NSDate *)date
{
NSString *ds = [NSString stringWithFormat:XY_FORMATSTR,
self.yearArray[self.yearIndex],
self.monthArray[self.monthIndex],
self.dayArray[self.dayIndex],
self.hourArray[self.hourIndex],
self.minuteArray[self.minuteIndex]
];
NSDate *date = [NSDate dateFromString:ds withFormat:XY_FORMAT];
return date;
}
-(NSString *)dateStr{
NSString *ds = [NSString stringWithFormat:XY_DATESTR,
self.yearArray[self.yearIndex],
self.monthArray[self.monthIndex],
self.dayArray[self.dayIndex],
self.hourArray[self.hourIndex],
self.minuteArray[self.minuteIndex]
];
return ds;
}
-(NSInteger)febNumber{
NSInteger day = [NSDate daysfromYear:[self.yearArray[self.yearIndex] integerValue] andMonth:[self.monthArray[self.monthIndex] integerValue]];
return day;
}
-(void)setMinimumDate:(NSDate *)minimumDate
{
if (!minimumDate) {
_minimumDate = [NSDate dateWithYea:XYPICKER_MINDATE];
}else{
_minimumDate = minimumDate;
}
}
-(void)setMaximumDate:(NSDate *)maximumDate
{
if (!_maximumDate) {
_maximumDate = [NSDate dateWithYea:XYPICKER_MAXDATE];
}else{
_maximumDate = maximumDate;
}
}
-(NSArray*)setDays:(NSInteger)num{
if ([_dayArray count]) {
[_dayArray removeAllObjects];
}
for (int i = 1; i <= num; i++) {
[_dayArray addObject:[NSString stringWithFormat:@"%02d",i]];
}
return _dayArray;
}
-(void)setCurrentDate:(NSDate *)currentDate{
if (currentDate) {
_currentDate = currentDate;
NSDateComponents *d = [NSDate dateComponentsFromDate:_currentDate];
self.yearIndex = d.year-XYPICKER_MINDATE;
self.monthIndex = d.month -1;
self.dayIndex = d.day -1;
self.hourIndex = d.hour;
self.minuteIndex = d.minute;
self.secondIndex = d.second;
}
}
#pragma mark - 初始化賦值操做
-(void)initData{
self.yearArray = [NSMutableArray array];
self.monthArray = [NSMutableArray array];
self.dayArray = [NSMutableArray array];
self.hourArray = [NSMutableArray array];
self.minuteArray = [NSMutableArray array];
self.amPmArray = @[@"AM",@"PM"];
for (int i=0; i<XYPICKER_MINUTE; i++) {
NSString *num = [NSString stringWithFormat:@"%02d",i];
if (0<i && i<=XYPICKER_MONTH)
[self.monthArray addObject:num];
if (0<i && i<=XYPICKER_DAY)
[self.dayArray addObject:num];
if (i<XYPICKER_HOUR)
[self.hourArray addObject:num];
[self.minuteArray addObject:num];
}
for (int i=XYPICKER_MINDATE; i<XYPICKER_MAXDATE; i++) {
NSString *num = [NSString stringWithFormat:@"%d",i];
[self.yearArray addObject:num];
}
self.currentDate = _date;
}
-(void)initUI{
if (self.datePickerMode >= UIYUDatePickerModeDateYYYYMMDDHHmm ) {
if (!PickerView) {
PickerView = [[UIPickerView alloc]initWithFrame:CGRectMake(0, TOOLBARHIGHT-22, self.frame.size.width, PICKERHIGHR)];
PickerView.showsSelectionIndicator = YES;
// PickerView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
PickerView.backgroundColor = [UIColor clearColor];
PickerView.delegate = self;
PickerView.dataSource = self;
[self addSubview:PickerView];
}
[self revertRow:_date animated:NO];
}else{
UIDatePicker *datePicker = [ [ UIDatePicker alloc] initWithFrame:CGRectMake(0,TOOLBARHIGHT-22,self.frame.size.width,PICKERHIGHR-TOOLBARHIGHT)];
datePicker.datePickerMode = (UIDatePickerMode)self.datePickerMode;
datePicker.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin;
[datePicker setLocale:self.locale?self.locale:[[NSLocale alloc]initWithLocaleIdentifier:@"zh_CN"]];
datePicker.calendar = self.calendar;
datePicker.timeZone = self.timeZone;
datePicker.date = _date;
datePicker.minimumDate = self.minimumDate;
datePicker.maximumDate = self.maximumDate;
datePicker.minuteInterval = self.minuteInterval;
datePicker.countDownDuration = self.countDownDuration;
[self addSubview:datePicker];
}
if (self.showToolbar) {
_actionToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, TOOLBARHIGHT)];
_actionToolbar.barStyle = UIBarStyleDefault;
[_actionToolbar sizeToFit];
_actionToolbar.layer.borderWidth = 0.35f;
_actionToolbar.layer.borderColor = [[UIColor colorWithWhite:.8 alpha:1.0] CGColor];
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(actionCancel:)];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(actionDone:)];
[_actionToolbar setItems:[NSArray arrayWithObjects:cancelButton,flexSpace,doneBtn, nil] animated:YES];
[self addSubview:_actionToolbar];
}
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
[self initData];
[self initUI];
}
#pragma mark - UIPickerViewDataSource
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
if (self.datePickerMode == UIYUDatePickerModeDateYYYYMMDDHHmm){
return 5;
}
return 0;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return XYNUMBEROFROWS;
}
#pragma mark - UIPickerViewDelegate
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component
{
switch (self.datePickerMode) {
case UIYUDatePickerModeDateYYYYMMDDHHmm:{
if (component == 0) {
return 75;
}
return 55;
}
break;
default:
break;
}
return 50;
}
- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component{
return 32;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
NSInteger count = 0;
switch (self.datePickerMode) {
case UIYUDatePickerModeDateYYYYMMDDHHmm:{
if (component == 0) {
self.yearIndex = row%(count=self.yearArray.count);
}
if (component == 1) {
self.monthIndex = row%(count=self.monthArray.count);
[self setDays:self.febNumber];
[pickerView selectRow:self.dayIndex + self.dayArray.count * XYROSE_NUMBER inComponent:2 animated:NO];
}
if (component == 2) {
self.dayIndex = row%(count=self.dayArray.count);
}
if (component == 3) {
self.hourIndex = row%(count=self.hourArray.count);
}
if (component == 4) {
self.minuteIndex = row%(count=self.minuteArray.count);
}
}
break;
default:
break;
}
[self selectDid:component];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self revertRow:self.date animated:NO];
});
}
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
UILabel *l = (UILabel *)view;
if (!l) {
l = [[UILabel alloc] init];
l.textAlignment = NSTextAlignmentCenter;
}
l.backgroundColor = [UIColor clearColor];
[l setFont:[UIFont systemFontOfSize:23]];
UIColor *textColor = [UIColor blackColor];
NSString *title;
switch (self.datePickerMode) {
case UIYUDatePickerModeDateYYYYMMDDHHmm:{
if (component==0) {
title = [NSString stringWithFormat:@"%@年",self.yearArray[row%self.yearArray.count]];
textColor = [self yearColorRow:row];
}
if (component==1) {
title = [NSString stringWithFormat:@"%@月",self.monthArray[row%self.monthArray.count]];
textColor = [self monthColorRow:row];
}
if (component==2) {
title = [NSString stringWithFormat:@"%@日",self.dayArray[row%self.dayArray.count]];
textColor = [self dayColorRow:row];
}
if (component==3) {
title = [NSString stringWithFormat:@"%@時",self.hourArray[row%self.hourArray.count]];
textColor = [self hourColorRow:row];
}
if (component==4) {
title = [NSString stringWithFormat:@"%@分",self.minuteArray[row%self.minuteArray.count]];
textColor = [self minuteColorRow:row];
}
}
break;
default:
break;
}
l.text = title;
l.textColor = textColor;
return l;
}
#pragma mark -
#pragma mark - Private
- (void)selectDid:(NSInteger)component
{
if ([self exceedMin:self.date]) {
[self revertRow:self.minimumDate animated:YES];
}else if ([self exceedMax:self.date]){
[self revertRow:self.maximumDate animated:YES];
}
[self sendActionsForControlEvents:UIControlEventValueChanged];
}
-(void)revertRow:(NSDate*)date animated:(BOOL)animated{
NSArray *arry = [self getNowDateArry:date];
NSInteger row = 1;
for (int i=0; i<arry.count; i++) {
if (i%2) {
[PickerView selectRow:[arry[i]integerValue]+row inComponent:i/2 animated:animated];
}else{
row = [arry[i]integerValue]*XYROSE_NUMBER;
}
}
}
- (NSArray *)getNowDateArry:(NSDate*)date
{
NSArray *iArr = nil;
self.currentDate = date;
if (self.datePickerMode == UIYUDatePickerModeDateYYYYMMDDHHmm){
iArr = @[I2S(self.yearArray.count),I2S(self.yearIndex),
I2S(self.monthArray.count),I2S(self.monthIndex),
I2S(self.dayArray.count),I2S(self.dayIndex),
I2S(self.hourArray.count),I2S(self.hourIndex),
I2S(self.minuteArray.count),I2S(self.minuteIndex)];
}
iArr ? 0 :(iArr=[NSArray array]);
return iArr;
}
-(UIColor*)rowColor:(NSDate*)date{
if ([self exceedDate:date]) {
return XY_LIGHTGRAY;
}
return XY_BLACK;
}
-(UIColor*)yearColorRow:(NSInteger)row{
NSString *ds = [NSString stringWithFormat:XY_DATESTR,
self.yearArray[row% self.yearArray.count],
self.monthArray[self.monthIndex],
self.dayArray[self.dayIndex],
self.hourArray[self.hourIndex],
self.minuteArray[self.minuteIndex]
];
NSDate *date = [NSDate dateFromString:ds withFormat:XY_FORMAT];
return [self rowColor:date];
}
-(UIColor*)monthColorRow:(NSInteger)row{
NSString *ds = [NSString stringWithFormat:XY_DATESTR,
self.yearArray[self.yearIndex],
self.monthArray[row%self.monthArray.count],
self.dayArray[self.dayIndex],
self.hourArray[self.hourIndex],
self.minuteArray[self.minuteIndex]
];
NSDate *date = [NSDate dateFromString:ds withFormat:XY_FORMAT];
return [self rowColor:date];
}
-(UIColor*)dayColorRow:(NSInteger)row{
NSString *ds = [NSString stringWithFormat:XY_DATESTR,
self.yearArray[self.yearIndex],
self.monthArray[self.monthIndex],
self.dayArray[row%self.dayArray.count],
self.hourArray[self.hourIndex],
self.minuteArray[self.minuteIndex]
];
NSDate *date = [NSDate dateFromString:ds withFormat:XY_FORMAT];
return [self rowColor:date];
}
-(UIColor*)hourColorRow:(NSInteger)row{
NSString *ds = [NSString stringWithFormat:XY_DATESTR,
self.yearArray[self.yearIndex],
self.monthArray[self.monthIndex],
self.dayArray[self.dayIndex],
self.hourArray[row%self.hourArray.count],
self.minuteArray[self.minuteIndex]
];
NSDate *date = [NSDate dateFromString:ds withFormat:XY_FORMAT];
return [self rowColor:date];
}
-(UIColor*)minuteColorRow:(NSInteger)row{
NSString *ds = [NSString stringWithFormat:XY_DATESTR,
self.yearArray[self.yearIndex],
self.monthArray[self.monthIndex],
self.dayArray[self.dayIndex],
self.hourArray[self.hourIndex],
self.minuteArray[row%self.minuteArray.count]
];
NSDate *date = [NSDate dateFromString:ds withFormat:XY_FORMAT];
return [self rowColor:date];
}
-(BOOL)exceedMin:(NSDate*)date{
if ([date compare:self.minimumDate] == NSOrderedAscending) {
return YES;
}
return NO;
}
-(BOOL)exceedMax:(NSDate*)date{
if ([date compare:self.maximumDate] == NSOrderedDescending){
return YES;
}
return NO;
}
-(BOOL)exceedDate:(NSDate*)date{
BOOL exD = NO;
if ([self exceedMin:date]) {
exD = YES;
}else
if ([self exceedMax:date]){
exD = YES;
}
return exD;
}
- (void)setDate:(NSDate *)date animated:(BOOL)animated{
self.currentDate = date;
[self revertRow:date animated:YES];
}
- (void)actionCancel:(id)sender
{
[self hidden];
}
- (void)actionDone:(id)sender
{
[self hidden];
}
@end
@implementation YUDatePicker(YU)
-(void)showInView:(UIView *)view block:(dateBlock)dateBlock{
if (self.superview) {
[self removeFromSuperview];
}
[self setFrame:CGRectMake(0,
view.frame.size.height + PICKERHIGHR,
view.frame.size.width,
PICKERHIGHR)];
[UIView animateWithDuration:0.35 animations:^{
[self setFrame:CGRectMake(
CGRectGetMinX(self.frame),
CGRectGetHeight(view.frame)-PICKERHIGHR,
view.frame.size.width,
PICKERHIGHR)];
}];
[view addSubview:self];
if (dateBlock) {
dateBlock(self);
}
}
-(void)Dismiss
{
[UIView animateWithDuration:0.35 animations:^{
[self setFrame:CGRectMake(0,
800+ self.frame.size.height,
self.frame.size.width,
PICKERHIGHR)];
} completion:^(BOOL finished) {
[self removeFromSuperview];
}];
}
-(void)hidden{
if (!self.superview) {
return;
}
[self Dismiss];
}
@end
軟件地址:http://www.oschina.net/p/yudatepickeride