你好,歡迎來到IOS教程網

 Ios教程網 >> IOS使用技巧 >> IOS技巧綜合 >> 自定義支持多種格式可控范圍的時間選擇器控件

自定義支持多種格式可控范圍的時間選擇器控件

編輯:IOS技巧綜合
[摘要]本文是對自定義支持多種格式可控范圍的時間選擇器控件的講解,對學習IOS蘋果軟件開發有所幫助,與大家分享。

支持四種格式,可控制可選時間范圍,如下:

(1)年月日時分

(2)年月日

(3)月日時分

(4)時分

效果如下:

iPhone 5s

iPhone 6

iPhone 6 Plus

ViewController.h

 #import <UIKit/UIKit.h>
 #import "KMDatePicker.h"
 
 @interface ViewController : UIViewController <UITextFieldDelegate, KMDatePickerDelegate>
 @property (strong, nonatomic) UITextField *txtFCurrent;
 
 @property (strong, nonatomic) IBOutlet UITextField *txtFYearMonthDayHourMinute;
 @property (strong, nonatomic) IBOutlet UITextField *txtFMonthDayHourMinute;
 @property (strong, nonatomic) IBOutlet UITextField *txtFYearMonthDay;
 @property (strong, nonatomic) IBOutlet UITextField *txtFHourMinute;
 @property (strong, nonatomic) IBOutlet UITextField *txtFLimitedDate;
 
 @end

ViewController.m

 #import "ViewController.h"
 #import "DateHelper.h"
 #import "NSDate+CalculateDay.h"
 
 @interface ViewController ()
 - (void)layoutUI;
 @end
 
 @implementation ViewController
 
 - (void)viewDidLoad {
     [super viewDidLoad];
     
     [self layoutUI];
 }
 
 - (void)didReceiveMemoryWarning {
     [super didReceiveMemoryWarning];
     // Dispose of any resources that can be recreated.
 }
 
 - (void)layoutUI {
     CGRect rect = [[UIScreen mainScreen] bounds];
     rect = CGRectMake(0.0, 0.0, rect.size.width, 216.0);
     //年月日時分
     KMDatePicker *datePicker = [[KMDatePicker alloc]
                                 initWithFrame:rect
                                 delegate:self
                                 datePickerStyle:KMDatePickerStyleYearMonthDayHourMinute];
     _txtFYearMonthDayHourMinute.inputView = datePicker;
     _txtFYearMonthDayHourMinute.delegate = self;
     
     //年月日
     datePicker = [[KMDatePicker alloc]
                   initWithFrame:rect
                   delegate:self
                   datePickerStyle:KMDatePickerStyleYearMonthDay];
     _txtFYearMonthDay.inputView = datePicker;
     _txtFYearMonthDay.delegate = self;
     
     //月日時分
     datePicker = [[KMDatePicker alloc]
                   initWithFrame:rect
                   delegate:self
                   datePickerStyle:KMDatePickerStyleMonthDayHourMinute];
     _txtFMonthDayHourMinute.inputView = datePicker;
     _txtFMonthDayHourMinute.delegate = self;
     
     //時分
     datePicker = [[KMDatePicker alloc]
                   initWithFrame:rect
                   delegate:self
                   datePickerStyle:KMDatePickerStyleHourMinute];
     _txtFHourMinute.inputView = datePicker;
     _txtFHourMinute.delegate = self;
     
     //年月日時分;限制時間范圍
     datePicker = [[KMDatePicker alloc]
                   initWithFrame:rect
                   delegate:self
                   datePickerStyle:KMDatePickerStyleYearMonthDayHourMinute];
     datePicker.minLimitedDate = [[DateHelper localeDate] addMonthAndDay:-24 days:0];
     datePicker.maxLimitedDate = [datePicker.minLimitedDate addMonthAndDay:48 days:0];
     _txtFLimitedDate.inputView = datePicker;
     _txtFLimitedDate.delegate = self;
 }
 
 - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
     [self.view endEditing:YES];
 }
 
 #pragma mark - UITextFieldDelegate
 - (void)textFieldDidBeginEditing:(UITextField *)textField {
     _txtFCurrent = textField;
 }
 
 #pragma mark - KMDatePickerDelegate
 - (void)datePicker:(KMDatePicker *)datePicker didSelectDate:(KMDatePickerDateModel *)datePickerDate {
     NSString *dateStr = [NSString stringWithFormat:@"%@-%@-%@ %@:%@ %@",
                          datePickerDate.year,
                          datePickerDate.month,
                          datePickerDate.day,
                          datePickerDate.hour,
                          datePickerDate.minute,
                          datePickerDate.weekdayName
                          ];
     _txtFCurrent.text = dateStr;
 }
 
 @end

