ios DatePicker 自定義,參考他人代碼,整理...優化, 循環滑動scrollview





自定義ios系統空間,UIDatePicker,單獨循環滑動...

一下是代碼....代碼註釋很詳細,不多講...

1. 循環滑動scrollview

//
//  CycleScrollView.h
//  DatePickerScroll
//
//  Created by lance on 14/12/8.
//  Copyright (c) 2014年 Lance. All rights reserved.
//

#import <UIKit/UIKit.h>

@protocol CycleScrollViewDataSource;
@protocol CycleScrollViewDelegate;

@interface CycleScrollView : UIView <UIScrollViewDelegate>

@property (nonatomic, strong, readonly) UIScrollView *scrollView;
/**
 *  當前行
 */
@property (nonatomic, assign) NSInteger index;
@property (nonatomic, assign) id<CycleScrollViewDelegate> delegate;
@property (nonatomic, assign) id<CycleScrollViewDataSource> dataSource;

/**
 *  重新加載數據
 */
- (void)reloadData;

@end


@protocol CycleScrollViewDataSource <NSObject>

@required
/**
 *  rows 行數
 *
 *  @param cycleScrollView CycleScrollView
 *
 *  @return 行數
 */
- (NSInteger)numberOfRowsInCycleScrollView:(CycleScrollView *)cycleScrollView;
/**
 *  行內容
 *
 *  @param cycleScrollView CycleScrollView
 *  @param index           行座標
 *
 *  @return UIView
 */
- (UIView *)cycleScrollView:(CycleScrollView *)cycleScrollView viewForRowAtIndex:(NSInteger)index;

@end

@protocol CycleScrollViewDelegate <NSObject>

@optional
/**
 *  當前選中,回調
 *
 *  @param cycleScrollView CycleScrollView
 *  @param index           行座標
 */
- (void)cycleScrollView:(CycleScrollView *)cycleScrollView didSelectedAtIndex:(NSInteger)index;

@end

//
//  CycleScrollView.m
//  DatePickerScroll
//
//  Created by lance on 14/12/8.
//  Copyright (c) 2014年 Lance. All rights reserved.
//

#import "CycleScrollView.h"

#define visibleRows 5 // 視野中的rows

@interface CycleScrollView ()
{
    /**
     *  view的寬高,行高
     */
    CGFloat _height;
    CGFloat _width;
    CGFloat _rowHeight;
    
    NSInteger _rows;
    NSMutableArray *_views;
    
    /**
     *  顏色,字體
     */
    NSArray *_colorsAndfonts;
}

@end

@implementation CycleScrollView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        
        [self configData];
        
        _height = CGRectGetHeight(frame);
        _width = CGRectGetWidth(frame);
        _rowHeight = _height / visibleRows;
        
        /**
         *  選中色彩
         */
        UIView *selectView = [[UIView alloc] initWithFrame:CGRectMake(0, _rowHeight * 2, _width, _rowHeight)];
        [selectView setBackgroundColor:[UIColor colorWithRed:227.0 / 255.0 green:255 / 255.0  blue:226 / 255.0  alpha:1.0]];
        [self addSubview:selectView];
        
        _scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];
        _scrollView.showsHorizontalScrollIndicator = NO;
        _scrollView.showsVerticalScrollIndicator = NO;
        _scrollView.contentSize = CGSizeMake(_width, _rowHeight * (visibleRows + 2));
        _scrollView.delegate = self;
        [self addSubview:_scrollView];
    }
    
    return self;
}

/**
 *  初始化顏色,字體信息
 */
- (void)configData
{
    _colorsAndfonts = @[
                        @{@"color":[UIColor colorWithRed:186.0 / 255.0 green:186.0 / 255.0 blue:186.0 / 255.0 alpha:1.0], @"font":[UIFont systemFontOfSize:14]},
                        @{@"color":[UIColor colorWithRed:186.0 / 255.0 green:186.0 / 255.0 blue:186.0 / 255.0 alpha:1.0], @"font":[UIFont systemFontOfSize:14]},
                        @{@"color":[UIColor colorWithRed:113.0 / 255.0 green:113.0 / 255.0 blue:113.0 / 255.0 alpha:1.0], @"font":[UIFont systemFontOfSize:16]},
                        
                        @{@"color":[UIColor greenColor], @"font":[UIFont systemFontOfSize:18]},
                        
                        @{@"color":[UIColor colorWithRed:113.0 / 255.0 green:113.0 / 255.0 blue:113.0 / 255.0 alpha:1.0], @"font":[UIFont systemFontOfSize:16]},
                        @{@"color":[UIColor colorWithRed:186.0 / 255.0 green:186.0 / 255.0 blue:186.0 / 255.0 alpha:1.0], @"font":[UIFont systemFontOfSize:14]},
                        @{@"color":[UIColor colorWithRed:186.0 / 255.0 green:186.0 / 255.0 blue:186.0 / 255.0 alpha:1.0], @"font":[UIFont systemFontOfSize:14]}
                        ];
}

