1. 程式人生 > >iOS 自定義時間選擇器 DatePicker

iOS 自定義時間選擇器 DatePicker

6種時間選擇方式:
年月日、年月日時、年月日時分、時分、日時分、月日時分

呼叫方式


 [[DatePicker shareManager]showWithType:PickerTypeDay title:nil time:@"2018:10:31" backTime:^(NSString * _Nonnull backTimeStr) {
        NSLog(@"%@",backTimeStr);
    }];

DatePicker.h


typedef NS_ENUM (NSInteger ,PickerType){

    PickerTypeDay = 3,//年月日
    PickerTypeHour,//年月日時
    PickerTypeMinute,//年月日時分
    PickerTypeMinuteHour,//時分
    PickerTypeMinuteDay,//日時分
    PickerTypeMinuteMonth,//月日時分
};

@interface DatePicker : UIView

+(instancetype)shareManager;
-(instancetype)init;

/*
 
 pickerType 時間選擇器型別
 title      標題(可不傳)
 time       傳入的值會在選擇器中選中展示(可不傳)
 backTime   返回時間(例:yyyy:MM:dd:HH:mm)
 */
-(void)showWithType:(PickerType)pickerType title:(NSString * _Nullable)title time:(NSString * _Nullable )timeStr backTime:(void (^)(NSString * backTimeStr))backTime;

@end

DatePicker.m


#import "DatePicker.h"


#define WIDTH [UIScreen mainScreen].bounds.size.width
#define HEIGHT [UIScreen mainScreen].bounds.size.height
#define KEYWINDOW [UIApplication sharedApplication].keyWindow



@interface DatePicker ()<UIPickerViewDelegate,UIPickerViewDataSource>


@property (nonatomic,strong)UIView * bgView;//背景
@property (nonatomic,strong)UILabel * titlelabel;//標題
@property (nonatomic,strong)UIPickerView * pickerView;//選擇器

@property (nonatomic,assign)PickerType pickerType;//型別

@property (nonatomic,strong)NSDateComponents * components;//時間結構體、可計算時間間隔、獲取年月日時分、
@property (nonatomic,strong)NSMutableArray * dataArray;//資料來源
@property (nonatomic,strong)NSMutableArray * selDateArray;
@property (nonatomic,strong)void (^backTime)(NSString * backTimeStr);//回撥

@end


@implementation DatePicker

+(instancetype)shareManager{
    
    static DatePicker * manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (!manager) {
            manager = [[DatePicker alloc] init];
        }
    });
    return manager;
}
-(instancetype)init{
    if (self = [super init]) {
        [self createView];
    }
    return self;
}

