UIPickView

目錄

  • UIPickerView的使用(兩個案例)

一、UIPickerView的使用

案例1:點菜系統

這裏寫圖片描述

目標:
》使用UIPikcerView控件實現點菜系統
》掌握UIPikcerView的代理與數據源與代理方法的使用,與TableView類比
(1)UITableView的每一行Cell是在數據源裏,而UIPikcerView的每一行View是在代理裏

(2)UIPickerView每一行長什麼樣有兩個方法

//-(NSString *)pickerView: titleForRow: forComponent:直接返回一個字符串
//-(UIView *)pickerView: viewForRow: forComponent: reusingView:直接返回一個view
#pragma mark - UIPickerViewDelegate methods
//數據部分的展示是交給代理來做
- (nullable NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;


》監聽每組選中的行,更改Label數據
(1)使用代理方法(數據源改變但是pickview沒有變化)
- (void)pickerView:didSelectRow:inComponent:

2)更改UIPickView選中的數據(讓pickview跟隨數據的改而改變)
        [self.pickerView selectRow:randRow inComponent:i animated:YES];




》實現默認選中每一組的第一行數據
(1)在viewDidLoad方法調用【-(void)pickerView:didSelectRow:inComponent:】實現

》實現隨機選菜單
(1)實現Label數據的隨機變更
(2)實現pickerView的數據隨機變更
(3)每一組對應行的數據一定要不同上一次的行數據
/**
*獲取舊行與新行,使用while循環,

    //舊行
    NSInteger oldRow = [self.pickerView selectedRowInComponent:i];
    //隨機新行
    NSInteger newRow = arc4random_uniform((int)rows);
    //新行與舊行相同,再隨機,直到不兩隻
    while (newRow == oldRow) {
        newRow = arc4random_uniform((int)rows);
    }
*/



eg:
#pragma makr - 隨機產生結果
- (IBAction)randNumber:(id)sender {
    //1.獲取列數
    NSInteger colum = self.dataArray.count;

    for (int i = 0; i < colum; i ++) {
    //2.獲取隨機每列的隨機行數
    NSArray *items = self.dataArray[i];
    unsigned int rowCount = (unsigned int)items.count;

    unsigned int randRow = arc4random_uniform(rowCount);//arc4random_uniform指定範圍,如果填arc4random_uniform(10),獲取的數是0-9

        //每列的隨機行數不能與之前一樣
        // 獲取舊的行數
        NSInteger oldRow = [self.pickerView selectedRowInComponent:i];
        while (oldRow == randRow) {
            randRow = arc4random_uniform(rowCount);
        }

        // 0.0~0.9
        //arc4random_uniform(10) * 0.1

        // 0.00~0.99
        //arc4random_uniform(100) * 0.01

    //3.更改數據(數據源改變但是pickview沒有變化)
        [self pickerView:nil didSelectRow:randRow inComponent:i];
        //更改UIPickView選中的數據
        [self.pickerView selectRow:randRow inComponent:i animated:YES];

    }
}

案例2.國旗選擇

》掌握代理【-(UIView *)pickerView:viewForRow:forComponent:reusingView:】的使用

這裏寫圖片描述

(1)在數據源裏返回一組數據,行數由國旗個數決定
(2)在代理方法中使用上面的方法,每一行返回一個View,返回的這個view爲label
(3)打印reusingView的地址和文字,”查看循環利用的view” –’備課的時候多演示幾次’
//eg: NSLog(@”==%p %@”,label,label.text);
(4)使用一個xib描述國家和國旗
(5)掌握一個設置行高的代理方法

#pragma mark - 自定義pickerView行
//循環引用在ios7以後,不帶明顯,但是確實還是會循環引用
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{

    //如果有重用的View,會傳一個view進來,重用

    FlagView *flagView = (FlagView *)view;
    if (!flagView) {
        flagView = [FlagView flageView];
    }

#warning 一般設置自定義的view大小時,不直接設置bounds/frame
    //自定義控件要添加bounds
    flagView.bounds = CGRectMake(0, 0, 200, 0);

    //設置數據
    flagView.modelData = self.array[row];


    //打印view的內存地址
    NSLog(@"row = %ld,address: %p, name = %@",row, flagView,((FlagModel *)self.array[row]).name );

    return flagView;
}
//設置高度無效,需要用代理設置高度

- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component{

    return 50;
}

//設置寬度
//- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component{
//    return 200;
//}


#import "FlagModel.h"

@interface FlagView : UIView


+ (instancetype)flageView;
@property (nonatomic, strong) FlagModel *modelData;

@end
#import "FlagView.h"

@interface FlagView ()
@property (weak, nonatomic) IBOutlet UILabel *label;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;

@end



@implementation FlagView

+ (instancetype)flageView{
    //需要lastobject因爲,xib中可以拖動多個視圖,而且是同級的。
   return  [[[NSBundle mainBundle] loadNibNamed:@"FlagView" owner:nil options:nil] lastObject];
}

- (void)setModelData:(FlagModel *)modelData{

    _modelData = modelData;
    self.label.text = modelData.name;
    self.imageView.image = [UIImage imageNamed:modelData.icon];
}

案例3.省市聯動

這裏寫圖片描述

@property (nonatomic,assign)NSInteger indexOfProvice;//當前默認選中的省份


ViewController.m

// returns the number of 'columns' to display.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
    return 2;
}
// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
    //第一列省份
    if (component == 0) {//省分
        return self.provinces.count;
    }


    //第二列:獲取對應省份的城市個數
    Province *province = self.provinces[self.indexOfProvice];

    return province.cities.count;

}
#pragma mark 顯示數據
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{



    if(component == 0){//顯示省份的名字
        //對應列行的省份
        Province *province = self.provinces[row];
        return province.name;
    }

    //獲取選中的城市,顯示城市名字
    Province *selectedProvice = self.provinces[self.indexOfProvice];
    return selectedProvice.cities[row];
}

//方法二


//-(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{
//    
//    UILabel *label = (UILabel *)view;
//    if (!label) {
//        label = [[UILabel alloc] init];
//    }
//    
//    if(component == 0){//顯示省份的名字
//        //對應列行的省份
//        Province *province = self.provinces[row];
//        label.text =  province.name;
//        label.backgroundColor = [UIColor grayColor];
//    }else{
//        
//        //獲取選中的城市,顯示城市名字
//        Province *selectedProvice = self.provinces[self.indexOfProvice];
//        label.text = selectedProvice.cities[row];
//        label.backgroundColor = [UIColor blueColor];
//    }
//    
//    
//    
//    
//    return label;
//}
#pragma mark 選中行

-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{

    if (component == 0) {//第一列省的選中改變後,就要更新第二列數據
        //更新選中省份的索引
        self.indexOfProvice = row;

        //刷新數據
        //全部刷新
        //[pickerView reloadAllComponents];

        //部份刷新
        [pickerView reloadComponent:1];

        //不管之前第二列選中第幾行,重新刷新數據後,都顯示每二列的第一行
        [pickerView selectRow:0 inComponent:1 animated:YES];
    }
}

#pragma mark 設置寬度
-(CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component{
    if (component == 0) {
        return 80;
    }

    return 200;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章