zoukankan      html  css  js  c++  java
  • IOS UIPickView+sqlite 选择中国所有城市案例

    1.案例简介

    通过读取文件,将中国所有城市写入sqlite数据库中,现通过UIPickView实现中国所有城市的选择,效果图如下所示

    2.城市对象模型

    中国所有城市数据请看http://blog.csdn.net/whzhaochao/article/details/37969145,城市模型对象如下
    //
    //  CityModel.h
    //  readData
    //
    //  Created by 赵超 on 14-8-28.
    //  Copyright (c) 2014年 赵超. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    @interface CityModel : NSObject
    
    @property (nonatomic,copy) NSString  *pid;      //父级城市ID
    @property (nonatomic,copy) NSString  *cityName; //城市名
    @property (nonatomic,copy) NSString  *ids;      //城市ID
    
    @end
    

    3.城市数据库操作对象

    sqlite封操作BseDB类请看http://blog.csdn.net/whzhaochao/article/details/38865535,然后封装城市对象的数据库操作对象CityDB
    CityDB.h文件
    //
    //  CityDB.h
    //  readData
    //
    //  Created by 赵超 on 14-8-28.
    //  Copyright (c) 2014年 赵超. All rights reserved.
    //
    
    #import "BaseDB.h"
    #import "CityModel.h"
    
    @interface CityDB : BaseDB
    /**
     *CityDB单例
     */
    +(id)ShareDB;
    
    /**
     * 创建数据库
     * dbName:数据库名称
     */
    -(void)creatTableWithDataBaseName:(NSString*) dbName;
    
    /**
     * 增加一个城市
     * city:城市
     * dbName:数据库名称
     */
    -(BOOL)addCity:(CityModel*)city dbName:(NSString*)dbName;
    /**
     * 选择所有的城市
     * dbName:数据库名称
     */
    -(id)selectAllCity:(NSString*)dbName;
    /**
     * 选择所有的省份
     * dbName:数据库名称
     */
    -(id)selectAllProvince:(NSString *)dbName;
    /**
     * 删除所有城市
     * dbName:数据库名称
     */
    -(BOOL)deleteAllCity:(NSString*)dbName;
    /**
     * 通过上一级省份选择下级市
     * city:上一级城市
     * dbName:数据库名称
     */
    -(id)selectCityByProvince:(CityModel*)provice dbName:(NSString*)dbName;
    
    
    @end
    
    CityDB.m文件实现
    //
    //  CityDB.m
    //  readData
    //
    //  Created by 赵超 on 14-8-28.
    //  Copyright (c) 2014年 赵超. All rights reserved.
    //
    
    #import "CityDB.h"
    
    @implementation CityDB
    
    static CityDB *citydb;
    
    +(id)ShareDB{
        if (citydb==nil) {
            citydb=[[CityDB alloc] init];
        }
        return citydb;
    }
    
    -(void)creatTableWithDataBaseName:(NSString *)dbName{
         NSString *sql=@"create table china (ids text primary key,cityName text,pid text )";
        [self createTable:sql dataBaseName:dbName];
    }
    
    -(BOOL)addCity:(CityModel *)city dbName:(NSString *)dbName{
        NSString *sql=@"insert into china values (?,?,?)";
        NSArray *params=@[city.ids,city.cityName,city.pid];
        return [self execSql:sql parmas:params dataBaseName:dbName];
    }
    
    -(id)selectAllCity:(NSString *)dbName{
        NSString *sql=@"select ids,cityName,pid from china";
        return [self selectCity:sql parmas:nil dbName:dbName];
    }
    
    -(id)selectCity:(NSString*)sql parmas:(NSArray*)params dbName:(NSString*)dbName{
        NSArray *result= [self selectSql:sql parmas:params dataBaseName:dbName];
        NSMutableArray *citys=[NSMutableArray array];
        for (NSDictionary *dic in result) {
            CityModel *city=[[CityModel alloc]init];
            city.ids=[dic objectForKey:@"ids"];
            city.cityName=[dic objectForKey:@"cityName"];
            city.pid=[dic objectForKey:@"pid"];
            [citys addObject:city];
        }
        return citys;
    }
    
    -(id)selectAllProvince:(NSString *)dbName{
        NSString *sql=@"select ids,cityName,pid from china where pid=?";
        NSArray  *parmas=@[@"0"];
        return [self selectCity:sql parmas:parmas dbName:dbName];
    }
    
    -(id)selectCityByProvince:(CityModel *)provice dbName:(NSString *)dbName{
        NSString *sql=@"select * from china where pid=?";
        NSArray  *params=@[provice.ids];
        return [self selectCity:sql parmas:params dbName:dbName];
    }
    
    -(BOOL)deleteAllCity:(NSString *)dbName{
        NSString *sql=@"delete from china";
        return [self execSql:sql parmas:nil dataBaseName:dbName];
    }
    
    @end
    

    4.城市数据处理

    中国城市数据放在china.txt中,需要处理后写入数据库中,读取文件装数据写入数据库代码如下
    //调用CitDB对象向数据库中增加一个城市
    -(void)addCity:(CityModel* )city{
        [[CityDB ShareDB] addCity:city dbName:@"China.sqlite"];
    }
    //处理china.txt城市数据,将其写入数据库中
    -(void)readData{
        NSString *path=[[NSBundle mainBundle] pathForResource:@"china" ofType:@"txt"];
        NSLog(@"%@",path);
        char  pid[30],name[30],ids[30];
        
        FILE *f=fopen([path UTF8String], "r");
        int i=0;
        while (!feof(f)) {
            CityModel *city=[[CityModel alloc] init];
            fscanf(f, " %s %s %s ",ids,name,pid);
            NSString *pids=[NSString stringWithUTF8String:pid];
            NSString *names=[NSString stringWithUTF8String:name];
            NSString *idss=[NSString stringWithUTF8String:ids];
            city.ids=idss;
            city.pid=pids;
            city.cityName=names;
            //向数据库插入一个城市
            [self addCity:city];
            NSLog(@"%@ %@ %@ %d",pids,names,idss,++i);
            
        }
    }


    5.UIPickView显示数据

    MainViewControoler用户数据的显示,其.h文件内容如下

    @interface MainViewController : UIViewController<UIPickerViewDataSource,UIPickerViewDelegate>{
        CityModel *privceModel;     //选择的省
        CityModel *cityModel;       //选择的市
        CityModel *subCityModel;    //选择的地级市
        CityModel *areaModel;       //选择的区
        UILabel *selectCity;        //显示选择的结果
    }
    
    
    @property (nonatomic,retain) NSArray *privices;    //所有省份
    
    @property (nonatomic,retain) NSArray *citys;       //省下对应的市
    
    @property (nonatomic,retain) NSArray *subCitys;    //市下对应的地级市
    
    @property (nonatomic,retain) NSArray *area;        //区
    
    
    @end

    在MainViewController的viewDidLoad中添加UIPickView并初始化数据
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        self.view.backgroundColor=[UIColor grayColor];
        
        UIPickerView *pickView=[[UIPickerView alloc] initWithFrame:CGRectMake(0, 100, 0, 0)];
        pickView.dataSource=self;
        pickView.delegate=self;
        pickView.showsSelectionIndicator=YES;
        pickView.backgroundColor=[UIColor whiteColor];
    
        
        [self.view addSubview:pickView];
        //初始化数据
        self.privices=[[CityDB ShareDB] selectAllProvince:dataBaseName];
        CityModel *city=[self.privices objectAtIndex:0];
        self.citys=[[CityDB ShareDB] selectCityByProvince:city dbName:dataBaseName];
        city=[self.citys objectAtIndex:0];
        self.subCitys=[[CityDB ShareDB] selectCityByProvince:city dbName:dataBaseName];
        city=[self.citys objectAtIndex:0];
        self.area=[[CityDB ShareDB] selectCityByProvince:city dbName:dataBaseName];
        
        selectCity=[[UILabel alloc] initWithFrame:CGRectMake(0, 40, 320, 30)];
    }
    

    实现UIPickView的列数和行数代理函数,列数只有4列,第一列的行数是中国所有的省数所以中人返回self.privices.count就可以了,但是第二列必需知道第一列选中哪个省份后,再通过这个省份从数据库库查出下面的市才知道要显示的行数,第3列是基于第2列选中的行数,第4列是基于第3列选中的列数,实现代码如下:
    //UIPcikView总共4列
    - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
        return 4;
    }
    
    //为每列加载行数
    - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
        
        if (component==0) {
            return self.privices.count;
        }else
        if (component==1) {
            //获取第一列选中的省份列表
            NSInteger privoceIndex=[pickerView selectedRowInComponent:0];
            CityModel *privoice=[self.privices objectAtIndex:privoceIndex];
            //从数据库中查询,省份下面的市
            self.citys=[[CityDB ShareDB] selectCityByProvince:privoice dbName:dataBaseName];
            //返回市的个数
            return self.citys.count;
     
        }else
        if (component==2) {
            NSInteger cityIndex=[pickerView selectedRowInComponent:1];
            if (self.citys.count==0) {
                return 0;
            }
            CityModel *subCitys=[self.citys objectAtIndex:cityIndex];
            self.subCitys=[[CityDB ShareDB] selectCityByProvince:subCitys dbName:dataBaseName];
            return self.subCitys.count;
            
        }else
        if (component==3) {
            NSInteger subCityIndex=[pickerView selectedRowInComponent:2];
            if (self.subCitys.count==0) {
                return 0;
            }
            CityModel *ares=[self.subCitys objectAtIndex:subCityIndex];
            self.area=[[CityDB ShareDB] selectCityByProvince:ares dbName:dataBaseName];
            return self.area.count;
        
        }else{
            return 0;
        }
        
    }
    为UIPickView加载每行每列的数据,获取数据时要注意有判断是否为空
    //获取每列每行的名称
    -(NSString*)getCityName:(NSInteger)row componet:(NSInteger) component{
        if (component==0) {
            CityModel *city=[self.privices objectAtIndex:row];
            return city.cityName;
        }else if (component==1) {
            CityModel *city=[self.citys objectAtIndex:row];
            return city.cityName;
        }else if (component==2) {
            if (self.subCitys==nil) {
                return @"";
            }else{
                CityModel *city=[self.subCitys objectAtIndex:row];
                return city.cityName;
            }
        }
        else if (component==3) {
            if (self.area==nil) {
                return @"";
            }else{
                CityModel *city=[self.area objectAtIndex:row];
                return city.cityName;
            }
            
        }
        
        return @"";
    }
    
    -(UIView*) pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{
        
        UILabel *lable=[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 60, 30)];
        //获取名称
        lable.text=[self getCityName:row componet:component];
        lable.font=[UIFont systemFontOfSize:14];
        
        return lable;
    }
    最后实现UIPickView的选择响应事件刷新Pickview,并显示选择的结果
    //获取每列每行的名称
    -(NSString*)getCityName:(NSInteger)row componet:(NSInteger) component{
        if (component==0) {
            CityModel *city=[self.privices objectAtIndex:row];
            return city.cityName;
        }else if (component==1) {
            CityModel *city=[self.citys objectAtIndex:row];
            return city.cityName;
        }else if (component==2) {
            if (self.subCitys==nil) {
                return @"";
            }else{
                CityModel *city=[self.subCitys objectAtIndex:row];
                return city.cityName;
            }
        }
        else if (component==3) {
            if (self.area==nil) {
                return @"";
            }else{
                CityModel *city=[self.area objectAtIndex:row];
                return city.cityName;
            }
            
        }
        
        return @"";
    }
    
    -(UIView*) pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{
        
        UILabel *lable=[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 60, 30)];
        //获取名称
        lable.text=[self getCityName:row componet:component];
        lable.font=[UIFont systemFontOfSize:14];
        
        return lable;
    }


    项目完整工程https://github.com/whzhaochao/IOSChinaCity




  • 相关阅读:
    JS 基于面向对象的 轮播图1
    JS 原型继承的几种方法
    angularJs 自定义服务 provide 与 factory 的区别
    C# 调用JS Eval,高效率
    Linq表连接大全(INNER JOIN、LEFT OUTER JOIN、RIGHT OUTER JOIN、FULL OUTER JOIN、CROSS JOIN)
    C# LINQ干掉for循环
    C# 彻底搞懂async/await
    .NET中的异步编程——动机和单元测试
    .NET中的异步编程——常见的错误和最佳实践
    C# 实用代码段
  • 原文地址:https://www.cnblogs.com/whzhaochao/p/5023433.html
Copyright © 2011-2022 走看看