-(void)createView{
    
    self.frame = CGRectMake(0, 0, WIDTH, HEIGHT);
    self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.3];
    _dataArray = [[NSMutableArray alloc]init];
    
    _bgView = [[UIView alloc]initWithFrame:CGRectMake((WIDTH-250)/2, HEIGHT/2-124, 250, 200)];
    _bgView.backgroundColor = [UIColor whiteColor];
    _bgView.layer.cornerRadius = 5;
    
    _titlelabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, _bgView.bounds.size.width, 33)];
    _titlelabel.textAlignment = NSTextAlignmentCenter;
    [_bgView addSubview:_titlelabel];
    
    
    _pickerView = [[UIPickerView alloc]initWithFrame:CGRectMake(0, CGRectGetMaxY(_titlelabel.frame), _bgView.bounds.size.width, _bgView.frame.size.height-CGRectGetMaxY(_titlelabel.frame)-33)];
    _pickerView.delegate = self;
    _pickerView.dataSource = self;
    [_bgView addSubview:_pickerView];
    
    
    UIButton * cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
    cancelButton.frame = CGRectMake(0, CGRectGetMaxY(_pickerView.frame), _bgView.bounds.size.width/2-0.5, 33);
    [cancelButton setTitle:@"取消" forState:UIControlStateNormal];
    [cancelButton addTarget:self action:@selector(cancelButtonClick:) forControlEvents:UIControlEventTouchUpInside];
    [cancelButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [_bgView addSubview:cancelButton];
    
    
    UIButton * trueButton = [UIButton buttonWithType:UIButtonTypeCustom];
    trueButton.frame = CGRectMake(_bgView.bounds.size.width/2+0.5, CGRectGetMaxY(_pickerView.frame), _bgView.bounds.size.width/2, 33);
    [trueButton setTitle:@"確定" forState:UIControlStateNormal];
    [trueButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [trueButton addTarget:self action:@selector(trueButtonClick:) forControlEvents:UIControlEventTouchUpInside];
    [_bgView addSubview:trueButton];
    
    [self addSubview:_bgView];
}


-(void)showWithType:(PickerType)pickerType title:(NSString * _Nullable)title time:( NSString * _Nullable )timeStr backTime:(void (^)(NSString * backTimeStr))backTime{
    
    _backTime = backTime;
    _pickerType = pickerType;
    _titlelabel.text = title;
    _selDateArray = [[NSMutableArray alloc]init];

    NSCalendar * calender = [NSCalendar currentCalendar];
    _components = [calender components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute fromDate:[NSDate date]];
    
    NSArray * timeArr = [[NSArray alloc]init];
    if (timeStr) {
        timeArr = [self receiveTime:timeStr];
    }
    NSInteger count = (_pickerType>5)?_pickerType-4:_pickerType;
    if (timeArr.count == count) {//需要顯示傳入的時間
        
        _dataArray = [self dataSourceArray];
        int index = (_pickerType<6)?2:((_pickerType == 8)?1:0);
        if (index && timeArr.count == count) {
            NSInteger year = (index == 1)?_components.year:[timeArr[index-2] integerValue];
            [_dataArray replaceObjectAtIndex:index withObject:[self dayArrayMonth:[timeArr[index-1] integerValue] year:year]];
        }
        [_pickerView reloadAllComponents];
        
        for (int i = 0; i<count; i++) {
            [_pickerView selectRow:[_dataArray[i] indexOfObject:timeArr[i]] inComponent:i animated:YES];
        }
        [_selDateArray addObjectsFromArray:timeArr];
    }else{//不需要顯示傳入的時間
        _dataArray = [self dataSourceArray];
        [_pickerView reloadAllComponents];
        
        
        NSArray * dateArr = @[[NSString stringWithFormat:@"%ld",_components.year],[NSString stringWithFormat:@"%ld",_components.month],[NSString stringWithFormat:@"%ld",_components.day],[NSString stringWithFormat:@"%ld",_components.hour],[NSString stringWithFormat:@"%ld",_components.minute]];

        if (_pickerType>5) {
            NSArray * arary = @[[NSNumber numberWithInteger:0],[NSNumber numberWithInteger:5],[NSNumber numberWithInteger:0],[NSNumber numberWithInteger:0]];
            for (int i = 0; i<_pickerType - 4; i++) {
                [_pickerView selectRow:[arary[i] integerValue] inComponent:_pickerType - 5 - i animated:YES];
                [_selDateArray insertObject:dateArr[4-i] atIndex:i];
            }
        }else{
            NSArray * arary = @[[NSNumber numberWithInteger:_components.month-1],[NSNumber numberWithInteger:_components.day-1],[NSNumber numberWithInteger:_components.hour],[NSNumber numberWithInteger:_components.minute]];
            for (int i = 1; i<_pickerType; i++) {
                [_pickerView selectRow:[arary[i] integerValue] inComponent:i animated:YES];
                [_selDateArray addObject:dateArr[i]];
            }
        }
        
    }
    
    //選中行邊框顏色
    
    if (_pickerView.subviews.count>0) {
        [_pickerView.subviews objectAtIndex:1].layer.borderWidth = 0.5f;
        [_pickerView.subviews objectAtIndex:2].layer.borderWidth = 0.5f;
        [_pickerView.subviews objectAtIndex:1].layer.borderColor = [UIColor blackColor].CGColor;
        [_pickerView.subviews objectAtIndex:2].layer.borderColor = [UIColor blackColor].CGColor;
    }
    [KEYWINDOW addSubview:self];
}

-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
    return _pickerType<6?_pickerType:_pickerType-4;
}

