【iOS】—— 自定义选择器

通常我们在使用很多软件的时候都会遇到选择日期或者性别之类的东西,其选择器非常的炫酷,今天我就来说说怎么自定义一个自己的选择器。

一、UIDatePicker

UIDatePicker就是系统为我们封装的一个选择器,继承于UIControl,它的用法非常简单,并且不需要遵守什么协议,我们只需要创建它,并且再选择它的类型就可以达到目的了,非常简单好用,就像下面这样:

@property (nonatomic, strong) UIDatePicker *showDatePicker;  //系统自带的选择器

    //系统自带的选择器
    self.showDatePicker = [[UIDatePicker alloc] init];
    self.showDatePicker.frame = CGRectMake(100, 400, 200, 50);
    self.showDatePicker.datePickerMode = UIDatePickerModeDateAndTime;
    [self.view addSubview:self.showDatePicker];

效果如下:
423423

datePickerMode

它是该选择的类型,一共有四个选项可选:

UIDatePickerModeTime,          
UIDatePickerModeDate,          
UIDatePickerModeDateAndTime, 
UIDatePickerModeCountDownTimer, 

从这些选项中我们就可以知道,它有一定的局限性,有很多东西它都不能够选择,所以我们就得用到下面说的UIPickerView自定义选择器了。

二、UIPickerView

UIPickerView是iOS为了满足我们需求而出现的一款自定义的选择器,进入UIPickerView的头文件,我们可以发现 UIPickerView直接继承了UIView,其事件处理通过代理方法完成,所以创建UIPickerView的时候记得签它的代理UIPickerViewDataSourceUIPickerViewDelegate。其实它和UITbleView有点像,不过UIPickerView还多了个列属性,UITbleView我们都很熟了,所以可以对比UITbleView的相关属性和代理方法来学习记忆UIPickerView

它的使用其实也非常简单,就和UITbleView十分的相似,只要你会使用其代理的方法就行了。

1.UIPickerViewDataSource对应的代理方法(其代理方法必须要实现):

  • 返回显示的列数
    - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
  • 返回每一列中需要显示的行数
    - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;

