iOS 自定义时间选择器

自定义时间选择器,时间到今天为止,并且可设置显示的年的数量

使用:


- (DatePickerView *)datePickerView {
    if (!_datePickerView) {
        NSInteger count = [[NSDate date] getYear] - 2017;
        _datePickerView = [[DatePickerView alloc] initWithType:DatePickerViewTypeYearMonth showYears:count];
        _datePickerView.delegate = self;
    }
    return _datePickerView;
}

效果:
在这里插入图片描述

#import <UIKit/UIKit.h>

typedef NS_ENUM(NSInteger, DatePickerViewType) {
    DatePickerViewTypeYear,
    DatePickerViewTypeYearMonth,
    DatePickerViewTypeYearMonthDay
};

@protocol DatePickerViewDelegate<NSObject>

- (void)datePickerViewDidCancel;
- (void)datePickerViewDidSelect:(NSInteger)year and:(NSInteger)month and:(NSInteger)day;

@end

@interface DatePickerView : UIView

@property (nonatomic, weak) id<DatePickerViewDelegate> delegate;
@property (nonatomic, assign) DatePickerViewType type;

- (instancetype)initWithType:(DatePickerViewType)type showYears:(NSInteger)count;
- (instancetype)initWithType:(DatePickerViewType)type showYears:(NSInteger)count image:(NSString *)name;

- (void)showInView:(UIView *)view;
- (void)dismiss;

@end
#import "DatePickerView.h"

@interface DatePickerView() <UIPickerViewDataSource,UIPickerViewDelegate>
{
    NSDateComponents *currentDateComponents;
    NSInteger maxYearCount;
    CGFloat pickerViewHeight;
    UIView *contentView;
    UIImageView *imageView;
}

@property (nonatomic, strong) UIPickerView *pickerView;
@property (nonatomic, strong) UIDatePicker *datePicker;
@property (nonatomic, strong) NSMutableArray<NSMutableArray<NSString *> *> * dataArray;

@end

@implementation DatePickerView

- (UIPickerView *)pickerView {
    if (!_pickerView) {
        _pickerView = [[UIPickerView alloc] init];
        _pickerView.delegate = self;
        _pickerView.dataSource = self;
    }
    return _pickerView;
}

- (instancetype)init {
    return [self initWithType:DatePickerViewTypeYearMonthDay showYears:50 image:nil];
}

- (instancetype)initWithType:(DatePickerViewType)type showYears:(NSInteger)count
{
    return [self initWithType:type showYears:count image:nil];
}

- (instancetype)initWithType:(DatePickerViewType)type showYears:(NSInteger)count image:(NSString *)name
{
    self.type = type;
    self = [super initWithFrame:ScreenBounds];
    if (self) {
        [self initViewWithShowYears:count image:name];
    }
    return self;
}

- (void)initViewWithShowYears:(NSInteger)count image:(NSString *)name {
    count = count > 0 ? count : 3;
    maxYearCount = count;
    pickerViewHeight = 240 * ScaleWidth + 40;
    
    self.backgroundColor = Color_Background_Alpha;
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)];
    [self addGestureRecognizer:tap];
    
    if (name) {
        //显示例图
        UIImage *image = [UIImage imageNamed:name];
        imageView = [[UIImageView alloc] initWithImage:image];
        CGFloat width = ScreenWidth - 38 * 2;
        CGFloat height = width / 3 * 2;
        imageView.frame = CGRectMake(38, ScreenHeight - pickerViewHeight - height - 50, width, height);
        imageView.alpha = 0;
        [self addSubview:imageView];
    }
    
    contentView = [[UIView alloc] initWithFrame:CGRectMake(0, ScreenHeight, ScreenWidth, pickerViewHeight)];
    contentView.backgroundColor = Color_Background;
    [self addSubview:contentView];
    
    UIButton *cancelButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 80, 44)];
    [cancelButton setTitle:@"取消" forState:UIControlStateNormal];
    [cancelButton setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
    cancelButton.titleLabel.font = [UIFont boldSystemFontOfSize:16];
    [cancelButton addTarget:self action:@selector(cancelButtonAction:) forControlEvents:UIControlEventTouchUpInside];
    [contentView addSubview:cancelButton];
    
    UIButton *confirmButton = [[UIButton alloc] initWithFrame:CGRectMake(ScreenWidth - 80, 0, 80, 44)];
    [confirmButton setTitle:@"确认" forState:UIControlStateNormal];
    [confirmButton setTitleColor:[UIColor darkTextColor] forState:UIControlStateNormal];
    confirmButton.titleLabel.font = [UIFont boldSystemFontOfSize:16];
    [confirmButton addTarget:self action:@selector(confirmButtonAction:) forControlEvents:UIControlEventTouchUpInside];
    [contentView addSubview:confirmButton];
    
    
    NSCalendar *calendar = [NSCalendar currentCalendar];
    unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
    currentDateComponents = [calendar components:unitFlags fromDate:[NSDate date]];
    NSLog(@"现在时间:%ld年 %ld月 %ld日", (long)currentDateComponents.year, (long)currentDateComponents.month, (long)currentDateComponents.day);
    //当前时间的行
    NSInteger yearIndex = maxYearCount - 1;
    NSInteger monthIndex = currentDateComponents.month - 1;
    NSInteger dayIndex = currentDateComponents.day - 1;
    
    //数据源
    _dataArray = [[NSMutableArray alloc] initWithCapacity:0];
    NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:0];
    for (int i = 0; i <= yearIndex; i ++) {
        [arr addObject:[NSString stringWithFormat:@"%zd年", currentDateComponents.year - maxYearCount + i + 1]];
    }
    [_dataArray addObject:arr];
    if (self.type != DatePickerViewTypeYear) {
        NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:0];
        for (int i = 0; i <= monthIndex; i ++) {
            [arr addObject:[NSString stringWithFormat:@"%d月", i + 1]];
        }
        [_dataArray addObject:arr];
    }
    if (self.type == DatePickerViewTypeYearMonthDay) {
        NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:0];
        for (int i = 0; i <= dayIndex; i ++) {
            [arr addObject:[NSString stringWithFormat:@"%d日", i + 1]];
        }
        [_dataArray addObject:arr];
    }
    
    //初始化选中的行
    [self.pickerView selectRow:yearIndex inComponent:0 animated:YES];
    if (self.type != DatePickerViewTypeYear) {
        [self.pickerView selectRow:monthIndex inComponent:1 animated:YES];
    }
    if (self.type == DatePickerViewTypeYearMonthDay) {
        [self.pickerView selectRow:dayIndex inComponent:2 animated:YES];
    }
    self.pickerView.frame = CGRectMake(0, 40, ScreenWidth, pickerViewHeight - 40);
    [contentView addSubview:self.pickerView];
}

