首页 > 代码库 > UI进阶之UIPickerView---点餐系统

UI进阶之UIPickerView---点餐系统

一:数据源方法

/** 数据源协议,所有方法都必须实现 */

@protocol UIPickerViewDataSource<NSObject>

@required

 // 返回要显示的列数

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;

 // 返回component列中的数据行数

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;

@end

二:代理方法:

** 代理协议,所有方法都是可选的 */

@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。

UI进阶之UIPickerView---点餐系统