Main.storyboard

 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8191" systemVersion="15A284" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
     <dependencies>
         <deployment identifier="iOS"/>
         <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8154"/>
     </dependencies>
     <scenes>
         <!--View Controller-->
         <scene sceneID="tne-QT-ifu">
             <objects>
                 <viewController id="BYZ-38-t0r" customClass="ViewController" sceneMemberID="viewController">
                     <layoutGuides>
                         <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
                         <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
                     </layoutGuides>
                     <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
                         <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <subviews>
                             <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" border placeholder="YearMonthDayHourMinute" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="RU4-aD-bI3">
                                 <rect key="frame" x="180" y="58" width="240" height="30"/>
                                 <animations/>
                                 <constraints>
                                     <constraint firstAttribute="width" constant="240" id="9Oi-OR-Ru9"/>
                                     <constraint firstAttribute="height" constant="30" id="Wsa-Pd-EDg"/>
                                 </constraints>
                                 <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                 <textInputTraits key="textInputTraits"/>
                             </textField>
                             <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" border placeholder="MonthDayHourMinute" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="KFz-2Q-yIQ">
                                 <rect key="frame" x="180" y="170" width="240" height="30"/>
                                 <animations/>
                                 <constraints>
                                     <constraint firstAttribute="height" constant="30" id="Qxz-uf-Ngd"/>
                                     <constraint firstAttribute="width" constant="240" id="pTd-xH-c6N"/>
                                 </constraints>
                                 <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                 <textInputTraits key="textInputTraits"/>
                             </textField>
                             <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" border placeholder="YearMonthDay" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="V6m-6E-ZuV">
                                 <rect key="frame" x="180" y="113" width="240" height="30"/>
                                 <animations/>
                                 <constraints>
                                     <constraint firstAttribute="height" constant="30" id="CzE-ap-TTQ"/>
                                     <constraint firstAttribute="width" constant="240" id="eCi-kT-2tg"/>
                                 </constraints>
                                 <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                 <textInputTraits key="textInputTraits"/>
                             </textField>
                             <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" border placeholder="HourMinute" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="Neu-Vj-fG0">
                                 <rect key="frame" x="180" y="228" width="240" height="30"/>
                                 <animations/>
                                 <constraints>
                                     <constraint firstAttribute="width" constant="240" id="XBx-GA-ad2"/>
                                     <constraint firstAttribute="height" constant="30" id="tON-2M-EMP"/>
                                 </constraints>
                                 <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                 <textInputTraits key="textInputTraits"/>
                             </textField>
                             <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" border placeholder="LimitedDate" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="vt1-Aj-i6Y">
                                 <rect key="frame" x="180" y="280" width="240" height="30"/>
                                 <animations/>
                                 <constraints>
                                     <constraint firstAttribute="height" constant="30" id="QSC-Me-tpx"/>
                                     <constraint firstAttribute="width" constant="240" id="X0a-1i-Z2T"/>
                                 </constraints>
                                 <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                 <textInputTraits key="textInputTraits"/>
                             </textField>
                         </subviews>
                         <animations/>
                         <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
                         <constraints>
                             <constraint firstItem="Neu-Vj-fG0" firstAttribute="top" secondItem="KFz-2Q-yIQ" secondAttribute="bottom" constant="28" id="4Wp-rC-NJF"/>
                             <constraint firstItem="RU4-aD-bI3" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" constant="38" id="EU7-1f-tVl"/>
                             <constraint firstItem="RU4-aD-bI3" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="FUG-e6-Qhi"/>
                             <constraint firstItem="Neu-Vj-fG0" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="HRH-7N-oaY"/>
                             <constraint firstItem="V6m-6E-ZuV" firstAttribute="top" secondItem="RU4-aD-bI3" secondAttribute="bottom" constant="25" id="Ind-TZ-Rzm"/>
                             <constraint firstItem="V6m-6E-ZuV" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="JTW-zd-LlI"/>
                             <constraint firstItem="KFz-2Q-yIQ" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="LpF-Jq-wwJ"/>
                             <constraint firstItem="KFz-2Q-yIQ" firstAttribute="top" secondItem="V6m-6E-ZuV" secondAttribute="bottom" constant="27" id="TyY-DA-rn2"/>
                             <constraint firstItem="vt1-Aj-i6Y" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="g0Z-bZ-p3g"/>
                             <constraint firstItem="vt1-Aj-i6Y" firstAttribute="top" secondItem="Neu-Vj-fG0" secondAttribute="bottom" constant="22" id="tyA-YZ-slJ"/>
                         </constraints>
                     </view>
                     <connections>
                         <outlet property="txtFHourMinute" destination="Neu-Vj-fG0" id="wPd-UK-nh5"/>
                         <outlet property="txtFLimitedDate" destination="vt1-Aj-i6Y" id="MzT-tx-thY"/>
                         <outlet property="txtFMonthDayHourMinute" destination="KFz-2Q-yIQ" id="Hp6-Ve-tYI"/>
                         <outlet property="txtFYearMonthDay" destination="V6m-6E-ZuV" id="0cJ-v8-xh3"/>
                         <outlet property="txtFYearMonthDayHourMinute" destination="RU4-aD-bI3" id="neo-JQ-wV5"/>
                     </connections>
                 </viewController>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
             </objects>
         </scene>
     </scenes>
 </document>

NSDate+CalculateDay.h

 #import <Foundation/Foundation.h>
 
 @interface NSDate (CalculateDay)
 /**
  *  獲取對應月份的天數
  *
  *  @return 對應月份的天數
  */
 - (NSUInteger)daysOfMonth;
 
 /**
  *  獲取對應年份的天數
  *
  *  @return 對應年份的天數
  */
 - (NSUInteger)daysOfYear;
 
 /**
  *  獲取對應月份的第一天時間
  *
  *  @return 對應月份的第一天時間
  */
 - (NSDate *)firstDayOfMonth;
 
 /**
  *  獲取對應月份的最後一天時間
  *
  *  @return 對應月份的最後一天時間
  */
 - (NSDate *)lastDayOfMonth;
 
 /**
  *  根據月數和天數間隔,獲取間隔後的時間
  *
  *  @param months 月數間隔
  *  @param days   天數間隔
  *
  *  @return 間隔後的時間
  */
 - (NSDate *)addMonthAndDay:(NSUInteger)months days:(NSUInteger)days;
 
 /**
  *  根據開始時間和結束時間,獲取間隔的時間數組
  *
  *  @param toDate 結束時間
  *
  *  @return 間隔的時間數組(月數和天數;toDate-fromDate的比較值是有符號整數NSInteger,所以存在負數的可能)
  */
 - (NSArray *)monthAndDayBetweenTwoDates:(NSDate *)toDate;
 
 /**
  *  獲取對應周期的數字
  *
  *  @return 對應周期的數字(1:周日、2:周一、3:周二、4:周三、5:周四、6:周五、7:周六)
  */
 - (NSInteger)weekday;
 
 /**
  *  根據地區標示符,獲取對應周期的名稱
  *
  *  @param isShortName      是否是短名稱
  *  @param localeIdentifier 地區標示符(中國:zh_CN、美國:en_US)
  *
  *  @return 對應周期的名稱
  */
 - (NSString *)weekdayName:(BOOL)isShortName localeIdentifier:(NSString *)localeIdentifier;
 
 /**
  *  獲取對應周期的中文名稱
  *
  *  @param isShortName 是否是短名稱
  *
  *  @return 對應周期的中文名稱(短名稱:周日、周一、周二、周三、周四、周五、周六)(長名稱:星期日、星期一、星期二、星期三、星期四、星期五、星期六)
  */
 - (NSString *)weekdayNameCN:(BOOL)isShortName;
 
 /**
  *  獲取對應周期的英文名稱
  *
  *  @param isShortName 是否是短名稱
  *
  *  @return 對應周期的英文名稱(短名稱:Sun、Mon、Tue、Wed、Thu、Fri、Sat)(長名稱:Sunday、Monday、Tuesday、Wednesday、Thursday、Friday、Saturday)
  */
 - (NSString *)weekdayNameEN:(BOOL)isShortName;
 @end