-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
    return [_dataArray[component] count];
}

-(CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component{
    return (pickerView.bounds.size.width-10)/(_pickerType<6?_pickerType:_pickerType-4);
}
-(CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component{
    return pickerView.bounds.size.height/3;
}

-(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{
     UILabel * lab = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, (pickerView.bounds.size.width-10)/(_pickerType<6?_pickerType:(_pickerType-4)), pickerView.frame.size.height/3)];
    lab.font = [UIFont systemFontOfSize:14];
    lab.textAlignment = NSTextAlignmentCenter;
    
    if (_selDateArray.count == _dataArray.count) {

        if (row == [pickerView selectedRowInComponent:component]) {
            NSMutableArray * array = [[NSMutableArray alloc]initWithArray:@[@"年",@"月",@"日",@"時",@"分"]];
        
            if (_pickerType>5) {
                for (int i = 0; i<9-_pickerType; i++) {
                    [array removeObjectAtIndex:0];
                }
            }
        
            NSString * str = [NSString stringWithFormat:@"%@%@",_dataArray[component][row],array[component]];
            NSMutableAttributedString * attrubutedStr = [[NSMutableAttributedString alloc]initWithString:str];
        
            [attrubutedStr setAttributes:@{NSForegroundColorAttributeName:[UIColor lightGrayColor]} range:NSMakeRange([str rangeOfString:array[component]].location, 1)];
        
            lab.textColor = [UIColor redColor];
            lab.attributedText = attrubutedStr;
        
        }else{
            lab.text = _dataArray[component][row];
            lab.textColor = [UIColor blackColor];
        
        }
    }else{
        lab.text = _dataArray[component][row];
        lab.textColor = [UIColor blackColor];
        
    }
    
    return lab;
}

-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
    
    [pickerView reloadComponent:component];
    int index = (_pickerType<6 && component == 1)?2:((_pickerType == 8 && component == 0)?1:0);

    if (index) {//選中月份時重新整理天數
        NSInteger year = (index == 1)?_components.year:[_selDateArray[index-2] integerValue];
        [_dataArray replaceObjectAtIndex:index withObject:[self dayArrayMonth:[_dataArray[component][row] integerValue] year:year]];
        
        NSInteger selRow = [pickerView selectedRowInComponent:index];
        [pickerView reloadComponent:index];
        
        if (selRow<[_dataArray[index] count]) {
        }else{
            [pickerView selectRow:0 inComponent:index animated:YES];
            [_selDateArray replaceObjectAtIndex:index withObject:_dataArray[index][0]];
        }
    }
    
    [_selDateArray replaceObjectAtIndex:component withObject:_dataArray[component][row]];
}
//確定
-(void)trueButtonClick:(UIButton *)button{
    self.backTime([_selDateArray componentsJoinedByString:@":"]);
    [self removeFromSuperview];
}
//取消
-(void)cancelButtonClick:(UIButton *)button{
    [self removeFromSuperview];
}

