因为项目需求,自定义弹出视图的基础上加一些用户体验更佳的动画和友情文字以及图片提示等,就有了写了这篇博客,一为方便自己以后在其他项目中复用二为更多开发者拷贝使用,若有书写代码不足之处欢迎批评指正。
先看下我的Demo示例运行效果图如下:
1. 数据源
为了便于演示,这里网上找了plist本地文件
2. 将本地数据转成模型
创建QDProvincePicker和QDCityPicker类文件
2.1 QDProvincePicker头文件如下:
#import <Foundation/Foundation.h>
#import "QDCityPicker.h"
@interface QDProvincePicker : NSObject
///城市列表
@property (nonatomic, copy) NSArray *Cities;
///省份/直辖市名称
@property (nonatomic, copy) NSString *State;
@end
2.2 QDCityPicker头文件如下:
#import <Foundation/Foundation.h>
@interface QDCityPicker : NSObject
///城市名称
@property (nonatomic, copy) NSString *city;
@end
2.3 然后创建工具类QDProvinceCityMetaTool具体试下如下:
#import <Foundation/Foundation.h>
#import "QDProvincePicker.h"
@interface QDProvinceCityMetaTool : NSObject
//模型数组
+ (NSArray *)provincecity;
@end
#import "QDProvinceCityMetaTool.h"
@implementation QDProvinceCityMetaTool
static NSArray *_provincecity;
+ (NSArray *)provincecity{
if (_provincecity == nil) {
//字典转模型
NSArray *condition = [QDProvincePicker mj_objectArrayWithFilename:@"provincecity.plist"];
_provincecity = condition;
}
return _provincecity;
}
@end
3. 关键一步
创建QDProvinceCityPickerView 带xib文件,具体代码实现
#import <UIKit/UIKit.h>
@interface QDProvinceCityPickerView : UIView
///初始化弹窗视图
+ (instancetype)pickerViewWithFrame:(CGRect)frame tapDoneBtnBlock:(void (^)(NSString *provinceName,NSString *cityName))tapDoneBtnBlock;
///在窗口展示(底部展示)
- (void)alert;
@end
#import "QDProvinceCityPickerView.h"
#import "QDProvinceCityMetaTool.h"
@interface QDProvinceCityPickerView ()<UIPickerViewDataSource,UIPickerViewDelegate>
@property (weak, nonatomic) IBOutlet UIButton *cancelBtn;
@property (weak, nonatomic) IBOutlet UIButton *doneBtn;
@property (weak, nonatomic) IBOutlet UIPickerView *pickerView;
@property (nonatomic, strong) NSArray *provinceCities;//省份/城市
@property (nonatomic, strong) QDProvincePicker *provincePicker;//省份
@property (nonatomic, strong) NSArray *cities;//城市
@property (nonatomic, copy) NSString *selectedCityName;
@property (nonatomic, copy) void (^tapDoneBtnBlock)(NSString *provinceName,NSString *cityName);
@end
@implementation QDProvinceCityPickerView
#pragma mark -getter-
- (NSArray *)provinceCities{
if (_provinceCities == nil) {
_provinceCities = [QDProvinceCityMetaTool provincecity];
}
return _provinceCities;
}
+ (instancetype)pickerViewWithFrame:(CGRect)frame tapDoneBtnBlock:(void (^)(NSString *provinceName,NSString *cityName))tapDoneBtnBlock{
QDProvinceCityPickerView *pickerView = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self) owner:nil options:nil] lastObject];
pickerView.frame = frame;
pickerView.tapDoneBtnBlock = tapDoneBtnBlock;
return pickerView;
}
- (void)alert{
[QDKeyWindow addSubview:self];
//设置frame
[self mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(QDKeyWindow);
make.right.mas_equalTo(QDKeyWindow.mas_right);
make.bottom.mas_equalTo(QDKeyWindow.mas_bottom);
make.height.mas_equalTo(200);
}];
}
//xib唤醒转代码
- (void)awakeFromNib{
[super awakeFromNib];
[self setUpUI];
//默认选中第一个数据
QDProvincePicker *provincePicker = self.provinceCities[0];
self.provincePicker = provincePicker;
self.cities = provincePicker.Cities;
QDCityPicker *cityPicker = provincePicker.Cities[0];
self.selectedCityName = cityPicker.city;
}
- (void)setUpUI{
self.pickerView.dataSource = self;
self.pickerView.delegate = self;
}
//重新布局子控件
- (void)layoutSubviews{
[super layoutSubviews];
}
#pragma mark -点击事件-
- (IBAction)cancelBtn:(UIButton *)btn {
//立刻执行
[self hidePickerView];
}
- (IBAction)DoneBtn:(UIButton *)btn {
//延迟执行
[self performSelector:@selector(hidePickerView) withObject:nil afterDelay:0.1f];
if (self.tapDoneBtnBlock) {
self.tapDoneBtnBlock(self.provincePicker.State,self.selectedCityName);
}
}
#pragma mark -从父视图移除-
- (void)hidePickerView{
[self removeFromSuperview];
}
#pragma mark -UIPickerViewDataSource/UIPickerViewDelegate-
//一共有多少列
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 2;
}
//第component列一共有多少行
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
NSInteger rows = 0;
switch (component) {
case 0:
rows = self.provinceCities.count;
break;
case 1:
rows = self.cities.count;
break;
default:
break;
}
return rows;
}
//第component列第row行显示什么文字
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
NSString * title = nil;
switch (component) {
case 0:{
QDProvincePicker *provincePicker = self.provinceCities[row];
title = provincePicker.State;
}
break;
case 1:{
QDCityPicker *cityPicker = self.cities[row];
title = cityPicker.city;
}
break;
default:
break;
}
return title;
}
//选中了pickerView的第component列第row行
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
switch (component) {
case 0:{
QDProvincePicker *provincePicker = self.provinceCities[row];
self.provincePicker = provincePicker;
//选中省份
self.cities = provincePicker.Cities;
//默认选中第一个城市
QDCityPicker *cityPicker = self.cities[0];
self.selectedCityName = cityPicker.city;
//刷新第二列表格
[self.pickerView reloadComponent:1];
}
break;
case 1:{
QDCityPicker *cityPicker = self.cities[row];
NSString *cityName = cityPicker.city;
self.selectedCityName = cityName;
}
break;
default:
break;
}
}
@end
封装完成了,可定制化比较强,可以直接copy运用在自己的项目当中试试。
调用方式:+pickerViewWithFrame:tapDoneBtnBlock:类方法进行初始化,加载到哪个视图上,自定义,-alert 对象方法默认加到窗口。
QDProvinceCityPickerView *pickerView = [QDProvinceCityPickerView pickerViewWithFrame:CGRectZero tapDoneBtnBlock:^(NSString *provinceName, NSString *cityName) {
DLog(@"省份:%@ -> 城市:%@",provinceName,cityName);
}];
[pickerView alert];
OK,觉得有帮助的点个赞,有不到之处欢迎批评指正。