NSDate+CalculateDay.m

 #import "NSDate+CalculateDay.h"
 
 @implementation NSDate (CalculateDay)
 
 - (NSUInteger)daysOfMonth {
     NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
     NSRange range = [gregorian rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:self];
     return range.length;
 }
 
 - (NSUInteger)daysOfYear {
     NSUInteger days = 0;
     NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
     NSDateComponents *comps = [gregorian components:NSCalendarUnitYear fromDate:self];
     
     for (NSUInteger i=1; i<=12; i++) {
         [comps setMonth:i];
         days += [[gregorian dateFromComponents:comps] daysOfMonth];
     }
     return days;
 }
 
 - (NSDate *)firstDayOfMonth {
     NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
     unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth |  NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
     NSDateComponents *comps = [gregorian components:unitFlags fromDate:self];
     [comps setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]]; //使用UTC或GMT解決時區相差8小時的問題
     [comps setDay:1];
     
     return [gregorian dateFromComponents:comps];
 }
 
 - (NSDate *)lastDayOfMonth {
     NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
     unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth |  NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
     NSDateComponents *comps = [gregorian components:unitFlags fromDate:self];
     [comps setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]]; //使用UTC或GMT解決時區相差8小時的問題
     [comps setDay:[self daysOfMonth]];
     
     return [gregorian dateFromComponents:comps];
 }
 
 - (NSDate *)addMonthAndDay:(NSUInteger)months days:(NSUInteger)days {
     NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
     NSDateComponents *comps = [NSDateComponents new];
     [comps setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]]; //使用UTC或GMT解決時區相差8小時的問題
     [comps setMonth:months];
     [comps setDay:days];
     
     return [gregorian dateByAddingComponents:comps toDate:self options:0];
 }
 
 - (NSArray *)monthAndDayBetweenTwoDates:(NSDate *)toDate {
     NSMutableArray *mArrMonthAndDay = [[NSMutableArray alloc] initWithCapacity:2];
     NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
     unsigned unitFlags = NSCalendarUnitMonth |  NSCalendarUnitDay;
     NSDateComponents *comps = [gregorian components:unitFlags fromDate:self toDate:toDate options:0];
     
     [mArrMonthAndDay addObject:[NSString stringWithFormat:@"%ld", (long)[comps month]]];
     [mArrMonthAndDay addObject:[NSString stringWithFormat:@"%ld", (long)[comps day]]];
     return mArrMonthAndDay;
 }
 
 - (NSInteger)weekday {
     return [[[NSCalendar currentCalendar] components:NSCalendarUnitWeekday fromDate:self] weekday];
 }
 
 - (NSString *)weekdayName:(BOOL)isShortName localeIdentifier:(NSString *)localeIdentifier {
     NSDateFormatter *formatter = [NSDateFormatter new];
     formatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];
     formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:localeIdentifier];
     formatter.dateFormat = isShortName ? @"EE" : @"EEEE";
     return [formatter stringFromDate:self];
 }
 
 - (NSString *)weekdayNameCN:(BOOL)isShortName {
     /*
     //方法一:
     NSArray *arrWeekdayName =
     isShortName
     ? @[ @"周日",
          @"周一",
          @"周二",
          @"周三",
          @"周四",
          @"周五",
          @"周六" ]
     : @[
         @"星期日",
         @"星期一",
         @"星期二",
         @"星期三",
         @"星期四",
         @"星期五",
         @"星期六"
         ];
     
     NSInteger weekday = [self weekday];
     return arrWeekdayName[weekday - 1];
      */
     
     //方法二:
     return [self weekdayName:isShortName localeIdentifier:@"zh_CN"];
 }
 
 - (NSString *)weekdayNameEN:(BOOL)isShortName {
     return [self weekdayName:isShortName localeIdentifier:@"en_US"];
 }
 
 @end

DateHelper.h

 #import <Foundation/Foundation.h>
 
 @interface DateHelper : NSObject
 /**
  *  獲取本地當前時間
  *
  *  @return 本地當前時間
  */
 + (NSDate *)localeDate;
 
 /**
  *  根據時間字符串和其格式,獲取對應的時間
  *
  *  @param dateStr 時間字符串
  *  @param format  時間字符串格式(默認值為@"yyyy-MM-dd HH:mm")
  *
  *  @return 對應的時間
  */
 + (NSDate *)dateFromString:(NSString *)dateStr withFormat:(NSString *)format;
 
 @end

DateHelper.m

 #import "DateHelper.h"
 
 @implementation DateHelper
 
 + (NSDate *)localeDate {
     NSDate *date = [NSDate date];
     NSTimeZone *zone = [NSTimeZone systemTimeZone];
     NSInteger interval = [zone secondsFromGMTForDate:date];
     return [date dateByAddingTimeInterval:interval];
 }
 
 + (NSDate *)dateFromString:(NSString *)dateStr withFormat:(NSString *)format {
     NSDateFormatter *formatter = [NSDateFormatter new];
     formatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];
     formatter.dateFormat = format ?: @"yyyy-MM-dd HH:mm";
     return [formatter dateFromString:dateStr];
 }
 
 @end

KMDatePickerDateModel.h

 #import <Foundation/Foundation.h>
 
 @interface KMDatePickerDateModel : NSObject
 @property (copy, nonatomic) NSString *year;
 @property (copy, nonatomic) NSString *month;
 @property (copy, nonatomic) NSString *day;
 @property (copy, nonatomic) NSString *hour;
 @property (copy, nonatomic) NSString *minute;
 @property (copy, nonatomic) NSString *weekdayName;
 
 - (instancetype)initWithDate:(NSDate *)date;
 
 @end

KMDatePickerDateModel.m

 #import "KMDatePickerDateModel.h"
 #import "NSDate+CalculateDay.h"
 
 @implementation KMDatePickerDateModel
 
 - (instancetype)initWithDate:(NSDate *)date {
     if (self = [super init]) {
         NSDateFormatter *formatter = [NSDateFormatter new];
         formatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];
         formatter.dateFormat = @"yyyyMMddHHmm";
         NSString *dateStr = [formatter stringFromDate:date];
         
         _year = [dateStr substringWithRange:NSMakeRange(0, 4)];
         _month = [dateStr substringWithRange:NSMakeRange(4, 2)];
         _day = [dateStr substringWithRange:NSMakeRange(6, 2)];
         _hour = [dateStr substringWithRange:NSMakeRange(8, 2)];
         _minute = [dateStr substringWithRange:NSMakeRange(10, 2)];
         _weekdayName = [date weekdayNameCN:YES];
     }
     return self;
 }
 
 @end