//資料來源
-(NSMutableArray *)dataSourceArray{
    NSMutableArray * sourceArray = [[NSMutableArray alloc]init];
    NSArray * yearArr = @[[NSString stringWithFormat:@"%ld",_components.year],
                          [NSString stringWithFormat:@"%ld",_components.year+1],
                          [NSString stringWithFormat:@"%ld",_components.year+2],
                          [NSString stringWithFormat:@"%ld",_components.year+3],
                          [NSString stringWithFormat:@"%ld",_components.year+4]];
    NSArray * monthArr = @[@"01",@"02",@"03",@"04",@"05",@"06",@"07",@"08",@"09",@"10",@"11",@"12"];
    NSArray * dayArr = [self dayArrayMonth:_components.month year:_components.year];
    NSArray * hourArr = @[@"00",@"01",@"02",@"03",@"04",@"05",@"06",@"07",@"08",@"09",@"10",@"11",@"12",@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21",@"22",@"23"];
    
    NSMutableArray * minutesArr = [[NSMutableArray alloc]init];
    for (int i = 0 ; i<60; i++) {
        [minutesArr addObject:[NSString stringWithFormat:@"%@%d",i<
[email protected]
"0":@"",i]]; } NSArray * array = @[yearArr,monthArr,dayArr,hourArr,minutesArr]; switch (_pickerType) { case PickerTypeDay: case PickerTypeHour: case PickerTypeMinute:{//年月日 & 時 & 分 for (int i = 0; i<_pickerType; i++) { [sourceArray addObject:array[i]]; } } break; case PickerTypeMinuteHour: case PickerTypeMinuteDay: case PickerTypeMinuteMonth:{//月 & 日 & 時分 for (int i = 0; i<_pickerType-4; i++) { [sourceArray insertObject:array[4-i] atIndex:0]; } } break; default: break; } return sourceArray; } //根據月份返回日期 -(NSArray *)dayArrayMonth:(NSInteger)month year:(NSInteger)year{ NSArray * dayArr = [[NSArray alloc]init]; switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: dayArr = @[@"01",@"02",@"03",@"04",@"05",@"06",@"07",@"08",@"09",@"10",@"11",@"12",@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21",@"22",@"23",@"24",@"25",@"26",@"27",@"28",@"29",@"30",@"31"]; break; case 4: case 6: case 9: case 11: dayArr = @[@"01",@"02",@"03",@"04",@"05",@"06",@"07",@"08",@"09",@"10",@"11",@"12",@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21",@"22",@"23",@"24",@"25",@"26",@"27",@"28",@"29",@"30"]; break; case 2: if (year%4) { dayArr = @[@"01",@"02",@"03",@"04",@"05",@"06",@"07",@"08",@"09",@"10",@"11",@"12",@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21",@"22",@"23",@"24",@"25",@"26",@"27",@"28"]; }else{ dayArr = @[@"01",@"02",@"03",@"04",@"05",@"06",@"07",@"08",@"09",@"10",@"11",@"12",@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21",@"22",@"23",@"24",@"25",@"26",@"27",@"28",@"29"]; } break; default: break; } return dayArr; } //分解傳來需要顯示的時間 -(NSArray *)receiveTime:(NSString *)timeStr{ NSArray * timeArray = [timeStr componentsSeparatedByString:@":"]; NSMutableArray * timeArr = [[NSMutableArray alloc]init]; for (int i = 0; i<timeArray.count; i++) { NSString * str = [timeArray objectAtIndex:i]; if (str.length == 1) { [timeArr addObject:[NSString stringWithFormat:@"0%@",str]]; }else if(str.length == 0){ [timeArr addObject:@"00"]; }else{ [timeArr addObject:str]; } } return timeArr; } @end

專案地址
Git首頁

相關推薦

iOS 定義時間選擇 DatePicker

6種時間選擇方式: 年月日、年月日時、年月日時分、時分、日時分、月日時分 呼叫方式 [[DatePicker shareManager]showWithType:PickerTypeDay title:nil time:@"2018:10:31" backT

定義時間選擇(更改分割線和距離)

一、首先了解DatePicker原始碼的佈局        年、月、日 是由3個numberPicker組成  通過發射獲取到NumberPicker 如果不想顯示天數 ,重新佈局       lps.wid

定義時間選擇UIPickerView

使用方法:@property (nonatomic, assign) QLChangeTimeView *chooseTimeView;//時間選擇檢視_chooseTimeView = [[NSBundle mainBundle]loadNibNamed:@"QLChangeTim

Android定義時間選擇或者WheelView

public class PickView extends View{ public static final String TAG = "PickerView"; /** * text之間間距和minTextSize之比 */ publ

定義時間選擇控制元件(仿ios滾動效果)

1.先上自定義的控制元件: /** * 滾輪選擇器 * author LH * data 2016/8/20 17:26 */ public class WheelView extends View { public static final String

ios開發 定義日期選擇 PTXDatePickerView

可能有一部分同學在專案中需要用到一個時間選擇器,又不想自己去自定義,那麼在這裡分享一個自定義的時間選擇器。可能直接用在你的專案中不合適,但可以給你提供參考,並快速自定義出一個時間選擇器。 首先描述下該

iOS-自己定義鍵盤選擇

ive 鍵盤 tac spa 人民幣 nco ger num 指示 目標樣式: 直接上代碼: 遵守協議 <UIPickerViewDataSource,UIPickerViewDelegate> 實現方法 //創建 UITe

定義Jquery選擇

如果當前jQuery內建的選擇器不夠用,開發人員也可以擴充套件jQuery,實現使用者自定義的選擇器。 如下面建立一個具有綠色背景元素的選擇器。 <script> $(function(){ // 通過擴充套件$.expr[":"]實現自定義選擇器 $.expr[":

html+js定義顏色選擇

選擇 wid htm borde 效果圖 html () alt mage <!DOCTYPE html><html><head> <meta charset="utf-8"> <title>test&

Android 定義數字選擇,可以根據自己的需求更改

實現效果如下: 還是以往的套路,先把那些專案所需要的給展示出來。 values下的資料夾,attrs.xml <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styl

安卓仿IOS日期或時間選擇WheelPicker

稽核的兄弟~,通過讓我看看文章結構和效果,我還不會用啊 專案裡用到了一個仿IOS的時間日期選擇器,恩,就是那種滾輪效果的,不多說,先看效果! 表示不會用部落格啊,不會搞動態圖。。看這張圖 ,應該是能看出來的 ,就是這個效果。 嘛,先說明下,這個是參考了別人的程式碼

Android基於wheelView的定義日期選擇(可拓展樣式)

基於wheelView的自定義日期選擇器 專案要求效果圖: 要求 “6月20 星期五” 這一項作為一個整體可以滑動,”7時”、”48分”分別作為一個滑動整體。 系統自帶的DatePicker、TimePicker大家都知道,只有這種效果:

安卓定義日曆選擇

哈哈,又要更新部落格了+_+! 這一次發一個日曆選擇器吧! 說實話,看到需求那一刻,我絕對是崩潰的,不過還好有github這個大佬罩著我,所以為了避免重複造輪子,我就去上面找了一下日曆選擇器,一搜一大把,剛開始挺高興的,結果後來越看臉越黑,沒一個符合我的需求

Android 仿 iphone 定義滾動選擇

背景:其實我們都知道,在我們做開發的過程中,會遇到Android 自身所帶控制元件不夠的情況,那麼這個時候,就需要我們自定義控制元件,所以,也就造成了,在開發的過程中,我們一定要掌握好自定義控制元件,不然,當你去一家公司,產品萌妹子過來找你,這個效果很不錯,問你能不能實

Android ListView三級聯動,實現定義地址選擇

說到地址選擇器,好多小夥伴第一印象就是——wheelView~這玩意確實挺好用的^(* ̄(oo) ̄)^! 然而悲劇的故事發生了,傲嬌的老闆不喜歡wheelView那種選中條不動的效果 ~(⊙o⊙)! 好吧,其實是老闆不知道從哪個忘記名字的App看到這種效果,

Spring mvc 定義時間轉換

spring-mvc.xml配置檔案: <!-- 自定義轉換器 --> <bean id="conversionService" class="org.springfr

android基礎-Toast提示框、日曆檢視(CalendarView)元件、日期、時間選擇DatePicker和TimerPicker等

1. Toast提示框 // 建立一個Toast提示資訊 Toast toast = Toast.makeText(MainActivity.this , "簡單

微信小程式-定義單項選擇樣式

效果: wxml: <view bindchange="radioChange"> <view class='list_item' wx:for="{{radioVa

Android定義狀態選擇屬性

其實,android已經給我們提供了比較豐富的狀態選擇器屬性了,比如android:state_checked、android:state_pressed、android:state_selected、android:state_enabled等等,相信大家都不

利用WheelView實現時間選擇DatePicker

先上最後效果圖: 部分程式碼如下(DatePickerDialog.java):package com.ywl5320.pickaddress; import java.util.ArrayList; import java.util.Calendar; impo