首页 > 代码库 > [iOS基础控件 - 6.10.2] PickerView 自定义row内容 国家选择Demo

[iOS基础控件 - 6.10.2] PickerView 自定义row内容 国家选择Demo

A.需求
1.自定义一个UIView和xib,包含国家名和国旗显示
2.学习row的重用
 
B.实现步骤
1.准备plist文件和国旗图片
Image(150)
 
Image(151)
 
2.创建模型
 1 // 2 //  Flag.h 3 //  CountriesSelection 4 // 5 //  Created by hellovoidworld on 14/12/16. 6 //  Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8  9 #import <Foundation/Foundation.h>10 11 @interface Flag : NSObject12 13 /** 国家名 */14 @property(nonatomic, copy) NSString *name;15 16 /** 国旗 */17 @property(nonatomic, copy) NSString *icon;18 19 - (instancetype) initWithDictionary:(NSDictionary *) dictionary;20 + (instancetype) flagWithDictionary:(NSDictionary *) dictionary;21 22 @end
 
 1 // 2 //  Flag.m 3 //  CountriesSelection 4 // 5 //  Created by hellovoidworld on 14/12/16. 6 //  Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8  9 #import "Flag.h"10 11 @implementation Flag12 13 - (instancetype) initWithDictionary:(NSDictionary *) dictionary {14     if (self = [super init]) {15         [self setValuesForKeysWithDictionary:dictionary];16     }17    18     return self;19 }20 21 + (instancetype) flagWithDictionary:(NSDictionary *) dictionary {22     return [[self alloc] initWithDictionary:dictionary];23 }24 25 @end
 
2.拖入PickerView, 准备主界面
Image(152)
 
3.实现dataSource和delegate方法
 1 #pragma mark - dataSource function 2 - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { 3     return 1; 4 } 5  6 - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { 7     return self.countries.count; 8 } 9 10 #pragma mark - delegate function11 // 使用返回UIView的row数据返回方法12 - (UIView *) pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {13     //todo 创建自定义的view14 }
 
4.创建自定义的UIView
Image(153)
 
5.设计自定row内容的xib,指定class
Image(154)
 
Image(155)
 
 
6.拖入控件到FlagView类,创建初始化方法和加载数据方法
 1 // 2 //  FlagView.h 3 //  CountriesSelection 4 // 5 //  Created by hellovoidworld on 14/12/16. 6 //  Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8  9 #import <UIKit/UIKit.h>10 11 @class Flag;12 @interface FlagView : UIView13 14 /** 国旗数据成员 */15 @property(nonatomic, strong) Flag *flag;16 17 /** 自定义构造方法 */18 + (instancetype) flagViewWithPickerView:(UIPickerView *) pickerView;19 20 /** 定义自己的高度 */21 + (CGFloat) flagViewHeight;22 23 @end
 
 1 // 2 //  FlagView.m 3 //  CountriesSelection 4 // 5 //  Created by hellovoidworld on 14/12/16. 6 //  Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8  9 #import "FlagView.h"10 #import "Flag.h"11 12 @interface FlagView()13 14 /** 国家名控件 */15 @property (weak, nonatomic) IBOutlet UILabel *contryLabel;16 /** 国旗控件 */17 @property (weak, nonatomic) IBOutlet UIImageView *flagImage;18 19 @end20 21 @implementation FlagView22 23 + (instancetype) flagViewWithPickerView:(UIPickerView *) pickerView {24     return [[NSBundle mainBundle] loadNibNamed:@"FlagView" owner:nil options:nil].lastObject;25 }26 27 /** 加载数据 */28 - (void) setFlag:(Flag *)flag {29     _flag = flag;30    31     // 1.国家名32     self.contryLabel.text = flag.name;33    34     // 2.国旗35     self.flagImage.image = [UIImage imageNamed:flag.icon];36 }37 38 /** 定义自己的高度 */39 + (CGFloat) flagViewHeight {40     return 44;41 }42 43 @end
 