KMDatePicker.h

 #import <UIKit/UIKit.h>
 #import "KMDatePickerDateModel.h"
 
 typedef NS_ENUM(NSUInteger, KMDatePickerStyle) {
     KMDatePickerStyleYearMonthDayHourMinute,
     KMDatePickerStyleYearMonthDay,
     KMDatePickerStyleMonthDayHourMinute,
     KMDatePickerStyleHourMinute
 };
 
 @protocol KMDatePickerDelegate;
 @interface KMDatePicker : UIView <UIPickerViewDataSource, UIPickerViewDelegate>
 @property (weak, nonatomic) id<KMDatePickerDelegate> delegate;
 @property (assign, nonatomic) KMDatePickerStyle datePickerStyle;
 @property (strong, nonatomic) NSDate *minLimitedDate; //最小限制時間;默認值為1970-01-01 00:00
 @property (strong, nonatomic) NSDate *maxLimitedDate; //最大限制時間;默認值為2060-12-31 23:59
 @property (strong, nonatomic) NSDate *scrollToDate; //滾動到指定時間;默認值為當前時間
 
 - (instancetype)initWithFrame:(CGRect)frame delegate:(id<KMDatePickerDelegate>)delegate datePickerStyle:(KMDatePickerStyle)datePickerStyle;
 
 @end
 
 @protocol KMDatePickerDelegate <NSObject>
 @required
 - (void)datePicker:(KMDatePicker *)datePicker didSelectDate:(KMDatePickerDateModel *)datePickerDate;
 
 @end