- (void)tapAction {
    [self dismiss];
}

- (void)cancelButtonAction:(UIButton *)sender {
    if ([self.delegate respondsToSelector:@selector(datePickerViewDidCancel)]) {
        [self.delegate datePickerViewDidCancel];
    }
    [self dismiss];
}

- (void)confirmButtonAction:(UIButton *)sender {
    NSInteger currentYear = currentDateComponents.year - maxYearCount + [self.pickerView selectedRowInComponent:0] + 1;
    NSInteger currentMonth = 0;
    NSInteger currentDay = 0;
    if (self.type != DatePickerViewTypeYear) {
        currentMonth = [self.pickerView selectedRowInComponent:1] + 1;
    }
    if (self.type == DatePickerViewTypeYearMonthDay) {
        currentDay = [self.pickerView selectedRowInComponent:2] + 1;
    }
    NSLog(@"选择时间:%ld年 %ld月 %ld日", (long)currentYear, (long)currentMonth, (long)currentDay);
    if ([self.delegate respondsToSelector:@selector(datePickerViewDidSelect:and:and:)]) {
        [self.delegate datePickerViewDidSelect:currentYear and:currentMonth and:currentDay];
    }
    [self dismiss];
}

- (void)showInView:(UIView *)view {
    [view addSubview:self];
    __weak  typeof(self) weakSelf = self;
    [UIView animateWithDuration:TimeInterval_Animation animations:^{
        CGRect frame = self->contentView.frame;
        frame.origin.y = ScreenHeight - self->pickerViewHeight;
        self->contentView.frame = frame;
        self->imageView.alpha = 1;
        [weakSelf layoutIfNeeded];
    }];
}

- (void)dismiss {
    __weak  typeof(self) weakSelf = self;
    [UIView animateWithDuration:TimeInterval_Animation animations:^{
        CGRect frame = self->contentView.frame;
        frame.origin.y = ScreenHeight;
        self->contentView.frame = frame;
        self->imageView.alpha = 0;
        [weakSelf layoutIfNeeded];
    } completion:^(BOOL finished) {
        if (finished) {
            [weakSelf removeFromSuperview];
        }
    }];
}

#pragma mark - DelegateAndDataSource
//列数
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
    return self.dataArray.count;
}
//行数
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
    return self.dataArray[component].count;
}

//每一列的宽度
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component {
    return ScreenWidth / 4;
}

//每一行的高度
- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component {
    return 30;
}

- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
    UILabel *label = [[UILabel alloc] init];
    label.font = [UIFont boldSystemFontOfSize:20];
    label.textAlignment = NSTextAlignmentCenter;
    label.text = self.dataArray[component][row];
    return label;
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
    //选中年月刷新对应的月日
    if (self.type == DatePickerViewTypeYearMonthDay) {
        if (component == 0) {
            [self datePickReloadMonth];
            [self datePickReloadDay];
        } else if (component == 1) {
            [self datePickReloadDay];
        }
    } else if (self.type == DatePickerViewTypeYearMonth) {
        if (component == 0) {
            [self datePickReloadMonth];
        }
    }
}

- (void)datePickReloadMonth {
    NSInteger yearIndex = [self.pickerView selectedRowInComponent:0];
    NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:0];
    NSInteger month = 12;
    if (yearIndex == maxYearCount - 1) {
        month = currentDateComponents.month;
    }
    for (int i = 0; i < month; i ++) {
        [arr addObject:[NSString stringWithFormat:@"%d月", i + 1]];
    }
    [_dataArray replaceObjectAtIndex:1 withObject:arr];
    [self.pickerView reloadComponent:1];
}

- (void)datePickReloadDay {
    NSInteger yearIndex = [self.pickerView selectedRowInComponent:0];
    NSInteger monthIndex = [self.pickerView selectedRowInComponent:1];
    NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:0];
    NSInteger days = [self dayNumberOfYear:_dataArray[0][yearIndex].integerValue month:_dataArray[1][monthIndex].integerValue];
    if (yearIndex == maxYearCount - 1 && monthIndex == currentDateComponents.month - 1) {
        days = currentDateComponents.day;
    }
    for (int i = 0; i < days; i ++) {
        [arr addObject:[NSString stringWithFormat:@"%d日", i + 1]];
    }
    [_dataArray replaceObjectAtIndex:2 withObject:arr];
    [self.pickerView reloadComponent:2];
}

- (NSInteger)dayNumberOfYear:(NSInteger)year month:(NSInteger)month {
    switch (month) {
        case 1: case 3: case 5: case 7: case 8: case 10: case 12:
            return 31;
        case 4: case 6: case 9: case 11:
            return 30;
        default:
            if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
                return 29;
            } else {
                return 28;
            }
    }
}

@end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值