7.在控制器中加载解析数据
 1 // 2 //  ViewController.m 3 //  CountriesSelection 4 // 5 //  Created by hellovoidworld on 14/12/16. 6 //  Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8  9 #import "ViewController.h"10 #import "Flag.h"11 #import "FlagView.h"12 13 @interface ViewController () <UIPickerViewDataSource, UIPickerViewDelegate>14 15 /** 国家选择器 */16 @property (weak, nonatomic) IBOutlet UIPickerView *pickerView;17 18 /** 国家数组 */19 @property(nonatomic, strong) NSArray *countries;20 21 22 @end23 24 @implementation ViewController25 26 - (void)viewDidLoad {27     [super viewDidLoad];28     // Do any additional setup after loading the view, typically from a nib.29    30     // 设置dataSource31     self.pickerView.dataSource = self;32     // 设置delegate33     self.pickerView.delegate = self;34 }35 36 - (void)didReceiveMemoryWarning {37     [super didReceiveMemoryWarning];38     // Dispose of any resources that can be recreated.39 }40 41 /** 加载数据 */42 - (NSArray *) countries {43     if (nil == _countries) {44         NSArray * dictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"flags.plist" ofType:nil]];45        46         NSMutableArray *mCountriesArray = [NSMutableArray array];47         for (NSDictionary *dict in dictArray) {48             Flag *flag = [Flag flagWithDictionary:dict];49             [mCountriesArray addObject:flag];50         }51        52         _countries = mCountriesArray;53     }54    55     return _countries;56 }57 58 #pragma mark - dataSource function59 - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {60     return 1;61 }62 63 - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {64     return self.countries.count;65 }66 67 #pragma mark - delegate function68 // 使用返回UIView的row数据返回方法69 - (UIView *) pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {70     FlagView *flagView = [FlagView flagViewWithPickerView:self.pickerView];71     flagView.flag = self.countries[row];72  73     return flagView;74 }75 76 /** 设置row的高度 */77 - (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component {78     return [FlagView flagViewHeight];79 }80 81 @end
 
out:
Image(156)
 
 
C.row的重用
PickerView没有像TableView一样提供缓存池的方法 dequeueReusableCellWithIdentifier
在PickerView的delegate的row数据加载方法中提供了reusingView,是iOS内核缓存的UIView
 1 #pragma mark - delegate function 2 // 使用返回UIView的row数据返回方法 3 - (UIView *) pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view { 4     5     FlagView *flagView; 6     if (nil == view) { 7         flagView = [FlagView flagViewWithPickerView:self.pickerView]; 8     } else { 9         NSLog(@"重用");10         flagView = (FlagView *)view;11     }12 13     flagView.flag = self.countries[row];14    15     NSLog(@"flagView - %p, view - %p", flagView, view);16    17     return flagView;18 }
 
==》但是在我的操作中,系统由始至终都没有传入缓存的UIView,每次都是使用了代码创建的FlagView
 
out:
2014-12-16 17:02:58.927 CountriesSelection[19352:1505008] flagView - 0x7ba7ee40, view - 0x0
2014-12-16 17:02:58.931 CountriesSelection[19352:1505008] flagView - 0x7b942300, view - 0x0
2014-12-16 17:02:58.936 CountriesSelection[19352:1505008] flagView - 0x79e44b80, view - 0x0
2014-12-16 17:02:58.937 CountriesSelection[19352:1505008] flagView - 0x79f64bc0, view - 0x0
2014-12-16 17:02:58.940 CountriesSelection[19352:1505008] flagView - 0x79f68e00, view - 0x0
2014-12-16 17:02:58.941 CountriesSelection[19352:1505008] flagView - 0x79f6a720, view - 0x0
2014-12-16 17:02:58.942 CountriesSelection[19352:1505008] flagView - 0x79f6bff0, view - 0x0
2014-12-16 17:02:58.943 CountriesSelection[19352:1505008] flagView - 0x79f6ff30, view - 0x0
2014-12-16 17:02:58.944 CountriesSelection[19352:1505008] flagView - 0x79f6e370, view - 0x0
2014-12-16 17:03:00.134 CountriesSelection[19352:1505008] flagView - 0x7b94a6c0, view - 0x0
2014-12-16 17:03:00.168 CountriesSelection[19352:1505008] flagView - 0x7b94b810, view - 0x0
2014-12-16 17:03:00.605 CountriesSelection[19352:1505008] flagView - 0x79f364c0, view - 0x0
2014-12-16 17:03:00.655 CountriesSelection[19352:1505008] flagView - 0x79f439e0, view - 0x0
2014-12-16 17:03:00.657 CountriesSelection[19352:1505008] flagView - 0x79f5a450, view - 0x0
2014-12-16 17:03:00.873 CountriesSelection[19352:1505008] flagView - 0x79f6cc60, view - 0x0
2014-12-16 17:03:01.477 CountriesSelection[19352:1505008] flagView - 0x7b94ce90, view - 0x0
 
 
 

[iOS基础控件 - 6.10.2] PickerView 自定义row内容 国家选择Demo