自定义UIDatePickView

本文介绍了一个iOS应用中实现的日期和省份选择器。通过使用UIDatePicker和UIPickerView,文章展示了如何定制日期选择器来显示中文日期,并设置日期范围限制;同时介绍了如何配置省份选择器来展示中国省份及其对应城市。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//
//  ViewController.m
//  05-UIDatePicker-键盘处理
//
//  Created by Itcast.GuangZhou on 15/10/6.
//  Copyright (c) 2015年 itcast. All rights reserved.
//

#import "ViewController.h"
#import "HMProvince.h"
@interface ViewController ()<UIPickerViewDataSource,UIPickerViewDelegate,UITextFieldDelegate>
// 生日输入框
@property (weak, nonatomic) IBOutlet UITextField *birthField;
// 省份输入框
@property (weak, nonatomic) IBOutlet UITextField *provinceField;

// 日期选择器
@property (strong, nonatomic) UIDatePicker *datePicker;
// 工具条
@property (strong, nonatomic) UIToolbar *toolBar;
// 省份选择器
@property (strong, nonatomic) UIPickerView *pickerView;
// 所有省份数据
@property (strong, nonatomic) NSArray *provinces;
// 记录选中的省份
@property (strong, nonatomic) HMProvince *selectedProvince;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // 设置文本输入框的代理
    self.birthField.delegate = self;
    self.provinceField.delegate = self;
    // 默认显示当天时间
    [self datePickerValueChanged:nil];
}

#pragma mark - 懒加载控件
- (UIDatePicker *)datePicker {
    if (_datePicker == nil) {
        NSLog(@"创建了日前选择器");
        // 创建日期选择器:可以不设置frame
        _datePicker = [[UIDatePicker alloc] init];
        // 设置时区
        _datePicker.locale = [NSLocale localeWithLocaleIdentifier:@"zh_CN"];
        
        // 设置时间模式
        _datePicker.datePickerMode = UIDatePickerModeDate;
        
        // 设置最小时间 (20年前)
        _datePicker.minimumDate = [NSDate dateWithTimeIntervalSinceNow:-(20 * 365 * 24 * 60 * 60)];
        // 设置最大时间 (20年后)
        _datePicker.maximumDate = [NSDate dateWithTimeIntervalSinceNow:(20 * 365 * 24 * 60 * 60)];
        
        // 设置时间间隔
        // 设置的值必须能够被60整除
//        _datePicker.minuteInterval = 30;
        
        // 监听时间值改变事件
        [_datePicker addTarget:self action:@selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged];
    }
    return _datePicker;
}

- (UIToolbar *)toolBar {
    if (_toolBar == nil) {
        // 创建工具条
        _toolBar = [[UIToolbar alloc] init];
        // 设置frame:只要设置高度即可
        _toolBar.frame = CGRectMake(0, 0, 0, 44);
        // 设置背景颜色
//        _toolBar.backgroundColor = [UIColor redColor];
        _toolBar.barTintColor = [UIColor orangeColor];
        _toolBar.tintColor = [UIColor whiteColor];
        // 创建item
        // 上一个
        UIBarButtonItem *lastItem = [[UIBarButtonItem alloc] initWithTitle:@"上一个" style:UIBarButtonItemStylePlain target:self action:@selector(lastItemClick)];
        
        // 下一个
        UIBarButtonItem *nextItem = [[UIBarButtonItem alloc] initWithTitle:@"下一个" style:UIBarButtonItemStylePlain target:self action:@selector(nextItemClick)];
        
        // 创建弹簧
        UIBarButtonItem *flexibleSpaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
        
        // 完成
        UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithTitle:@"完成" style:UIBarButtonItemStylePlain target:self action:@selector(doneItemClick)];
        
        _toolBar.items = @[lastItem,nextItem,flexibleSpaceItem,doneItem];
//        [_toolBar addSubview:lastItem];
    }
    return _toolBar;
}

- (UIPickerView *)pickerView {
    if (_pickerView == nil) {
        // 创建选择器
        _pickerView = [[UIPickerView alloc] init];
        // 设置数据源和代理
        _pickerView.dataSource = self;
        _pickerView.delegate = self;
    }
    return _pickerView;
}

- (NSArray *)provinces {
    if (_provinces == nil) {
        NSLog(@"加载了省份数据");
        _provinces = [HMProvince provinces];
    }
    return _provinces;
}

#pragma mark - UIPickerViewDataSource 数据源方法
// 两列
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
    return 2;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
    if (component == 0) { // 省份列
        return self.provinces.count;
    } else { // 城市列
        // 获得省份所在的行号
        NSInteger provinceIndex = [pickerView selectedRowInComponent:0];
        // 根据索引获得省份
        HMProvince *province = self.provinces[provinceIndex];
        return province.cities.count;
    }
}

