UI進階第五發:使用picker View控件完成一個簡單的選餐應用

一、實現效果

  說明:點擊隨機按鈕,能夠自動選取,下方數據自動刷新。

  

二、實現思路

1.picker view的有默認高度爲162,不可修改。
2.顯示數據,需要設置數據源,也有兩種方式(成爲數據源,遵守協議)
3.實現數據源裏面的兩個方法
1)返回一共有多少列
2)在這一列中一共有多少行
4.通過代理告訴它那一列的哪一行顯示哪些數據(設置其代理爲控制器)
5.使用懶加載,加載所有的食物
6.完成基本數據的展示(列,行,內容)
7.自動更新選中的食物信息。(使用一個大的view,上面放6個label)
1)給3個lab賦值,添加三個屬性(水果,主菜,飲料)
2)監聽選中了哪一行(監聽有兩種思想,一個是代理,一個是通知),先查看有沒有代理的方法(didselectRow)這個方法當選中了某一行的的時候調用,會將選中的列號和行號當做參數傳入進去。能夠獲取到對應的列號和行號。
3)完成選中時調用的監聽方法
4)在viewdidload裏面設置默認選中的內容,設置爲[0][1]
5)提高可擴展性(手動的調用那幾行-使用一個for循環)
8.隨機功能的實現
1)怎麼讓代碼選中某一行(selectrow),調用該方法可以指定讓它滾動到那一列的哪一行
2)實現頭部的功能(使用一個大的uiview,裏面放兩個子控件)
3)設置高度44,怎麼讓隨機按鈕的位置居中?可以設置它的高度爲44,最大的Y值爲64。
4)設置隨機按鈕的點擊事件randomFood,讓pickerview主動選中某一行。
5)生成隨機數的方法(生成隨機數的限制,不超過當前的總數)
6)缺點,將來數據改變之後,會報錯(模於幾)[self.foods[0] count]?爲什麼不用簡寫 點語法?(切記要記住)
7)隨機數的處理不嚴謹,有的時候生成的隨機數可能是相等的,那麼這樣的話列就不會滾動,獲取到對應列的數據總數,如何拿到上一次產生的隨機值(也就是當前選中的行),比較上一次的行號和當前生成的隨機數是否相同,如果相同則重寫生成
9.解決另外一個問題,下面的數據隨機刷新失效了,通過代碼選中某一行。
 