- (void)setDataSource:(id<CycleScrollViewDataSource>)dataSource
{
    _dataSource = dataSource;
    
    [self reloadData];
}

- (void)reloadData
{
    _rows = [_dataSource numberOfRowsInCycleScrollView:self];
    
    if (_rows <= 0) {
        return;
    }
    
    [self loadView];
}

- (void)loadView
{
    // 移除已添加的row
    NSArray *subViews = [_scrollView subviews];
    if (subViews && subViews.count != 0) {
        [subViews makeObjectsPerformSelector:@selector(removeFromSuperview)];
    }
    
    // 顯示新的row
    [self createRows];
    
    [_scrollView setContentOffset:CGPointMake(0.0, _rowHeight)];
}

/**
 *  創建rows內容
 */
- (void)createRows
{
    if (_views) {
        _views = [NSMutableArray array];
    } else {
        [_views removeAllObjects];
    }
    
    NSInteger colorIndex = 0;
    for (NSInteger i = _index - 3; i <= _index + 3; i ++) {
        NSInteger index =  [self getValidateIndex:i];
        id data = [_colorsAndfonts objectAtIndex:colorIndex];
        
        UILabel *label = (UILabel*)[_dataSource cycleScrollView:self viewForRowAtIndex:index];
        label.font = [data objectForKey:@"font"];
        label.textColor = [data objectForKey:@"color"];
        [_views addObject:label];
        
        label.frame = CGRectMake(0.0, _rowHeight * colorIndex, _width, _rowHeight);
        [_scrollView addSubview:label];
        
        colorIndex ++;
    }
}

/**
 *  滑動後 ,更新界面顏色,字體
 *
 *  @param index
 */
- (void)setAfterDisplayWithIndex:(NSInteger)index
{
    NSInteger colorIndex = 1;
    for (NSInteger i = index - 2; i <= index + 2; i ++) {
        UILabel *label = (UILabel *)[[_scrollView subviews] objectAtIndex:i];
        id data = [_colorsAndfonts objectAtIndex:colorIndex];
        
        label.font = [data objectForKey:@"font"];
        label.textColor = [data objectForKey:@"color"];
        
        colorIndex ++;
    }
}

#pragma mark UIScrollView delegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGFloat y = scrollView.contentOffset.y;
    
    /**
     *  當滑倒第二行或者第一行結束時,需加載新的
     */
    if ( y >= _rowHeight * 2) {
        _index = [self getValidateIndex:_index + 1];
        
        [self loadView];
    } else if (y <= 0) {
        _index = [self getValidateIndex:_index - 1];
        
        [self loadView];
    }
    
    /**
     *  更新滑動後信息
     */
    [self setAfterDisplayWithIndex:3];
    
    /**
     *  響應結果事件
     */
    if ([self.delegate respondsToSelector:@selector(cycleScrollView:didSelectedAtIndex:)]) {
        [self.delegate cycleScrollView:self didSelectedAtIndex:_index];
    }
}

/**
 *  返回對應的數據下標
 *
 *  @param index   NSInteger
 *
 *  @return NSInteger
 */
- (NSInteger)getValidateIndex:(NSInteger)index;
{
    return index >= 0 ? (index % _rows) : (index + _rows);
}

/**
 *  滑動結束後,設置UIScrollView在第二行
 */
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [scrollView setContentOffset:CGPointMake(0, _rowHeight) animated:YES];
}

/**
 *  滑動結束後,設置UIScrollView在第二行
 */
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    [scrollView setContentOffset:CGPointMake(0, _rowHeight) animated:YES];
}

@end


2. 定義日期控件...

//
//  CustomDatePicker.h
//  DatePickerScroll
//
//  Created by lance on 14/12/9.
//  Copyright (c) 2014年 Lance. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface CustomDatePicker : UIView

@end

//
//  CustomDatePicker.m
//  DatePickerScroll
//
//  Created by lance on 14/12/9.
//  Copyright (c) 2014年 Lance. All rights reserved.
//

#import "CustomDatePicker.h"
#import "CycleScrollView.h"

#define WEEKARRAY @[@"週日", @"週一", @"週二", @"週三", @"週四", @"週五", @"週六"]

@interface CustomDatePicker () <CycleScrollViewDataSource, CycleScrollViewDelegate>
{
    NSMutableArray *_dataArray;
    
    CycleScrollView *_yearCycleScrollView;
    CycleScrollView *_monthCycleScrollView;
    CycleScrollView *_dayCycleScrollView;
    CycleScrollView *_hourCycleScrollView;
    CycleScrollView *_minCycleScrollView;
    
