UIPickerView实现省份城市联动&封装

因为项目需求,自定义弹出视图的基础上加一些用户体验更佳的动画和友情文字以及图片提示等,就有了写了这篇博客,一为方便自己以后在其他项目中复用二为更多开发者拷贝使用,若有书写代码不足之处欢迎批评指正。

先看下我的Demo示例运行效果图如下:

省份城市联动动画.gif

1. 数据源

为了便于演示,这里网上找了plist本地文件

省份城市数据源@2x.png

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,觉得有帮助的点个赞,有不到之处欢迎批评指正。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,846评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,637评论 18 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,778评论 6 342
  • 太阳从东方缓缓升起的时候,我们在干什么? 街角的行人行色匆匆,我却漫无目的的徘徊着。鸽子从我头顶飞...
    _九歌阅读 1,429评论 4 1
  • 不知道是因为身处社会太久了,还是年龄太老了,亦或是想得太多,我变得越来越悲观了。 我前年为一个病危的同事去献血,很...
    文真阅读 2,124评论 6 40