#pragma mark - UIPickerView 代理方法
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
    if (component == 0) { // 省份列
        // 根据row获得对应的省份
        HMProvince *province = self.provinces[row];
        return province.name;
    } else if (component == 1) { // 城市列
        // 获得省份所在的行号
        NSInteger provinceIndex = [pickerView selectedRowInComponent:0];
        // 根据索引获得省份
        HMProvince *province = self.provinces[provinceIndex];
        // 获得省份对应的所有城市
        NSArray *cities = province.cities; // 10 11
//        NSLog(@"row = %zd,城市个数= %zd,省名 = %@",row,cities.count,province.name);
        if (cities.count > row) {
            return cities[row];
        }
        return nil;
    }
    return @"";
}

#pragma mark - UITextField 代理方法
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
    if (textField.inputView) return YES;
    
    if (self.birthField == textField) { // 生日
         // 自定义输入框的键盘
        self.birthField.inputView = self.datePicker;
        // 设置键盘输入辅助附件
        self.birthField.inputAccessoryView = self.toolBar;

    } else if(self.provinceField == textField){
        self.provinceField.inputAccessoryView = self.toolBar;
        self.provinceField.inputView = self.pickerView;
        // 默认选中第一个省份
        self.selectedProvince = self.provinces[0];
    }
    return YES;
}

// 监听pickerView选择行事件
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
    if(component == 0) { // 滚动的是省份列
        // 刷新城市列
        [pickerView reloadComponent:1];
        // 主动选择第1列的第0行
        [pickerView selectRow:0 inComponent:1 animated:YES];
        // 获得选中的省份
        self.selectedProvince = self.provinces[row];
    }
    // 设置身份文本输入框的内容
    self.provinceField.text = [NSString stringWithFormat:@"%@ %@",self.selectedProvince.name,self.selectedProvince.cities[(component == 0) ? 0 :row]];
}

#pragma mark - 监听时间值的改变
- (void)datePickerValueChanged:(UIDatePicker *)datePicker{
    // 获得时间
    NSDate *date = datePicker == nil ? [NSDate date]:datePicker.date;
    // 格式化时间
    NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
    // 时间格式
    fmt.dateFormat = @"yyyy-MM-dd";
    // 将时间转换成字符串
    self.birthField.text = [fmt stringFromDate:date];
}

#pragma mark - 监听item的点击
- (void)lastItemClick{
    if ([self.provinceField isFirstResponder]) {
        [self.birthField becomeFirstResponder];
    }
}

- (void)nextItemClick{
    if([self.birthField isFirstResponder]) {
        // 如果是生日文本输入框是第一个响应者
        [self.provinceField becomeFirstResponder];
    }
}

- (void)doneItemClick{
    if (self.provinceField.text.length == 0 && [self.provinceField isFirstResponder]) {
        // 设置省份内容
        self.provinceField.text = [NSString stringWithFormat:@"%@ %@",self.selectedProvince.name,self.selectedProvince.cities[0]];
    }    // 隐藏键盘
    [self.view endEditing:YES];
}
@end


<pre name="code" class="objc">// 模型
#import <Foundation/Foundation.h>

@interface HMProvince : NSObject
/**
 *  省份对应的所有城市
 */
@property (strong, nonatomic) NSArray *cities;
/**
 *  省份的名字
 */
@property (copy, nonatomic) NSString *name;

+(instancetype)provinceWithDict:(NSDictionary *)dict;
- (instancetype)initWithDict:(NSDictionary *)dict;

+(NSArray *)provinces;
@end



<pre name="code" class="objc">// 模型
#import "HMProvince.h"

@implementation HMProvince
- (instancetype) initWithDict:(NSDictionary *)dic
{
    if (self=[super init]) {
        [self setValuesForKeysWithDictionary:dic];
    }
    return self;
}

+ (instancetype) provinceWithDict:(NSDictionary *)dic
{
    return [[self alloc] initWithDict:dic];
}

+ (NSArray *) provinces
{
    NSArray *sourceArr=[NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"cities.plist" ofType:nil]];
    NSMutableArray *desArr=[NSMutableArray array];
    //循环遍历字典数组,字典转模型
    for (NSDictionary *dic in sourceArr) {
        //每一个字典对应着一个模型对象
        HMProvince *provincer=[HMProvince provinceWithDict:dic];
        [desArr addObject:provincer];
    }
    return desArr;
}

@end





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值