三、實現代碼示例
1.項目文檔結構和storyboard文件
storyboard文件大的界面設置:
2.代碼示例
主控制器文件代碼:
複製代碼
  1 //
  2 //  YYViewController.m
  3 //  06-簡單選菜系統的實現
  4 //
  5 //  Created by apple on 14-6-5.
  6 //  Copyright (c) 2014年 itcase. All rights reserved.
  7 //
  8 
  9 #import "YYViewController.h"
 10 
 11 //遵守數據源和代理協議
 12 @interface YYViewController ()<UIPickerViewDataSource,UIPickerViewDelegate>
 13 /**
 14  *  水果
 15  */
 16 @property (strong, nonatomic) IBOutlet UILabel *fruitLab;
 17 /**
 18  *  主菜
 19  */
 20 @property (strong, nonatomic) IBOutlet UILabel *stapleLab;
 21 /**
 22  *  飲料
 23  */
 24 @property (strong, nonatomic) IBOutlet UILabel *drinkLab;
 25 /**
 26  *  保存所有的數據
 27  */
 28 @property(nonatomic,strong)NSArray *foods;
 29 @property (weak, nonatomic) IBOutlet UIPickerView *pickerView;
 30 - (IBAction)randomFood:(id)sender;
 31 
 32 @end
 33 
 34 @implementation YYViewController
 35 
 36 - (void)viewDidLoad
 37 {
 38     [super viewDidLoad];
 39     
 40     //在這裏設置下方數據刷新部分的初始顯示
 41     for (int component = 0; component<self.foods.count; component++) {
 42         [self pickerView:nil didSelectRow:0 inComponent:component];
 43     }
 44 }
 45 
 46 #pragma mark-使用懶加載,把數據信息加載進來
 47 -(NSArray *)foods
 48 {
 49     if (_foods==nil) {
 50         NSString *fullpath=[[NSBundle mainBundle]pathForResource:@"foods.plist" ofType:nil];
 51         NSArray *arrayM=[NSArray arrayWithContentsOfFile:fullpath];
 52         _foods=arrayM;
 53     }
 54     return _foods;
 55 }
 56 
 57 #pragma mark-處理隨機按鈕的點擊事件
 58 - (IBAction)randomFood:(id)sender {
 59     
 60     // 讓pickerView主動選中某一行
 61     // 讓pickerView選中inComponent列的Row行
 62     //    [self.pickerView selectRow:1 inComponent:0 animated:YES];
 63     
 64     /*
 65      [self.pickerView selectRow: arc4random() % 12 inComponent:0 animated:YES];
 66      [self.pickerView selectRow: arc4random() % 15 inComponent:1 animated:YES];
 67      [self.pickerView selectRow: arc4random() % 10 inComponent:2 animated:YES];
 68      */
 69     
 70     //    [self.foods objectAtIndex:0]; == self.foods[0];
 71     //    [self.foods[0] count];
 72     
 73     /*
 74      // 根據每一列的元素個數生成隨機值
 75      [self.pickerView selectRow: arc4random() % [self.foods[0] count] inComponent:0 animated:YES];
 76      [self.pickerView selectRow: arc4random() % [self.foods[1] count] inComponent:1 animated:YES];
 77      [self.pickerView selectRow: arc4random() % [self.foods[2] count] inComponent:2 animated:YES];
 78      */
 79     
 80     //設置一個隨機數
 81     for (int component=0; component<self.foods.count; component++) {
 82         //獲取當前列對應的數據元素的個數
 83         int total=[self.foods[component] count];
 84         //根據每一列的總數生成隨機數(當前生成的隨機數)
 85         int randomNumber=arc4random()%total;
 86         
 87         //獲取當前選中的行(上一次隨機後移動到的行)
 88         int oldRow=[self.pickerView selectedRowInComponent:0];
 89         
 90         //比較上一次的行號和當前生成的隨機數是否相同,如果相同的話則重新生成
 91         while (oldRow==randomNumber) {
 92                 randomNumber=arc4random()%total;
 93         }
 94         
 95         //讓pickerview滾動到指定的某一行
 96         [self.pickerView selectRow:randomNumber inComponent:component animated:YES];
 97         //模擬,通過代碼選中某一行
 98         [self pickerView:nil didSelectRow:randomNumber inComponent:component];
 99     }
100 }
101 
102 #pragma mark- 設置數據
103 //一共多少列
104 -(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
105 {
106     return self.foods.count;
107 }
108 
109 //每列對應多少行
110 -(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
111 {
112     //1.獲取當前的列
113     NSArray *arayM= self.foods[component];
114     //2.返回當前列對應的行數
115     return arayM.count;
116 }
117 
118 //每列每行對應顯示的數據是什麼
119 -(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
120 {
121     //1.獲取當前的列
122     NSArray *arayM= self.foods[component];
123     //2.獲取當前列對應的行的數據
124     NSString *name=arayM[row];
125     return name;
126 }
127 
128 #pragma mark-設置下方的數據刷新
129 // 當選中了pickerView的某一行的時候調用
130 // 會將選中的列號和行號作爲參數傳入
131 // 只有通過手指選中某一行的時候纔會調用
132 -(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
133 {
134     //獲取對應列,對應行的數據
135     NSString *name=self.foods[component][row];
136     //賦值
137     if (0==component) {
138         self.fruitLab.text=name;
139     }else if(1==component)
140     {
141         self.stapleLab.text=name;
142     }else
143         self.drinkLab.text=name;
144 }
145 
146 #pragma mark-隱藏狀態欄
147 -(BOOL)prefersStatusBarHidden
148 {
149     return YES;
150 }
151 @end
複製代碼

四、重要補充

請注意在代碼實現中爲什麼使用 [self.foods[0] count]; 而不是直接使用點語法self.foods[0].count取值。     

[self.foods objectAtIndex:0]; == self.foods[0];//這兩句的效果等價,而self調用objectAtIndex:0這個方法,返回的是一個id類型的萬能指針,它的真實類型要到實際運行的時候才能檢測得到,因此不能直接使用self.foods[0].count。

  

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