转自:http://tech.cncms.com/shouji/iphone/96186_3.html
iPhone应用开发-UIPickerView选取器详解
选取器被用来取代PC上面的下拉菜单,它是一个大大的滚轮,它占用固定的大小 320×216.
二、实现UIPickerViewDelegate和UIPickerViewDataSource
三、读取选取器
下面看个例子:
2、创建数据。我们用到的数据如下:
江苏省: 南京市 无锡市 徐州市 常州市 苏州市 南通市 连云港市 淮安市 盐城市 扬州市 镇江市 泰州市 宿迁市
浙江省: 杭州市 宁波市 温州市 嘉兴市 湖州市 绍兴市 金华市 衢州市 舟山市 台州市 丽水市
安徽省: 合肥市 芜湖市 蚌埠市 淮南市 马鞍山市 淮北市 铜陵市 安庆市 黄山市 滁州市 阜阳市 宿州市 巢湖市 六安市 亳州市 池州市 宣城市 福建省: 福州市 厦门市 莆田市 三明市 泉州市 漳州市 南平市 龙岩市 宁德市
江西省: 南昌市 景德镇市 萍乡市 九江市 新余市 鹰潭市 赣州市 吉安市 宜春市 抚州市 上饶市
山东省: 济南市 青岛市 淄博市 枣庄市 东营市 烟台市 潍坊市 济宁市 泰安市 威海市 日照市 莱芜市 临沂市 德州市 聊城市 滨州市 菏泽市
河南省: 郑州市 开封市 洛阳市 平顶山市 安阳市 鹤壁市 新乡市 焦作市 濮阳市 许昌市 漯河市 三门峡市 南阳市 商丘市 信阳市 周口市 驻马店市
广东省: 广州市 深圳市 珠海市 汕头市 韶关市 佛山市 江门市 湛江市 茂名市 肇庆市 惠州市 梅州市 汕尾市 河源市 阳江市 清远市 东莞市 中山市 潮州市 揭阳市 云浮市
四川省: 成都市 自贡市 攀枝花市 泸州市 德阳市 绵阳市 广元市 遂宁市 内江市 乐山市 南充市 眉山市 宜宾市 广安市 达州市 雅安市 巴中市 资阳市
在前边的文章中曾经提到过plist文件,现在,我们就要用plist文件存储以上数据。为此,选择File — New — New File,在打开的窗口中,左边选择iOS中的Resource,右边选择Property List:
3、单击ViewController.h,向其中添加代码:
#import <UIKit/UIKit.h>
#define kProvinceComponent 0
#define kCityComponent 1
@interface ViewController : UIViewController <UIPickerViewDelegate, UIPickerViewDataSource>
@property (strong, nonatomic) IBOutlet UIPickerView *picker;
@property (strong, nonatomic) NSDictionary *provinceCities;
@property (strong, nonatomic) NSArray *provinces;
@property (strong, nonatomic) NSArray *cities;
- (IBAction)buttonPressed;
@end
4、单击ViewController.m,向其中添加代码:
@synthesize picker;
@synthesize provinceCities;
@synthesize provinces;
@synthesize cities;
4.2 在ViewDidLoad方法中添加代码:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSBundle *bundle = [NSBundle mainBundle];
NSURL *plistURL = [bundle URLForResource:@"provinceCities" withExtension:@"plist"];
NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfURL:plistURL];
self.provinceCities = dictionary;
NSArray *components = [self.provinceCities allKeys];
NSArray *sorted = [components sortedArrayUsingSelector:@selector(compare:)];
//用于对字符串数组进行排序,方法会在排序后返回一个新的数组。有默认的排序方法 compare :
self.provinces = sorted;
NSString *selectedState = [self.provinces objectAtIndex:0];
NSArray *array = [provinceCities objectForKey:selectedState];
self.cities = array;
}
补充:http://www.appfanr.com/2012/06/how-to-give-an-nsdictionary-by-key-sort/
给dictionary 按key排序
代码中NSBundle *bundle = [NSBundle mainBundle];
用于获得当前程序的Main Bundle,这个Bundle可以看成是一个文件夹,其中的内容遵循特定的框架。Main Bundle的一种主要用途是使用程序中的资源,如图片、声音等,本例中使用的是plist文件。
下面的一行NSURL *plistURL = [bundle URLForResource:@"provinceCities" withExtension:@"plist"];
用来获取provinceCities.plist的路径,之后将这个文件中的内容都放在一个NSDictionary对象中,用的是NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfURL:plistURL];
4.3 找到viewDidUnload方法,添加代码:
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view. // e.g.self.myOutlet = nil;
self.picker = nil;
self.provinceCities = nil;
self.provinces = nil;
self.cities = nil; }
4.4 在@end之前添加代码,实现buttonPressed方法:
- (IBAction)buttonPressed:(id)sender {
NSInteger provinceRow = [picker selectedRowInComponent:kProvinceComponent];
NSInteger cityRow = [picker selectedRowInComponent:kCityComponent];
NSString *province = [self.provinces objectAtIndex:provinceRow];
NSString *city = [self.cities objectAtIndex:cityRow];
NSString *title = [[NSString alloc] initWithFormat:@"你选择了%@.", city];
NSString *message = [[NSString alloc] initWithFormat:@"%@属于%@", city, province];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:@"好的" otherButtonTitles: nil]; [alert show];
}
4.5 在@end之前添加代码:
#pragma mark - #pragma mark Picker Date Source Methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
if (component == kProvinceComponent)
{ return [self.provinces count]; }
return [self.cities count];
}
#pragma mark Picker Delegate Methods
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
if (component == kProvinceComponent)
{ return [self.provinces objectAtIndex:row]; }
return [self.cities objectAtIndex:row];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
if (component == kProvinceComponent)
{ NSString *selectedState = [self.provinces objectAtIndex:row];
NSArray *array = [provinceCities objectForKey:selectedState];
self.cities = array;
[picker selectRow:0 inComponent:kCityComponent animated:YES];
[picker reloadComponent:kCityComponent];
}
}
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component
{
if (component == kCityComponent) { return 150; }
return 140;
}
可以看到,跟上篇文章的例子相比,大部分代码是一样的,不同的是增加了pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component这个方法。这个方法中,当检测到修改的是左边转盘的值,则将self.cities中的内容替换成相应的数组,并执行[picker reloadComponent:kCityComponent];这个语句。
可以用来修改每个转盘的宽度,虽然在这个例子中不必要,但是我们得知道是怎么做的。