一:數據源方法緩存
/** 數據源協議,全部方法都必須實現 */dom
@protocol UIPickerViewDataSource<NSObject>ui
@requiredatom
// 返回要顯示的列數spa
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;代理
// 返回component列中的數據行數指針
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;code
@endcomponent
二:代理方法:對象
** 代理協議,全部方法都是可選的 */
@protocol UIPickerViewDelegate<NSObject>
@optional
// 返回指定列的寬度
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component;
// 返回指定列的行高
- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component;
/**
如下三個返回指定列對應行的內容
能夠是:
1> NSString
2> NSAttributedString
若是同時實現了以上兩個方法,優先選擇NSAttributedString的代理方法執行
3> UIView
若是視圖不可見,系統會緩存這些不使用的視圖,而且回傳以便重複使用
若是返回了一個不一樣的對象,回傳的視圖會被釋放
自定義視圖會被顯示在行的中間位置
*/
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
- (NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component NS_AVAILABLE_IOS(6_0);
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view;
// component列中的row行被選中
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component;
@end
三:pickerView的經常使用方法
// 從新加載全部列的數據
- (void)reloadAllComponents;
// 從新加載指定列的數據
- (void)reloadComponent:(NSInteger)component;
// 選中指定component列中的row行,不會觸發代理方法
- (void)selectRow:(NSInteger)row inComponent:(NSInteger)component animated:(BOOL)animated; // 滾動指定的行到中間位置
// 返回當前選中的行,若是沒有選中行,返回-1
- (NSInteger)selectedRowInComponent:(NSInteger)component;
四:點餐系統代碼實現:
#import "ViewController.h" @interface ViewController ()<UIPickerViewDataSource, UIPickerViewDelegate> - (IBAction)selectAnyFood; @property (weak, nonatomic) IBOutlet UIPickerView *pickView; @property (weak, nonatomic) IBOutlet UILabel *fruitLab; @property (weak, nonatomic) IBOutlet UILabel *foodLab; @property (weak, nonatomic) IBOutlet UILabel *drinkLab; @property (nonatomic, strong) NSArray *foods; @end @implementation ViewController #pragma mark - 懶加載數據 - (NSArray *)foods { if (!_foods) { NSString *path = [[NSBundle mainBundle] pathForResource:@"foods.plist" ofType:nil]; NSArray *foodsArr = [NSArray arrayWithContentsOfFile:path]; _foods = foodsArr; } return _foods; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // 視圖加載完畢默認顯示第0行數據 for (int i = 0; i<self.foods.count; i++) { [self pickerView:nil didSelectRow:0 inComponent:i]; } } #pragma mark - 數據源方法 - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { return self.foods.count; } - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { // 注意爲何 self.foods[component]不能用點語法點出count? /** * [self.foods objectAtIndex:0]; == self.foods[0];//這兩句的效果等價,而self調用objectAtIndex:0這個方法,返回的是一個id類型的萬能指針,它的真實類型要到實際運行的時候才能檢測獲得,所以不能直接使用self.foods[0].count。 */ return [self.foods[component] count]; } #pragma mark - 代理方法 - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { return self.foods[component][row]; } - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { if (component == 0) { self.fruitLab.text = self.foods[component][row]; } else if(component == 1) { self.foodLab.text = self.foods[component][row]; } else { self.drinkLab.text = self.foods[component][row]; } } /** * 隨機點餐 */ - (IBAction)selectAnyFood { for (int i = 0; i<self.foods.count; i++) { // 取出被選中的行 int row =(int)[self.pickView selectedRowInComponent:i]; int random; do { random = arc4random() % [self.foods[i] count]; } while (row == random); [self.pickView selectRow:random inComponent:i animated:YES]; [self pickerView:nil didSelectRow:random inComponent:i]; } } @end
效果:
五:國旗展現代碼:
數據模型
#import <Foundation/Foundation.h> @interface LLFlag : NSObject @property (nonatomic, copy) NSString *name; @property (nonatomic, copy) NSString *icon; - (instancetype)initWithDic:(NSDictionary *)dic; + (instancetype)flagWithDic:(NSDictionary *)dic; + (NSArray *)flagsList; @end
#import "LLFlag.h" @implementation LLFlag - (instancetype)initWithDic:(NSDictionary *)dic { if (self = [super init]) { [self setValuesForKeysWithDictionary:dic]; } return self; } + (instancetype)flagWithDic:(NSDictionary *)dic { return [[self alloc] initWithDic:dic]; } + (NSArray *)flagsList { NSString *path = [[NSBundle mainBundle] pathForResource:@"flags" ofType:@"plist"]; NSArray *dicArr = [NSArray arrayWithContentsOfFile:path]; NSMutableArray *tmpArr = [[NSMutableArray alloc] initWithCapacity:dicArr.count]; for (NSDictionary *dic in dicArr) { LLFlag *flag = [LLFlag flagWithDic:dic]; [tmpArr addObject:flag]; } return tmpArr; } @end
xib加載view
#import <UIKit/UIKit.h> @class LLFlag; @interface LLFlagView : UIView @property (nonatomic, strong) LLFlag *flag; + (instancetype)flagView; @end
#import "LLFlagView.h" #import "LLFlag.h" @interface LLFlagView () @property (weak, nonatomic) IBOutlet UILabel *nameLabel; @property (weak, nonatomic) IBOutlet UIImageView *iconView; @end @implementation LLFlagView + (instancetype)flagView { LLFlagView *view = [[[NSBundle mainBundle] loadNibNamed:@"LLFlagView" owner:nil options:nil] lastObject]; return view; } - (void)setFlag:(LLFlag *)flag { _flag = flag; self.nameLabel.text = flag.name; self.iconView.image = [UIImage imageNamed:flag.icon]; } @end
controller
#import "ViewController.h" #import "LLFlag.h" #import "LLFlagView.h" @interface ViewController ()<UIPickerViewDataSource, UIPickerViewDelegate> @property (nonatomic, strong) NSArray *flags; @property (weak, nonatomic) IBOutlet UIPickerView *pickView; @end @implementation ViewController #pragma mark - 懶加載 - (NSArray *)flags { if (!_flags) { _flags = [LLFlag flagsList]; } return _flags; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. } #pragma mark - 數據源方法 - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { return 1; } - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { return self.flags.count; } - (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view { LLFlagView *flagView = [LLFlagView flagView]; flagView.flag = self.flags[row]; return flagView; } - (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component { return 50; } @end
效果:
六:補充:
在代碼實現中爲何使用 [self.foods[0] count]; 而不是直接使用點語法self.foods[0].count取值。
[self.foods objectAtIndex:0]; == self.foods[0];//這兩句的效果等價,而self調用objectAtIndex:0這個方法,返回的是一個id類型的萬能指針,它的真實類型要到實際運行的時候才能檢測獲得,所以不能直接使用self.foods[0].count。