IOS 開發筆記-基礎 UI(6)照片瀏覽器(控制項的懶載入和使用Plist檔案將資料與代碼分離),iosplist
使用UIImageView、UILabel、UIButton實現一個綜合小案例
功能分析
(1)點擊箭頭切換序號、圖片、描述(2)如果是首張圖片,左邊箭頭不能點擊(3)如果是尾張圖片,右邊箭頭不能點擊
步驟分析
(1)搭建UI介面(2)監聽按鈕點擊
切換序號、圖片、描述
1. 介面分析
1> 需要讀取或修改的屬性的控制項
// 序號標籤
// 圖片
// 圖片描述
// 左邊按鈕
// 右邊按鈕
2> 需要監聽響應事件的對象,需要添加監聽方法
// 左邊按鈕
// 右邊按鈕
uiimage 是圖片,不是控制項,他的父類為NSObject,UIImageView是載入圖片的控制項,父類為UIView
完全的代碼編寫介面(複習回憶)
#import "ViewController.h"@interface ViewController ()//序號標籤@property (nonatomic, strong) UILabel *noLabel;//圖片@property (nonatomic, strong) UIImageView *icon;//圖片描述@property (nonatomic, strong) UILabel *descLabel;//左邊按鈕@property (nonatomic, strong) UIButton *leftButton;//右邊按鈕@property (nonatomic, strong) UIButton *rightButton;@end@implementation ViewController//初始化工作//viewDidLoad是視圖載入完成後調用的方法,通常在此方法中執行視圖控制器的初始化工作- (void)viewDidLoad { [super viewDidLoad]; //執行個體化控制項 //1、序號標籤的編寫 UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, 320, 40)]; label.text = @"1/5"; //置中對齊 label.textAlignment = NSTextAlignmentCenter; [self.view addSubview:label]; //記錄改變 self.noLabel = label; //2、圖片控制項 CGFloat imageW = 200; CGFloat imageH = 200; CGFloat imageX = (320 - imageW) / 2; CGFloat imageY = 80; //執行個體化一個映像視圖 UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(imageX, imageY, imageW, imageH)]; //執行個體化一個映像 UIImage *image = [UIImage imageNamed:@"biaoqingdi"]; //把圖片顯示到imageView imageView.image = image; [self.view addSubview:imageView]; //記錄下改變 self.icon = imageView; //3、圖片描述 label 控制項 UILabel *label1 = [[UILabel alloc] initWithFrame:CGRectMake(0, 300, 300, 80)]; label1.text = @"發發發"; //置中對齊 label1.textAlignment = NSTextAlignmentCenter; [self.view addSubview:label1]; //記錄改變 self.descLabel = label1; //4、左邊的按鈕 UIButton *leftBtn = [[UIButton alloc] init]; //設定按鈕的背景圖 [leftBtn setBackgroundImage:[UIImage imageNamed:@"left_normal"] forState:UIControlStateNormal]; [leftBtn setBackgroundImage:[UIImage imageNamed:@"left_highlighted"] forState:UIControlStateHighlighted]; //設定按鈕的大小 leftBtn.frame = CGRectMake(0, 0, 40, 40); //設定按鈕的位置 leftBtn.center = CGPointMake(self.icon.frame.origin.x / 2, self.icon.center.y); [self.view addSubview:leftBtn]; self.leftButton = leftBtn; //5、右邊的按鈕 UIButton *rightBtn = [[UIButton alloc] init]; //設定按鈕的背景圖 [rightBtn setBackgroundImage:[UIImage imageNamed:@"right_normal"] forState:UIControlStateNormal]; [rightBtn setBackgroundImage:[UIImage imageNamed:@"right_highlighted"] forState:UIControlStateHighlighted]; //設定按鈕的大小 rightBtn.frame = CGRectMake(0, 0, 40, 40); //設定按鈕的位置 rightBtn.center = CGPointMake(self.view.frame.size.width - self.icon.frame.origin.x / 2, self.icon.center.y); [self.view addSubview:rightBtn]; self.leftButton = rightBtn;}@end
完整的代碼如下:
#import "ViewController.h"@interface ViewController ()//序號標籤@property (nonatomic, strong) UILabel *noLabel;//圖片@property (nonatomic, strong) UIImageView *icon;//圖片描述@property (nonatomic, strong) UILabel *descLabel;//左邊按鈕@property (nonatomic, strong) UIButton *leftButton;//右邊按鈕@property (nonatomic, strong) UIButton *rightButton;//圖片索引,index預設是0@property (nonatomic, assign) int index;/**設定一個映像的數組*///新的注釋,可以顯式中文@property (nonatomic, strong) NSArray *imageList;/* @property 自動為我們產生 set,get 方法的聲明和實現 帶底線的成員變數 */@end@implementation ViewController//控制項懶載入//不需要每次都在 viewdidload 裡執行個體化數組,只要在需要的時候執行個體化即可//重寫 get 方法- (NSArray *)imageList{ //只有第一次調用imageList 的 getter 方法的時候,如果為空白,那麼再執行個體化並建立數組,其他時候,直接返回成員變數 if (_imageList == nil) { //使用字典 NSDictionary *dict1 = @{@"name" : @"biaoqingdi", @"desc" : @"表情"}; NSDictionary *dict2 = @{@"name" : @"bingli", @"desc" : @"病曆"}; NSDictionary *dict3 = @{@"name" : @"chiniupa", @"desc" : @"吃牛扒"}; NSDictionary *dict4 = @{@"name" : @"danteng", @"desc" : @"蛋疼"}; NSDictionary *dict5 = @{@"name" : @"wangba", @"desc" : @"王八"}; self.imageList = @[dict1, dict2, dict3, dict4, dict5]; } return _imageList;}//初始化工作//viewDidLoad是視圖載入完成後調用的方法,通常在此方法中執行視圖控制器的初始化工作- (void)viewDidLoad { [super viewDidLoad]; //執行個體化控制項 //1、序號標籤的編寫 UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, 320, 40)]; // label.text = @"1/5"; //置中對齊 label.textAlignment = NSTextAlignmentCenter; [self.view addSubview:label]; //記錄改變 self.noLabel = label; //2、圖片控制項 CGFloat imageW = 200; CGFloat imageH = 200; CGFloat imageX = (320 - imageW) / 2; CGFloat imageY = 80; //執行個體化一個映像視圖 UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(imageX, imageY, imageW, imageH)]; //執行個體化一個映像 // UIImage *image = [UIImage imageNamed:@"biaoqingdi"]; //把圖片顯示到imageView // imageView.image = image; //把映像增加到 view [self.view addSubview:imageView]; //記錄下改變 self.icon = imageView; //3、圖片描述 label 控制項 UILabel *label1 = [[UILabel alloc] initWithFrame:CGRectMake(0, 300, 300, 80)]; // label1.text = @"發發發"; //置中對齊 label1.textAlignment = NSTextAlignmentCenter; [self.view addSubview:label1]; //記錄改變 self.descLabel = label1; //4、左邊的按鈕 UIButton *leftBtn = [[UIButton alloc] init]; //設定按鈕的背景圖 [leftBtn setBackgroundImage:[UIImage imageNamed:@"left_normal"] forState:UIControlStateNormal]; [leftBtn setBackgroundImage:[UIImage imageNamed:@"left_highlighted"] forState:UIControlStateHighlighted]; //設定按鈕的大小 leftBtn.frame = CGRectMake(0, 0, 40, 40); //設定按鈕的位置 leftBtn.center = CGPointMake(self.icon.frame.origin.x / 2, self.icon.center.y); [self.view addSubview:leftBtn]; //設定監聽 [leftBtn addTarget:self action:@selector(leftClick) forControlEvents:UIControlEventTouchUpInside]; self.leftButton = leftBtn; //5、右邊的按鈕 UIButton *rightBtn = [[UIButton alloc] init]; //設定按鈕的背景圖 [rightBtn setBackgroundImage:[UIImage imageNamed:@"right_normal"] forState:UIControlStateNormal]; [rightBtn setBackgroundImage:[UIImage imageNamed:@"right_highlighted"] forState:UIControlStateHighlighted]; //設定按鈕的大小 rightBtn.frame = CGRectMake(0, 0, 40, 40); //設定按鈕的位置 rightBtn.center = CGPointMake(self.view.frame.size.width - self.icon.frame.origin.x / 2, self.icon.center.y); [self.view addSubview:rightBtn]; //設定監聽 [rightBtn addTarget:self action:@selector(rightClick) forControlEvents:UIControlEventTouchUpInside]; self.rightButton = rightBtn; [self change];}- (void)change{ //更具 self.index 來顯示序號標籤,圖形,,描述 self.noLabel.text = [NSString stringWithFormat:@"%d / %d", self.index + 1, 5]; self.icon.image = [UIImage imageNamed:self.imageList[self.index][@"name"]]; self.descLabel.text = self.imageList[self.index][@"desc"]; self.leftButton.enabled = (self.index != 0); self.rightButton.enabled = (self.index != 4);}//left- (void)leftClick{ self.index--; [self change];}//right- (void)rightClick{ self.index++; [self change];}@end
小結:
/**設定一個映像的數組*/
這是 xcode 的新的注釋,滑鼠浮動時,可以顯式出中文注釋。
手碼懶載入建立控制項的步驟
1> 定義控制項屬性,注意:屬性必須是strong的,如下:
@property (nonatomic, strong) UIImageView *icon;
2> 在屬性的getter方法中實現懶載入。
使用懶載入的好處:
1> 不必將建立對象的代碼全部寫在viewDidLoad方法中,代碼的可讀性更強
2> 每個控制項的getter方法中分別負責各自的執行個體化處理,代碼彼此之間的獨立性強,松耦合
按鈕的狀態
normal(普通狀態)預設情況對應的枚舉常量:UIControlStateNormal highlighted(高亮狀態)按鈕被按下去的時候(手指還未鬆開)對應的枚舉常量:UIControlStateHighlighted disabled(失效狀態,不可用狀態)如果enabled屬性為NO,就是處於disable狀態,代表按鈕不可以被點擊對應的枚舉常量:UIControlStateDisabled
使用Plist檔案重構本項目代碼:
目的:將資料與代碼分離(類似 java 裡的 xml 檔案寫資料,資料和代碼分離)
之前的代碼,尤其是字典那部分,還是處理的不好,顯得太耦合。需要把資料和代碼分離,這裡學習屬性列表檔案,property list
建立file
本地檔案,也可以網路上解析 xml 檔案
這樣,只需要修改對應的 xml 檔案即可,不用再開啟代碼,修改代碼
//控制項懶載入//不需要每次都在 viewdidload 裡執行個體化數組,只要在需要的時候執行個體化即可- (NSArray *)imageList{ //只有第一次調用imageList 的 getter 方法的時候,如果為空白,那麼再執行個體化並建立數組,其他時候,直接返回成員變數 if (_imageList == nil) { //bundle 包的概念 唯讀 NSString *path = [[NSBundle mainBundle] pathForResource:@"imageDate" ofType:@".plist"]; NSLog(@"%@", path); //File 表示從完整路徑尋找檔案 _imageList = [NSArray arrayWithContentsOfFile:path]; } return _imageList;}
小結:
1、將資料與代碼分離,Plist 檔案的載入方法:
直接將資料直接寫在代碼裡面,不是一種合理的做法。如果資料經常改,就要經常翻開對應的代碼進行修改,造成代碼擴充性低,因此,可以考慮將經常變的資料放在檔案中進行儲存,程式啟動後從檔案中讀取最新的資料。如果要變動資料,直接修改資料檔案即可,不用修改代碼。一般可以使用屬性列表檔案儲存體NSArray或者NSDictionary之類的資料,這種屬性列表檔案的副檔名是plist,因此也成為“Plist檔案”
NSString *path = [[NSBundle mainBundle] pathForResource:@"ImageData" ofType:@"plist"];
_imageList = [NSArray arrayWithContentsOfFile:path];
提示:通常在方法中出現File字眼,通常需要傳遞檔案的全路徑作為參數,如下全路徑:
/Users/dashuai/Library/Developer/CoreSimulator/Devices/83C611C9-DE98-4D02-BC64-D31C0403766E/data/Containers/Bundle/Application/E04713CF-A9D4-49D1-A934-B4093BCE5B3C/圖片瀏覽.app/imageDate.plist
2、要想讓UILabel自動換行,設定Lines為0即可。
3、UIButton和UIImageView
相同點都能顯示圖片 不同點UIButton預設情況就能監聽點擊事件,而UIImageView預設情況下不能UIButton可以在不同狀態下顯示不同的圖片UIButton既能顯示文字,又能顯示圖片 如何選擇UIButton:需要顯示圖片,點擊圖片後需要做一些特定的操作UIImageView:僅僅需要顯示圖片,點擊圖片後不需要做任何事情 NSArray和NSDictionary的使用當圖片內容非常多時,“根據index來設定內容”的代碼就不具備擴充性,要經常改動,為了改變現狀,可以考慮將圖片資料儲存到一個數組中,數組中有序地放著很多字典,一個字典代表一張圖片資料,包含了圖片名、圖片描述
@property (strong, nonatomic) NSArray *images;
由於只需要初始化一次圖片資料,因此放在get方法中初始化,將屬性放在get方法中初始化的方式,稱為“懶載入”\”消極式載入”
/**設定一個映像的數組*/
這是 xcode 的新的注釋,滑鼠浮動時,可以顯式出中文注釋。
手碼懶載入建立控制項的步驟
1> 定義控制項屬性,注意:屬性必須是strong的,如下:
@property (nonatomic, strong) UIImageView *icon;
2> 在屬性的getter方法中實現懶載入。
使用懶載入的好處:
1> 不必將建立對象的代碼全部寫在viewDidLoad方法中,代碼的可讀性更強
2> 每個控制項的getter方法中分別負責各自的執行個體化處理,代碼彼此之間的獨立性強,松耦合
按鈕的狀態
normal(普通狀態)預設情況對應的枚舉常量:UIControlStateNormal highlighted(高亮狀態)按鈕被按下去的時候(手指還未鬆開)對應的枚舉常量:UIControlStateHighlighted disabled(失效狀態,不可用狀態)如果enabled屬性為NO,就是處於disable狀態,代表按鈕不可以被點擊對應的枚舉常量:UIControlStateDisabled