2.UIPickerViewDelegate对应的代理方法(其代理方法根据需求进行选择性实现):

  • 返回每一列的宽度
    - (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component;
  • 返回每一列的高度
    - (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component ;
  • 返回UIPickerView控件中指定列的列表项的要显示的内容
    - (nullable NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component ;
  • 返回UIView,作为该UIPickerView控件中指定列的指定行的显示视图
    - (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(nullable UIView *)view ;
  • 选择指定列中的指定行
    - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component ;

UIPickerView的内容大概就这些,非常容易理解和上手。下面就是我随便写的一个自定义的UIPickerView

三、自定义的UIPickerView

ViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
@property (nonatomic, strong) UIButton *myButton;
@end

ViewController.m

#import "ViewController.h"
#import "MyPickerView.h"

#define ScreenWidth [UIScreen mainScreen].bounds.size.width
#define ScreenHeight [UIScreen mainScreen].bounds.size.height

@interface ViewController ()
@property (nonatomic, strong) MyPickerView *timeSelectView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.view.backgroundColor = [UIColor whiteColor];
    
    self.myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [self.myButton setTitle:@"选择" forState:UIControlStateNormal];
    [self.myButton addTarget:self action:@selector(pressSelect:) forControlEvents:UIControlEventTouchUpInside];
    self.myButton.frame = CGRectMake(100, 300, 100, 30);
    [self.view addSubview:self.myButton];
    
    self.timeSelectView = [[MyPickerView alloc] initWithFrame:CGRectZero];
    [self.timeSelectView.sureButton addTarget:self action:@selector(pressSure:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:self.timeSelectView];

//确定按钮事件
- (void)pressSure:(UIButton *)button {
    self.timeSelectView.frame = CGRectZero;
    [self.timeSelectView isShowOnView:NO];
    [self.myButton setTitle:self.timeSelectView.timeString forState:UIControlStateNormal];
}

//按钮事件
- (void)pressSelect:(UIButton *)button {
    self.timeSelectView.frame = CGRectMake(0, 400, ScreenWidth, ScreenHeight - 400);
    [self.timeSelectView isShowOnView:YES];
}

@end

MyPickerView.h

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface MyPickerView : UIView<UIPickerViewDelegate, UIPickerViewDataSource>

@property (nonatomic, strong) UIPickerView *pickerView;  //选择器
@property (nonatomic, strong) UIButton *cancelButton;  //关闭按钮
@property (nonatomic, strong) UIButton *sureButton;  //确认按钮
@property (nonatomic, strong) NSString *timeString;  //最终的时间

@property NSInteger one;
@property NSInteger two;
@property NSInteger three;
@property NSInteger four;

//判断是否要显示视图
- (void)isShowOnView:(BOOL)select;

@end

NS_ASSUME_NONNULL_END

MyPickerView.h

#import "MyPickerView.h"

#define ScreenWidth [UIScreen mainScreen].bounds.size.width
#define ScreenHeight [UIScreen mainScreen].bounds.size.height

@implementation MyPickerView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    
    //初始化数据
    [self p_initData];
    
    //初始化选择器
    [self p_initPickerView];
    
    return self;
}

//初始化选择器
- (void)p_initPickerView {
    
    //初始化按钮
    self.cancelButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [self.cancelButton setTitle:@"取消" forState:UIControlStateNormal];
    [self.cancelButton addTarget:self action:@selector(pressCancel:) forControlEvents:UIControlEventTouchUpInside];
    self.cancelButton.frame = CGRectMake(0, 0, 50, 30);
    self.cancelButton.hidden = YES;
    [self addSubview:self.cancelButton];
    self.sureButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [self.sureButton setTitle:@"确定" forState:UIControlStateNormal];
    self.sureButton.frame = CGRectMake(ScreenWidth - 50, 0, 50, 30);
    self.sureButton.hidden = YES;
    [self addSubview:self.sureButton];
    
    //自定义选择器
    self.pickerView = [[UIPickerView alloc] initWithFrame:CGRectNull];
    self.pickerView.delegate = self;
    self.pickerView.dataSource = self;
    [self addSubview:self.pickerView];
}

//UIPickerViewDataSource

//返回显示的列数
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
    return 4;
}

//返回每一列中需要显示的行数
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
    if (component % 2) {
        return 60;
    } else {
        return 24;
    }
}

//UIPickerViewDelegate

//返回每一列的宽度
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component {
    if (component == 1 || component == 2) {
        return 100;
    } else {
        return 50;
    }
}

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

//返回UIPickerView控件中指定列的列表项的要显示的内容
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
    @autoreleasepool {
        NSString *tempString = [[NSString alloc] initWithFormat:@"%.2ld", row];
        return tempString;
    }
}

//选择指定列中的指定行
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
    switch (component) {
        case 0:
            self.one = row;
            break;
        case 1:
            self.two = row;
            break;
        case 2:
            self.three = row;
            break;
        case 3:
            self.four = row;
            break;
    }
    self.timeString = [NSString stringWithFormat:@"%.2ld:%.2ld - %.2ld:%.2ld", self.one, self.two, self.three, self.four];
    
    NSLog(@"%@", self.timeString);
}

//初始化数据
- (void)p_initData {
    self.timeString = [[NSString alloc] init];
}

//取消按钮事件
- (void)pressCancel:(UIButton *)button {
    self.frame = CGRectZero;
    [self isShowOnView:NO];
}

//判断是否要显示在视图上
- (void)isShowOnView:(BOOL)select {
    if (select) {
        self.pickerView.frame = CGRectMake(0, 30, ScreenWidth, 230);
        self.cancelButton.hidden = NO;
        self.sureButton.hidden = NO;
    } else {
        self.pickerView.frame = CGRectNull;
        self.cancelButton.hidden = YES;
        self.sureButton.hidden = YES;
    }
}

@end

53453
21432

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值