    CGFloat _width;
    CGFloat _height;
    NSInteger _days;
    
    NSCalendar *_calendar;
    
    NSInteger _yearIndex;
    NSInteger _monthIndex;
}

@end

@implementation CustomDatePicker

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    
    if (self) {
        _width = CGRectGetWidth(frame);
        _height = CGRectGetHeight(frame);
        
        _calendar = [NSCalendar currentCalendar];
        
        _days = [self daysOfDate:[NSDate date]];
        
        [self initView];
    }
    
    return self;
}

/**
 *  初始化界面
 */
- (void)initView
{
    NSDateComponents *dateComponents = [_calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit fromDate:[NSDate date]];
    
    /**
     *  初始化臨時變量,當年,月,變化時,初始化當前年月信息
     */
    _yearIndex = 0;
    _monthIndex = 0;
    
    _yearCycleScrollView = [self cycleScrollViewWithFrame:CGRectMake(0.0, 0.0, 80.0, _height)];
    _yearCycleScrollView.index = dateComponents.year - 2000;
    _yearCycleScrollView.dataSource = self;
    _yearCycleScrollView.delegate = self;
    
    _monthCycleScrollView = [self cycleScrollViewWithFrame:CGRectMake(CGRectGetMaxX(_yearCycleScrollView.frame), 0.0, 50.0, _height)];
    _monthCycleScrollView.index = dateComponents.month - 1;
    _monthCycleScrollView.dataSource = self;
    _monthCycleScrollView.delegate = self;
    
    _dayCycleScrollView = [self cycleScrollViewWithFrame:CGRectMake(CGRectGetMaxX(_monthCycleScrollView.frame), 0.0, 90.0, _height)];
    _dayCycleScrollView.index = dateComponents.day - 1;
    _dayCycleScrollView.dataSource = self;
    _dayCycleScrollView.delegate = self;
    
    _hourCycleScrollView = [self cycleScrollViewWithFrame:CGRectMake(CGRectGetMaxX(_dayCycleScrollView.frame), 0.0, 50.0, _height)];
    _hourCycleScrollView.index = dateComponents.hour;
    _hourCycleScrollView.dataSource = self;
    _hourCycleScrollView.delegate = self;
    
    _minCycleScrollView = [self cycleScrollViewWithFrame:CGRectMake(CGRectGetMaxX(_hourCycleScrollView.frame), 0.0, 50.0, _height)];
    _minCycleScrollView.index = dateComponents.minute - 1;
    _minCycleScrollView.dataSource = self;
    _minCycleScrollView.delegate = self;
}

/**
 *  創建一個CycleScrollView
 *
 *  @param frame
 *
 *  @return
 */
- (CycleScrollView *)cycleScrollViewWithFrame:(CGRect)frame
{
    CycleScrollView *cycleScrollView = [[CycleScrollView alloc] initWithFrame:frame];
    [self addSubview:cycleScrollView];
    
    return cycleScrollView;
}

#pragma mark CycleScrollViewDataSource
- (NSInteger)numberOfRowsInCycleScrollView:(CycleScrollView *)cycleScrollView
{
    NSInteger result = 0;
    
    if (cycleScrollView == _yearCycleScrollView) {
        result = 100;
    } else if (cycleScrollView == _monthCycleScrollView) {
        result = 12;
    } else if (cycleScrollView == _dayCycleScrollView) {
        result = _days;
    } else if (cycleScrollView == _hourCycleScrollView) {
        result = 24;
    } else if (cycleScrollView == _minCycleScrollView) {
        result = 60;
    } else {
        result = 31;
    }
    
    return result;
}

- (UIView *)cycleScrollView:(CycleScrollView *)cycleScrollView viewForRowAtIndex:(NSInteger)index
{
    UILabel *lable = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, cycleScrollView.bounds.size.width, cycleScrollView.bounds.size.height / 5)];
    lable.font = [UIFont systemFontOfSize:16];
    lable.textColor = [UIColor colorWithRed:113.0 / 255.0 green:113.0 / 255.0 blue:113.0 / 255.0 alpha:1.0];
    lable.textAlignment = NSTextAlignmentCenter;
    lable.backgroundColor = [UIColor clearColor];
    lable.tag = index + 1;
    
    NSString *result = @"";
    if (cycleScrollView == _yearCycleScrollView) {
        result = [NSString stringWithFormat:@"%ld年", index + 2000];
    } else if (cycleScrollView == _monthCycleScrollView) {
        result = [NSString stringWithFormat:@"%02ld月", index + 1];
    } else if (cycleScrollView == _dayCycleScrollView) {
        /**
         *  根據年,月,日算星期幾...
         */
        UILabel *yearLabel = (UILabel*)[[_yearCycleScrollView.scrollView subviews] objectAtIndex:(_yearIndex) % 7];
        UILabel *monthLabel = (UILabel*)[[_monthCycleScrollView.scrollView subviews] objectAtIndex:(_monthIndex) % 7];
        NSInteger yearInt = yearLabel.tag + 1999;
        NSInteger monthInt = monthLabel.tag;
        NSInteger dayInt = lable.tag;
        
        NSString *dateStr = [NSString stringWithFormat:@"%ld-%02ld-%02ld",yearInt, monthInt, dayInt];
        result = [NSString stringWithFormat:@"%02ld日 %@", dayInt, [self getWeekDay:dateStr]];
        
        _yearIndex ++;
        _monthIndex ++;
    } else if (cycleScrollView == _hourCycleScrollView) {
        result = [NSString stringWithFormat:@"%02ld時", index];
    } else if (cycleScrollView == _minCycleScrollView) {
        result = [NSString stringWithFormat:@"%02ld分", index];
    }
    
    lable.text = result;
    
    return lable;
}

