UI進階之UIPickerView---點餐系統

一:數據源方法緩存

/** 數據源協議,全部方法都必須實現 */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。

相關文章
相關標籤/搜索