這就是我參考別人的文章寫的第一個(gè)demo森缠。通過(guò)這個(gè)簡(jiǎn)單的demo祝闻,我學(xué)會(huì)了:
1: 鞏固了OC的語(yǔ)法游昼,比如上篇文章寫的copy屬性修飾符甘苍、#pragma mark的使用、私有成員等烘豌。
2:使用簡(jiǎn)單的UIKit方法载庭,主要是UITableview。
3:MVC設(shè)計(jì)模式的實(shí)際應(yīng)用廊佩。
4: iOS程序的啟動(dòng)順序囚聚。
接下來(lái)就結(jié)合Demo分別總結(jié)一下上述幾個(gè)方面,其中OC的語(yǔ)法就跳過(guò)标锄。
UITableView的使用方法
- 創(chuàng)建
[[UITableView alloc] initWithFrame:(CGRect)frame style:(UITableViewStyle)style];
其中frame 就是tableview的邊框顽铸, UITableViewStyle是風(fēng)格,是一個(gè)常量:
typedef enum {
UITableViewStylePlain, //純列表模式
UITableViewStyleGrouped //分組模式
} UITableViewStyle;
- 使用
根據(jù)MVC設(shè)計(jì)原則料皇,View使用之前要先指定數(shù)據(jù)源(DataSource)和委托(Delegate)谓松。一般就是委托為ViewController。
_tableView.dataSource = self;
_tableView.delegate = self;
因此践剂,就要在ViewController里實(shí)現(xiàn)UITableViewDataSource和
UITableViewDelegate協(xié)議毒返。
其中, 數(shù)據(jù)源協(xié)議的方法主要是
-(NSInteger)numberOfSectionsInTableView: //返回分組數(shù)
-(NSInteger)tableView:numberOfRowsInSection: //返回每組的行數(shù)
-(UITableViewCell*)tableView:cellForRowAtIndexPath://返回每行的單元格
-(NSString*)tableView:titleForHeaderInSection://返回每組頭標(biāo)題名稱
-(NSString*)tableView:titleForFooterInSection://返回每組尾標(biāo)題名稱
-(NSArray*)sectionIndexTitlesForTableView://返回每組標(biāo)索引
這些方法都是View委托實(shí)現(xiàn)的舷手,操作的實(shí)體就是數(shù)據(jù)源拧簸,由此達(dá)到了View與Model通過(guò)Controller通信。
代理協(xié)議的方法主要是:
-(CGFloat)tableView:heightForHeaderInSection://設(shè)置分組標(biāo)題內(nèi)容高度
-(CGFloat)tableView:heightForFooterInSection://設(shè)置尾部說(shuō)明內(nèi)容高度
-(CGFloat)tableView:heightForRowAtIndexPath://設(shè)置每行高度
-(void)tableView:didSelectRowAtIndexPath://點(diǎn)擊某一行行為
使用UITableViewCell的一個(gè)細(xì)節(jié)需要注意男窟,也是性能的一個(gè)優(yōu)化盆赤。
UITableView中的單元格cell是在顯示到用戶可視區(qū)域后創(chuàng)建的,那么如果用戶往下滾動(dòng)就會(huì)繼續(xù)創(chuàng)建顯示在屏幕上的單元格歉眷,如果用戶向上滾動(dòng)返回到查看過(guò)的內(nèi)容時(shí)同樣會(huì)重新創(chuàng)建之前已經(jīng)創(chuàng)建過(guò)的單元格牺六。如此一來(lái)就重復(fù)創(chuàng)建了很多cell,導(dǎo)致內(nèi)存浪費(fèi)汗捡。
在UITableView內(nèi)部有一個(gè)緩存池淑际,初始化時(shí)使用initWithStyle:(UITableViewCellStyle) reuseIdentifier:(NSString *)方法指定一個(gè)可重用標(biāo)識(shí)畏纲,就可以將這個(gè)cell放到緩存池。然后在使用時(shí)使用指定的標(biāo)識(shí)去緩存池中取得對(duì)應(yīng)的cell然后修改cell內(nèi)容即可春缕,不同類型的cell可以指定不同的標(biāo)示符盗胀。
//由于此方法調(diào)用十分頻繁,cell的標(biāo)示聲明成靜態(tài)變量有利于性能優(yōu)化
static NSString *cellIdentifier=@"UITableViewCellIdentifierKey1";
//首先根據(jù)標(biāo)識(shí)去緩存池取
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
//如果緩存池沒(méi)有到則重新創(chuàng)建并放到緩存池中
if(!cell) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];
}
- -(UITableViewCell *)tableView:cellForRowAtIndexPath:方法調(diào)用很頻繁锄贼,無(wú)論是初始化票灰、上下滾動(dòng)、刷新都會(huì)調(diào)用此方法宅荤,所有在這里執(zhí)行的操作一定要注意性能屑迂;
- 可重用標(biāo)識(shí)可以有多個(gè),如果在UITableView中有多類結(jié)構(gòu)不同的Cell冯键,可以通過(guò)這個(gè)標(biāo)識(shí)進(jìn)行緩存和重新惹盼;
MVC設(shè)計(jì)模式的實(shí)際使用
如圖所示:
- Model和View永遠(yuǎn)不能相互通信,只能通過(guò)Controller傳遞惫确。
- Controller可以直接與Model對(duì)話(讀寫調(diào)用Model)逻锐,Model通過(guò)
Notification和KVO機(jī)制與Controller間接通信。 - Controller可以直接與View對(duì)話(通過(guò)outlet,直接操作View,outlet直接對(duì)應(yīng)到View中的控件),View通過(guò) action向Controller報(bào)告事件的發(fā)生(如用戶Touch我了)雕薪。Controller是View的直接數(shù)據(jù)源(數(shù)據(jù)很可能是 Controller從Model中取得的)昧诱。Controller是View的代理(delegate),以同步View與Controller。
關(guān)于MVC的理論就不說(shuō)了所袁,google一大堆盏档。在本Demo中,Model就是聯(lián)系人信息Contact和分組信息ContactGroup,它們定義了數(shù)據(jù)的格式燥爷,一般還可以定義讀寫的接口蜈亩;View就是UIWindow、UITableView和UIToolBar前翎,主要說(shuō)UITableView稚配,它定義了在界面上繪制那些視圖元素,怎么繪制港华,在哪繪制道川,并不知道這些視圖上顯示什么數(shù)據(jù);Controller主要就是MyViewController,這個(gè)是自定義的立宜,它維護(hù)了視圖tableView冒萄,也維護(hù)了數(shù)據(jù)contacts,當(dāng)然它要實(shí)現(xiàn)對(duì)應(yīng)的數(shù)據(jù)源和委托協(xié)議橙数。
iOS啟動(dòng)過(guò)程
在本Demo中尊流,具體的執(zhí)行順序是:
1.main.m中的UIApplicationMain, 設(shè)置整個(gè)app的委托為AppDelegate,開(kāi)始監(jiān)聽(tīng)事件循環(huán)灯帮。
2.AppDelegate.m中的didFinishLaunchingWithOptions:方法崖技,在這里面創(chuàng)建UIWindow并設(shè)置它的rootViewController為MyViewController,那UIWindow的事件就委托給MyViewController了逻住。
3.MyViewController.m中的viewDidLoad方法,在這里開(kāi)始初始化數(shù)據(jù)以及添加子視圖迎献。
這樣瞎访,視圖就可以顯示了,在視圖的操作都會(huì)傳遞到MyViewController中的對(duì)應(yīng)方法中去忿晕,這些方法可能更新Model中的數(shù)據(jù)装诡,然后刷新視圖银受,展示更新践盼。
接下來(lái)可以在此基礎(chǔ)上增加導(dǎo)航欄,也學(xué)會(huì)數(shù)據(jù)存取的幾種方法宾巍。