#pragma mark CycleScrollView delegate
- (void)cycleScrollView:(CycleScrollView *)cycleScrollView didSelectedAtIndex:(NSInteger)index
{
    UILabel *yearLabel = (UILabel*)[[_yearCycleScrollView.scrollView subviews] objectAtIndex:3];
    UILabel *monthLabel = (UILabel*)[[_monthCycleScrollView.scrollView subviews] objectAtIndex:3];
    UILabel *dayLabel = (UILabel*)[[_dayCycleScrollView.scrollView subviews] objectAtIndex:3];
    NSInteger yearInt = yearLabel.tag + 1999;
    NSInteger monthInt = monthLabel.tag;
    NSInteger dayInt = dayLabel.tag;
    
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"zh_CN"]];
    [dateFormatter setDateFormat:@"yyyy-MM-dd"];
    
    /**
     *  年,月,發生變化,重新加載天,星期會發生變化
     */
    if (cycleScrollView == _yearCycleScrollView || cycleScrollView == _monthCycleScrollView) {
        NSString *dateStr = [NSString stringWithFormat:@"%ld-%02ld-01",yearInt, monthInt];
        NSInteger day = [self daysOfDate:[dateFormatter dateFromString:dateStr]];
        
        _days = day;
        
        _yearIndex = 0;
        _monthIndex = 0;
        
        [_dayCycleScrollView reloadData];
        
    } else if (cycleScrollView == _dayCycleScrollView) {
        /**
         *  天發生變化,更新星期幾
         */
        NSString *dateStr = [NSString stringWithFormat:@"%ld-%02ld-%02ld",yearInt, monthInt,dayInt];
        dayLabel.text = [NSString stringWithFormat:@"%02ld日 %@",dayInt, [self getWeekDay:dateStr]];
    }
    
    UILabel *hourLabel = [[(UILabel*)_hourCycleScrollView.scrollView subviews] objectAtIndex:3];
    UILabel *minuteLabel = [[(UILabel*)_minCycleScrollView.scrollView subviews] objectAtIndex:3];
    NSInteger hourInt = hourLabel.tag - 1;
    NSInteger minuteInt = minuteLabel.tag - 1;
    
    /**
     *  輸出打印,選中的日期信息
     */
    NSLog(@"%ld%02ld%02ld%02ld%02ld", yearInt, monthInt, dayInt, hourInt, minuteInt);
}

/**
 *  獲取星期
 *
 *  @param strDate 日期字符串
 *
 *  @return 周幾
 */
- (NSString *)getWeekDay:(NSString *)strDate
{
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"zh_CN"]];
    [dateFormatter setDateFormat:@"yyyy-MM-dd"];
    
    NSDate *date = [dateFormatter dateFromString:strDate];
    if (date == nil) {
        return @"";
    }
    
    NSDateComponents *dateComponents = [_calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSWeekdayCalendarUnit fromDate:date];
    // 默認顯示今天
    NSDateComponents *currDateComponents = [_calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:[NSDate date]];
    NSString *weekStr = @"";
    if (dateComponents.year == currDateComponents.year && dateComponents.month == currDateComponents.month && dateComponents.day == currDateComponents.day) {
        weekStr = @"今天";
    } else {
        weekStr = [WEEKARRAY objectAtIndex:dateComponents.weekday - 1];
    }
    
    return weekStr;
}

/**
 *  返回一個月有多少天
 *
 *  @param date 日期
 *
 *  @return 天數
 */
- (NSInteger)daysOfDate:(NSDate *)date
{
    return [_calendar rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:date].length;
}

@end

附代碼地址;代碼地址..

有積分的就去這裏下載嘍,沒積分的,可以私信我,留下郵箱,我郵件給你.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章