KMDatePicker.m

 #import "KMDatePicker.h"
 #import "NSDate+CalculateDay.h"
 #import "DateHelper.h"
 
 #define kDefaultMinLimitedDate @"1970-01-01 00:00"
 #define kDefaultMaxLimitedDate @"2060-12-31 23:59"
 #define kMonthCountOfEveryYear 12
 #define kHourCountOfEveryDay 24
 #define kMinuteCountOfEveryHour 60
 #define kRowDisabledStatusColor [UIColor redColor]
 #define kRowNormalStatusColor [UIColor blackColor]
 #define kWidthOfTotal self.frame.size.width
 #define kHeightOfButtonContentView 35.0
 #define kButtonNormalStatusColor [UIColor colorWithRed:0.0 green:0.5 blue:1.0 alpha:1.0]
 
 @interface KMDatePicker () {
     UIPickerView *pikV;
     
     //最小和最大限制時間、滾動到指定時間實體對象實例
     KMDatePickerDateModel *datePickerDateMinLimited;
     KMDatePickerDateModel *datePickerDateMaxLimited;
     KMDatePickerDateModel *datePickerDateScrollTo;
     
     //存儲時間數據源的數組
     NSMutableArray *mArrYear;
     NSMutableArray *mArrMonth;
     NSMutableArray *mArrDay;
     NSMutableArray *mArrHour;
     NSMutableArray *mArrMinute;
     
     //時間數據源的數組中,選中元素的索引
     NSInteger yearIndex;
     NSInteger monthIndex;
     NSInteger dayIndex;
     NSInteger hourIndex;
     NSInteger minuteIndex;
 }
 
 - (void)addUnitLabel:(NSString *)text withPointX:(CGFloat)pointX;
 - (NSUInteger)daysOfMonth;
 - (void)reloadDayArray;
 - (void)loadData;
 - (void)scrollToDateIndexPosition;
 - (void)playDelegateAfterSelectedRow;
 - (BOOL)validatedDate:(NSDate *)date;
 - (BOOL)canShowScrollToNowButton;
 - (void)cancel:(UIButton *)sender;
 - (void)scrollToNowDateIndexPosition:(UIButton *)sender;
 - (void)confirm:(UIButton *)sender;
 - (UIColor *)monthRowTextColor:(NSInteger)row;
 - (UIColor *)dayRowTextColor:(NSInteger)row;
 - (UIColor *)hourRowTextColor:(NSInteger)row;
 - (UIColor *)minuteRowTextColor:(NSInteger)row;
 
 @end
 
 @implementation KMDatePicker
 
 - (instancetype)init {
     if (self = [super init]) {
         self.backgroundColor = [UIColor whiteColor];
     }
     return self;
 }
 
 - (instancetype)initWithFrame:(CGRect)frame {
     if (self = [super initWithFrame:frame]) {
         self.backgroundColor = [UIColor whiteColor];
     }
     return self;
 }
 
 - (instancetype)initWithFrame:(CGRect)frame delegate:(id<KMDatePickerDelegate>)delegate datePickerStyle:(KMDatePickerStyle)datePickerStyle {
     _delegate = delegate;
     _datePickerStyle = datePickerStyle;
     return [self initWithFrame:frame];
 }
 
 #pragma mark - 自定義方法
 - (void)addUnitLabel:(NSString *)text withPointX:(CGFloat)pointX {
     CGFloat pointY = pikV.frame.size.height/2 - 10.0 + kHeightOfButtonContentView;
     UILabel *lblUnit = [[UILabel alloc] initWithFrame:CGRectMake(pointX, pointY, 20.0, 20.0)];
     lblUnit.text = text;
     lblUnit.textAlignment = NSTextAlignmentCenter;
     lblUnit.textColor = [UIColor blackColor];
     lblUnit.backgroundColor = [UIColor clearColor];
     lblUnit.font = [UIFont systemFontOfSize:18.0];
     lblUnit.layer.shadowColor = [[UIColor whiteColor] CGColor];
     lblUnit.layer.shadowOpacity = 0.5;
     lblUnit.layer.shadowRadius = 5.0;
     [self addSubview:lblUnit];
 }
 
 - (NSUInteger)daysOfMonth {
     NSString *dateStr = [NSString stringWithFormat:@"%@-%@-01 00:00", mArrYear[yearIndex], mArrMonth[monthIndex]];
     return [[DateHelper dateFromString:dateStr withFormat:@"yyyy-MM-dd HH:mm"] daysOfMonth];
 }
 
 - (void)reloadDayArray {
     mArrDay = [NSMutableArray new];
     for (NSUInteger i=1, len=[self daysOfMonth]; i<=len; i++) {
         [mArrDay addObject:[NSString stringWithFormat:@"%02ld", (long)i]];
     }
 }
 
 - (void)loadData {
     //初始化最小和最大限制時間、滾動到指定時間實體對象實例
     if (!_minLimitedDate) {
         _minLimitedDate = [DateHelper dateFromString:kDefaultMinLimitedDate withFormat:nil];
     }
     datePickerDateMinLimited = [[KMDatePickerDateModel alloc] initWithDate:_minLimitedDate];
     
     if (!_maxLimitedDate) {
         _maxLimitedDate = [DateHelper dateFromString:kDefaultMaxLimitedDate withFormat:nil];
     }
     datePickerDateMaxLimited = [[KMDatePickerDateModel alloc] initWithDate:_maxLimitedDate];
     
     //滾動到指定時間;默認值為當前時間。如果是使用自定義時間小於最小限制時間,這時就以最小限制時間為准;如果是使用自定義時間大於最大限制時間,這時就以最大限制時間為准
     if (!_scrollToDate) {
         _scrollToDate = [DateHelper localeDate];
     }
     if ([_scrollToDate compare:_minLimitedDate] == NSOrderedAscending) {
         _scrollToDate = _minLimitedDate;
     } else if ([_scrollToDate compare:_maxLimitedDate] == NSOrderedDescending) {
         _scrollToDate = _maxLimitedDate;
     }
     datePickerDateScrollTo = [[KMDatePickerDateModel alloc] initWithDate:_scrollToDate];
     
     //初始化存儲時間數據源的數組
     //年
     mArrYear = [NSMutableArray new];
     for (NSInteger beginVal=[datePickerDateMinLimited.year integerValue], endVal=[datePickerDateMaxLimited.year integerValue]; beginVal<=endVal; beginVal++) {
         [mArrYear addObject:[NSString stringWithFormat:@"%ld", (long)beginVal]];
     }
     yearIndex = [datePickerDateScrollTo.year integerValue] - [datePickerDateMinLimited.year integerValue];
     
     //月
     mArrMonth = [[NSMutableArray alloc] initWithCapacity:kMonthCountOfEveryYear];
     for (NSInteger i=1; i<=kMonthCountOfEveryYear; i++) {
         [mArrMonth addObject:[NSString stringWithFormat:@"%02ld", (long)i]];
     }
     monthIndex = [datePickerDateScrollTo.month integerValue] - 1;
     
     //日
     [self reloadDayArray];
     dayIndex = [datePickerDateScrollTo.day integerValue] - 1;
     
     //時
     mArrHour = [[NSMutableArray alloc] initWithCapacity:kHourCountOfEveryDay];
     for (NSInteger i=0; i<kHourCountOfEveryDay; i++) {
         [mArrHour addObject:[NSString stringWithFormat:@"%02ld", (long)i]];
     }
     hourIndex = [datePickerDateScrollTo.hour integerValue];
     
     //分
     mArrMinute = [[NSMutableArray alloc] initWithCapacity:kMinuteCountOfEveryHour];
     for (NSInteger i=0; i<kMinuteCountOfEveryHour; i++) {
         [mArrMinute addObject:[NSString stringWithFormat:@"%02ld", (long)i]];
     }
     minuteIndex = [datePickerDateScrollTo.minute integerValue];
 }
 
 - (void)scrollToDateIndexPosition {
     NSArray *arrIndex;
     switch (_datePickerStyle) {
         case KMDatePickerStyleYearMonthDayHourMinute: {
             arrIndex = @[
                          [NSNumber numberWithInteger:yearIndex],
                          [NSNumber numberWithInteger:monthIndex],
                          [NSNumber numberWithInteger:dayIndex],
                          [NSNumber numberWithInteger:hourIndex],
                          [NSNumber numberWithInteger:minuteIndex]
                          ];
             break;
         }
         case KMDatePickerStyleYearMonthDay: {
             arrIndex = @[
                          [NSNumber numberWithInteger:yearIndex],
                          [NSNumber numberWithInteger:monthIndex],
                          [NSNumber numberWithInteger:dayIndex]
                          ];
             break;
         }
         case KMDatePickerStyleMonthDayHourMinute: {
             arrIndex = @[
                          [NSNumber numberWithInteger:monthIndex],
                          [NSNumber numberWithInteger:dayIndex],
                          [NSNumber numberWithInteger:hourIndex],
                          [NSNumber numberWithInteger:minuteIndex]
                          ];
             break;
         }
         case KMDatePickerStyleHourMinute: {
             arrIndex = @[
                          [NSNumber numberWithInteger:hourIndex],
                          [NSNumber numberWithInteger:minuteIndex]
                          ];
             break;
         }
     }
 
     for (NSUInteger i=0, len=arrIndex.count; i<len; i++) {
         [pikV selectRow:[arrIndex[i] integerValue] inComponent:i animated:YES];
     }
 }
 
 - (BOOL)validatedDate:(NSDate *)date {
     NSString *minDateStr = [NSString stringWithFormat:@"%@-%@-%@ %@:%@",
                             datePickerDateMinLimited.year,
                             datePickerDateMinLimited.month,
                             datePickerDateMinLimited.day,
                             datePickerDateMinLimited.hour,
                             datePickerDateMinLimited.minute
                             ];
     
     return !([date compare:[DateHelper dateFromString:minDateStr withFormat:nil]] == NSOrderedAscending ||
              [date compare:_maxLimitedDate] == NSOrderedDescending);
 }
 
 - (BOOL)canShowScrollToNowButton {
     return [self validatedDate:[DateHelper localeDate]];
 }
 
 - (void)cancel:(UIButton *)sender {
     UIViewController *delegateVC = (UIViewController *)self.delegate;
     [delegateVC.view endEditing:YES];
 }
 
 - (void)scrollToNowDateIndexPosition:(UIButton *)sender {
     //為了區別最大最小限制范圍外行的標簽顏色,這裡需要重新加載所有組件列
     [pikV reloadAllComponents];
     
     _scrollToDate = [DateHelper localeDate];
     datePickerDateScrollTo = [[KMDatePickerDateModel alloc] initWithDate:_scrollToDate];
     yearIndex = [datePickerDateScrollTo.year integerValue] - [datePickerDateMinLimited.year integerValue];
     monthIndex = [datePickerDateScrollTo.month integerValue] - 1;
     dayIndex = [datePickerDateScrollTo.day integerValue] - 1;
     hourIndex = [datePickerDateScrollTo.hour integerValue];
     minuteIndex = [datePickerDateScrollTo.minute integerValue];
     [self scrollToDateIndexPosition];
 }
 
 - (void)confirm:(UIButton *)sender {
     [self playDelegateAfterSelectedRow];
     
     [self cancel:sender];
 }
 
 - (UIColor *)monthRowTextColor:(NSInteger)row {
     UIColor *color = kRowNormalStatusColor;
     NSString *dateStr = [NSString stringWithFormat:@"%@-%@-01 00:00",
                          mArrYear[yearIndex],
                          mArrMonth[row]
                          ];
     NSDate *date = [DateHelper dateFromString:dateStr withFormat:nil];
     
     NSString *minDateStr = [NSString stringWithFormat:@"%@-%@-01 00:00",
                          datePickerDateMinLimited.year,
                          datePickerDateMinLimited.month
                          ];
     
     if ([date compare:[DateHelper dateFromString:minDateStr withFormat:nil]] == NSOrderedAscending ||
         [date compare:_maxLimitedDate] == NSOrderedDescending) {
         color = kRowDisabledStatusColor;
     }
     
     return color;
 }
 
 - (UIColor *)dayRowTextColor:(NSInteger)row {
     UIColor *color = kRowNormalStatusColor;
     NSString *dateStr = [NSString stringWithFormat:@"%@-%@-%@ 00:00",
                          mArrYear[yearIndex],
                          mArrMonth[monthIndex],
                          mArrDay[row]
                          ];
     NSDate *date = [DateHelper dateFromString:dateStr withFormat:nil];
     
     NSString *minDateStr = [NSString stringWithFormat:@"%@-%@-%@ 00:00",
                             datePickerDateMinLimited.year,
                             datePickerDateMinLimited.month,
                             datePickerDateMinLimited.day
                             ];
     
     if ([date compare:[DateHelper dateFromString:minDateStr withFormat:nil]] == NSOrderedAscending ||
         [date compare:_maxLimitedDate] == NSOrderedDescending) {
         color = kRowDisabledStatusColor;
     }
     
     return color;
 }
 
 - (UIColor *)hourRowTextColor:(NSInteger)row {
     UIColor *color = kRowNormalStatusColor;
     NSString *dateStr = [NSString stringWithFormat:@"%@-%@-%@ %@:00",
                          mArrYear[yearIndex],
                          mArrMonth[monthIndex],
                          mArrDay[dayIndex],
                          mArrHour[row]
                          ];
     NSDate *date = [DateHelper dateFromString:dateStr withFormat:nil];
     
     NSString *minDateStr = [NSString stringWithFormat:@"%@-%@-%@ %@:00",
                             datePickerDateMinLimited.year,
                             datePickerDateMinLimited.month,
                             datePickerDateMinLimited.day,
                             datePickerDateMinLimited.hour
                             ];
     
     if ([date compare:[DateHelper dateFromString:minDateStr withFormat:nil]] == NSOrderedAscending ||
         [date compare:_maxLimitedDate] == NSOrderedDescending) {
         color = kRowDisabledStatusColor;
     }
     
     return color;
 }
 
 - (UIColor *)minuteRowTextColor:(NSInteger)row {
     NSString *format = @"yyyy-MM-dd HH:mm:ss";
     UIColor *color = kRowNormalStatusColor;
     NSString *dateStr = [NSString stringWithFormat:@"%@-%@-%@ %@:%@:00",
                          mArrYear[yearIndex],
                          mArrMonth[monthIndex],
                          mArrDay[dayIndex],
                          mArrHour[hourIndex],
                          mArrMinute[row]
                          ];
     NSDate *date = [DateHelper dateFromString:dateStr withFormat:format];
     
     NSString *minDateStr = [NSString stringWithFormat:@"%@-%@-%@ %@:%@:00",
                             datePickerDateMinLimited.year,
                             datePickerDateMinLimited.month,
                             datePickerDateMinLimited.day,
                             datePickerDateMinLimited.hour,
                             datePickerDateMinLimited.minute
                             ];
     
     if ([date compare:[DateHelper dateFromString:minDateStr withFormat:format]] == NSOrderedAscending ||
         [date compare:_maxLimitedDate] == NSOrderedDescending) {
         color = kRowDisabledStatusColor;
     }
     
     return color;
 }
 
 #pragma mark - 繪制內容
 - (void)drawRect:(CGRect)rect {
     //加載數據
     [self loadData];
     
     //初始化頭部按鈕(取消、現在時間、確定)
     UIView *buttonContentView = [[UIView alloc] initWithFrame:CGRectMake(-2.0, 0.0, kWidthOfTotal + 4.0, kHeightOfButtonContentView)];
     buttonContentView.layer.borderColor = [UIColor lightGrayColor].CGColor;
     buttonContentView.layer.borderWidth = 0.5;
     [self addSubview:buttonContentView];
     
     UIButton *btnCancel = [UIButton buttonWithType:UIButtonTypeCustom];
     btnCancel.frame = CGRectMake(2.0, 2.5, 60.0, kHeightOfButtonContentView - 5.0);
     btnCancel.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
     [btnCancel setTitle:@"取消" forState:UIControlStateNormal];
     [btnCancel setTitleColor:kButtonNormalStatusColor forState:UIControlStateNormal];
     [btnCancel addTarget:self
                   action:@selector(cancel:)
         forControlEvents:UIControlEventTouchUpInside];
     [buttonContentView addSubview:btnCancel];
     
     if ([self canShowScrollToNowButton]) {
         UIButton *btnScrollToNow = [UIButton buttonWithType:UIButtonTypeCustom];
         btnScrollToNow.frame = CGRectMake(buttonContentView.frame.size.width/2 - 50.0, 2.5, 100.0, kHeightOfButtonContentView - 5.0);
         btnScrollToNow.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
         [btnScrollToNow setTitle:@"現在時間" forState:UIControlStateNormal];
         [btnScrollToNow setTitleColor:kButtonNormalStatusColor forState:UIControlStateNormal];
         [btnScrollToNow addTarget:self
                            action:@selector(scrollToNowDateIndexPosition:)
                  forControlEvents:UIControlEventTouchUpInside];
         [buttonContentView addSubview:btnScrollToNow];
     }
     
     UIButton *btnConfirm = [UIButton buttonWithType:UIButtonTypeCustom];
     btnConfirm.frame = CGRectMake(kWidthOfTotal - 58.0, 2.5, 60.0, kHeightOfButtonContentView - 5.0);
     btnConfirm.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
     [btnConfirm setTitle:@"確定" forState:UIControlStateNormal];
     [btnConfirm setTitleColor:kButtonNormalStatusColor forState:UIControlStateNormal];
     [btnConfirm addTarget:self
                    action:@selector(confirm:)
          forControlEvents:UIControlEventTouchUpInside];
     [buttonContentView addSubview:btnConfirm];
     
     //初始化選擇器視圖控件
     if (!pikV) {
         pikV = [[UIPickerView alloc]initWithFrame:CGRectMake(0.0, kHeightOfButtonContentView, kWidthOfTotal, self.frame.size.height - kHeightOfButtonContentView)];
         pikV.showsSelectionIndicator = YES;
         pikV.backgroundColor = [UIColor clearColor];
         [self addSubview:pikV];
     }
     pikV.dataSource = self;
     pikV.delegate = self;
     
     //初始化滾動到指定時間位置
     [self scrollToDateIndexPosition];
 }
 
 #pragma mark - 執行 KMDatePickerDelegate 委托代理協議方法,用於回調傳遞參數
 - (void)playDelegateAfterSelectedRow {
     if ([self.delegate respondsToSelector:@selector(datePicker:didSelectDate:)]) {
         [self.delegate datePicker:self
                     didSelectDate:datePickerDateScrollTo];
     }
 }
 
 #pragma mark - UIPickerViewDataSource
 - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
     NSInteger numberOfComponents = 0;
     switch (_datePickerStyle) {
         case KMDatePickerStyleYearMonthDayHourMinute: {
             numberOfComponents = 5;
             break;
         }
         case KMDatePickerStyleYearMonthDay: {
             numberOfComponents = 3;
             break;
         }
         case KMDatePickerStyleMonthDayHourMinute: {
             numberOfComponents = 4;
             break;
         }
         case KMDatePickerStyleHourMinute: {
             numberOfComponents = 2;
             break;
         }
     }
     return numberOfComponents;
 }
 
 - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
     NSInteger numberOfRows = 0;
     switch (_datePickerStyle) {
         case KMDatePickerStyleYearMonthDayHourMinute: {
             switch (component) {
                 case 0:
                     numberOfRows = mArrYear.count;
                     break;
                 case 1:
                     numberOfRows = kMonthCountOfEveryYear;
                     break;
                 case 2:
                     numberOfRows = [self daysOfMonth];
                     break;
                 case 3:
                     numberOfRows = kHourCountOfEveryDay;
                     break;
                 case 4:
                     numberOfRows = kMinuteCountOfEveryHour;
                     break;
             }
             break;
         }
         case KMDatePickerStyleYearMonthDay: {
             switch (component) {
                 case 0:
                     numberOfRows = mArrYear.count;
                     break;
                 case 1:
                     numberOfRows = kMonthCountOfEveryYear;
                     break;
                 case 2:
                     numberOfRows = [self daysOfMonth];
                     break;
             }
             break;
         }
         case KMDatePickerStyleMonthDayHourMinute: {
             switch (component) {
                 case 0:
                     numberOfRows = kMonthCountOfEveryYear;
                     break;
                 case 1:
                     numberOfRows = [self daysOfMonth];
                     break;
                 case 2:
                     numberOfRows = kHourCountOfEveryDay;
                     break;
                 case 3:
                     numberOfRows = kMinuteCountOfEveryHour;
                     break;
             }
             break;
         }
         case KMDatePickerStyleHourMinute: {
             switch (component) {
                 case 0:
                     numberOfRows = kHourCountOfEveryDay;
                     break;
                 case 1:
                     numberOfRows = kMinuteCountOfEveryHour;
                     break;
             }
             break;
         }
     }
     return numberOfRows;
 }
 
 #pragma mark - UIPickerViewDelegate
 - (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component {
     CGFloat width = 50.0;
     CGFloat widthOfAverage;
     
     switch (_datePickerStyle) {
         case KMDatePickerStyleYearMonthDayHourMinute: {
             //規則一:平均寬度 = (總共寬度 - 年份相比多兩個數字的寬度 - 分鐘會是右對齊導致需偏移寬度來顯示「分」這個文字) / 5等份
             widthOfAverage = (kWidthOfTotal - 20.0 - 25.0) / 5;
             switch (component) {
                 case 0:
                     width = widthOfAverage + 20.0;
                     //規則二:單位標簽的 X 坐標位置 = 列的水平居中 X 坐標 + 偏移量
                     [self addUnitLabel:@"年" withPointX:width/2 + 24.0];
                     break;
                 case 1:
                     width = widthOfAverage;
                     [self addUnitLabel:@"月" withPointX:(widthOfAverage + 20.0) + width/2 + 16.0];
                     break;
                 case 2:
                     width = widthOfAverage;
                     [self addUnitLabel:@"日" withPointX:(2*widthOfAverage + 20.0) + width/2 + 22.0];
                     break;
                 case 3:
                     width = widthOfAverage;
                     [self addUnitLabel:@"時" withPointX:(3*widthOfAverage + 20.0) + width/2 + 28.0];
                     break;
                 case 4:
                     width = widthOfAverage;
                     [self addUnitLabel:@"分" withPointX:(4*widthOfAverage + 20.0) + width/2 + 32.0];
                     break;
             }
             break;
         }
         case KMDatePickerStyleYearMonthDay: {
             widthOfAverage = (kWidthOfTotal - 20.0 - 15.0) / 3;
             switch (component) {
                 case 0:
                     width = widthOfAverage + 20.0;
                     [self addUnitLabel:@"年" withPointX:width/2 + 24.0];
                     break;
                 case 1:
                     width = widthOfAverage;
                     [self addUnitLabel:@"月" withPointX:(widthOfAverage + 20.0) + width/2 + 16.0];
                     break;
                 case 2:
                     width = widthOfAverage;
                     [self addUnitLabel:@"日" withPointX:(2*widthOfAverage + 20.0) + width/2 + 22.0];
                     break;
             }
             break;
         }
         case KMDatePickerStyleMonthDayHourMinute: {
             widthOfAverage = (kWidthOfTotal - 20.0) / 4;
             switch (component) {
                 case 0:
                     width = widthOfAverage;
                     [self addUnitLabel:@"月" withPointX:width/2 + 11.0];
                     break;
                 case 1:
                     width = widthOfAverage;
                     [self addUnitLabel:@"日" withPointX:widthOfAverage + width/2 + 17.0];
                     break;
                 case 2:
                     width = widthOfAverage;
                     [self addUnitLabel:@"時" withPointX:2*widthOfAverage + width/2 + 23.0];
                     break;
                 case 3:
                     width = widthOfAverage;
                     [self addUnitLabel:@"分" withPointX:3*widthOfAverage + width/2 + 27.0];
                     break;
             }
             break;
         }
         case KMDatePickerStyleHourMinute: {
             widthOfAverage = (kWidthOfTotal - 10.0) / 2;
             switch (component) {
                 case 0:
                     width = widthOfAverage;
                     [self addUnitLabel:@"時" withPointX:width/2 + 12.0];
                     break;
                 case 1:
                     width = widthOfAverage;
                     [self addUnitLabel:@"分" withPointX:widthOfAverage + width/2 + 18.0];
                     break;
             }
             break;
         }
     }
     return width;
 }
 
 - (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component {
     return 30.0;
 }
 
 - (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(nullable UIView *)view {
     UILabel *lblCustom = (UILabel *)view;
     if (!lblCustom) {
         lblCustom = [UILabel new];
         lblCustom.textAlignment = NSTextAlignmentCenter;
         lblCustom.font = [UIFont systemFontOfSize:18.0];
     }
     
     NSString *text;
     UIColor *textColor = kRowNormalStatusColor;
     switch (_datePickerStyle) {
         case KMDatePickerStyleYearMonthDayHourMinute: {
             switch (component) {
                 case 0:
                     text = mArrYear[row];
                     break;
                 case 1:
                     text = mArrMonth[row];
                     textColor = [self monthRowTextColor:row];
                     break;
                 case 2:
                     text = mArrDay[row];
                     textColor = [self dayRowTextColor:row];
                     break;
                 case 3:
                     text = mArrHour[row];
                     textColor = [self hourRowTextColor:row];
                     break;
                 case 4:
                     text = mArrMinute[row];
                     textColor = [self minuteRowTextColor:row];
                     break;
             }
             break;
         }
         case KMDatePickerStyleYearMonthDay: {
             switch (component) {
                 case 0:
                     text = mArrYear[row];
                     break;
                 case 1:
                     text = mArrMonth[row];
                     textColor = [self monthRowTextColor:row];
                     break;
                 case 2:
                     text = mArrDay[row];
                     textColor = [self dayRowTextColor:row];
                     break;
             }
             break;
         }
         case KMDatePickerStyleMonthDayHourMinute: {
             switch (component) {
                 case 0:
                     text = mArrMonth[row];
                     textColor = [self monthRowTextColor:row];
                     break;
                 case 1:
                     text = mArrDay[row];
                     textColor = [self dayRowTextColor:row];
                     break;
                 case 2:
                     text = mArrHour[row];
                     textColor = [self hourRowTextColor:row];
                     break;
                 case 3:
                     text = mArrMinute[row];
                     textColor = [self minuteRowTextColor:row];
                     break;
             }
             break;
         }
         case KMDatePickerStyleHourMinute: {
             switch (component) {
                 case 0:
                     text = mArrHour[row];
                     textColor = [self hourRowTextColor:row];
                     break;
                 case 1:
                     text = mArrMinute[row];
                     textColor = [self minuteRowTextColor:row];
                     break;
             }
             break;
         }
     }
     lblCustom.text = text;
     lblCustom.textColor = textColor;
     return lblCustom;
 }
 
 - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
     NSDate *scrollToDateTemp = _scrollToDate;
     KMDatePickerDateModel *datePickerDateScrollToTemp = datePickerDateScrollTo;
     
     switch (_datePickerStyle) {
         case KMDatePickerStyleYearMonthDayHourMinute: {
             switch (component) {
                 case 0:
                     yearIndex = row;
                     break;
                 case 1:
                     monthIndex = row;
                     break;
                 case 2:
                     dayIndex = row;
                     break;
                 case 3:
                     hourIndex = row;
                     break;
                 case 4:
                     minuteIndex = row;
                     break;
             }
             if (component == 0 || component == 1) {
                 [self reloadDayArray];
                 if (mArrDay.count-1 < dayIndex) {
                     dayIndex = mArrDay.count-1;
                 }
                 //[pickerView reloadComponent:2];
             }
             break;
         }
         case KMDatePickerStyleYearMonthDay: {
             switch (component) {
                 case 0:
                     yearIndex = row;
                     break;
                 case 1:
                     monthIndex = row;
                     break;
                 case 2:
                     dayIndex = row;
                     break;
             }
             if (component == 0 || component == 1) {
                 [self reloadDayArray];
                 if (mArrDay.count-1 < dayIndex) {
                     dayIndex = mArrDay.count-1;
                 }
                 //[pickerView reloadComponent:2];
             }
             break;
         }
         case KMDatePickerStyleMonthDayHourMinute: {
             switch (component) {
                 case 0:
                     monthIndex = row;
                     break;
                 case 1:
                     dayIndex = row;
                     break;
                 case 2:
                     hourIndex = row;
                     break;
                 case 3:
                     minuteIndex = row;
                     break;
             }
             if (component == 0) {
                 [self reloadDayArray];
                 if (mArrDay.count-1 < dayIndex) {
                     dayIndex = mArrDay.count-1;
                 }
                 //[pickerView reloadComponent:1];
             }
             break;
         }
         case KMDatePickerStyleHourMinute: {
             switch (component) {
                 case 0:
                     hourIndex = row;
                     break;
                 case 1:
                     minuteIndex = row;
                     break;
             }
             break;
         }
     }
     
     NSString *dateStr = [NSString stringWithFormat:@"%@-%@-%@ %@:%@",
                          mArrYear[yearIndex],
                          mArrMonth[monthIndex],
                          mArrDay[dayIndex],
                          mArrHour[hourIndex],
                          mArrMinute[minuteIndex]
                          ];
     _scrollToDate = [DateHelper dateFromString:dateStr withFormat:nil];
     datePickerDateScrollTo = [[KMDatePickerDateModel alloc] initWithDate:_scrollToDate];
     
     //為了區別最大最小限制范圍外行的標簽顏色,這裡需要重新加載所有組件列
     [pickerView reloadAllComponents];
     
     //如果選擇時間不在最小和最大限制時間范圍內就回滾
     if (![self validatedDate:_scrollToDate]) {
         _scrollToDate = scrollToDateTemp;
         datePickerDateScrollTo = datePickerDateScrollToTemp;
         yearIndex = [datePickerDateScrollTo.year integerValue] - [datePickerDateMinLimited.year integerValue];
         monthIndex = [datePickerDateScrollTo.month integerValue] - 1;
         dayIndex = [datePickerDateScrollTo.day integerValue] - 1;
         hourIndex = [datePickerDateScrollTo.hour integerValue];
         minuteIndex = [datePickerDateScrollTo.minute integerValue];
         [self scrollToDateIndexPosition];
     }
 }
 
 @end
  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved