一、創(chuàng)建TableView
? TableView在iOS的開發(fā)中,是最為常用的UI控件,其實質(zhì)是一個列表。其包含了如下功能:
? 數(shù)據(jù)的收集由實現(xiàn)了<UITableViewDataSource>協(xié)議的類提供吉懊。
? 處理Action事件由實現(xiàn)了<UITableViewDelegate>協(xié)議的類提供。
1.1 從StoryBoard和屬性中認識TableView
先從StoryBoard中創(chuàng)建一個UITableView假勿,來來看它可變屬性分別代表著什么借嗽。
分別解釋一下每項的具體意思:
1、Content和Prototype Cells
Content選項是用于定義開發(fā)者創(chuàng)建的TableView是動態(tài)表格還是靜態(tài)表格转培。Dynamic Prototypes是動態(tài)恶导,Static Cells是靜態(tài)。Dynamic Prototypes是動態(tài)單元格的模版浸须。
2甲锡、Style
TableView有兩種Style,分別為Plain和Grouped羽戒。Plain意思是表格使用系統(tǒng)默認Style缤沦,也就是無分組的類型。Grouped則是分組類型易稠。
3缸废、Separator
是指Cells與Cells之間的分割線,其有Style屬性:Single Line(單線)驶社、Single Line Etched(被蝕刻的單線)企量、Default(系統(tǒng)默認)、Color屬性和Separator Inset屬性:控制分割線長度亡电。
4届巩、Selection
控制Cells被選中時的處理,有三個可選值份乒,分別為:NO Selection:不允許選中恕汇、Single Selection: 只允許單選、 Multiple Selection:允許多選或辖。
5瘾英、Editing
Editing是表示TableView處于可編輯狀態(tài),其下有三個值可供選擇颂暇,分別為:No Selection: During Editing:處于編輯狀態(tài)不允許選中缺谴、Single Selection During Editing:處于編輯狀態(tài)允許單選、Multiple Selection During Editing:處于編輯狀態(tài)時允許多選耳鸯。
tableView的屬性介紹:
self.tableView.style//只讀屬性湿蛔,用于返回該表格的樣式膀曾。
self.tableView.rowHeight//該屬性用語返回或設(shè)置表格的行高。
self.tableView.separatorStyle//該屬性用語返回或設(shè)置表格的分割條樣式
UITableViewCellSeparatorStyleNone//無分隔條
UITableViewCellSeparatorStyleSingleLine//單線分隔條
UItableViewCellSpearatorStyleSingleLineEtched//被蝕刻的單線分隔條
self.tableView.separatorColor//該屬性用語設(shè)置分隔條的顏色
self.tableView.backgroundView//該屬性用于返回或設(shè)置表格的背景控件
self.tableView.tableHeaderView//該屬性可設(shè)置或返回該表格的頁眉控件
self.tableView.tableFooterView//該屬性可設(shè)置或返回制定分區(qū)包含的行數(shù)
1.2TableView的DataSource
先來看看Table的結(jié)構(gòu)示意圖:
從這張圖中阳啥,我們可以知道UItableView直接管三個東西妓肢,分別是:UITableViewCell、UITableViewDataSource和UITableViewDelegate苫纤。
其中UITableViewCell是TableView主要視圖控件,其主要功能是提供Cell的各種設(shè)置和提供定制類型的Cell纲缓,如何定制Cell將在本文的下一節(jié)中探討卷拘。
UITableViewDataSource主要是為UITableView提供數(shù)據(jù)源,有了這些數(shù)據(jù)源祝高,UITableView才能顯示復(fù)合預(yù)期的內(nèi)容栗弟。
我跳到UITableViewDataSource協(xié)議的接口文件,來看一下工闺,DataSource可以為我們提供哪些內(nèi)容乍赫。在協(xié)議協(xié)議中,我們看到陆蟆,定義了一個NSIndexPath類雷厂,其主要作用是提供為開發(fā)者提供Cell的索引。
@interface NSIndexPath (UITableView)
+ (instancetype)indexPathForRow:(NSInteger)row inSection:(NSInteger)section;//類方法叠殷,作用是通過提供一個row和section屬性初始化一個NSIndexPath對象改鲫,可以用來表示某一個Cell。
@property (nonatomic, readonly) NSInteger section;//表明Cell處于哪個section段中林束,是只讀屬性
@property (nonatomic, readonly) NSInteger row;//表明在section段中的行數(shù)像棘,是只讀屬性
@end
再來看看其中的@required方法。
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;//這個方法的返回值確定TableView在一個Section中顯示多少個Cell壶冒。
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier: **翻譯:Row顯示缕题。開發(fā)者應(yīng)該總是通過設(shè)置每個Cell的reuseIdentifier和dequeueReusableCellwithIdentifier:方法,來重用細胞胖腾。這句話顯示了蘋果希望開發(fā)者自定義自己的Cell烟零。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;//這個方法將提供如何顯示Cell,返回的對象將會顯示在TableView上咸作。
再來看看老師在課堂上講的其它常用方法瓶摆。
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView//這個方法的返回的值確定在TableView中有幾個Section。*特別提醒性宏,如何沒有提供這個方法群井,程序?qū)詣臃祷?。
—(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath // Return NO if you do not want the specified item to be editable.//蘋果已經(jīng)為我們說明了這個方法的作用毫胜,如何返回NO的話specified item將無法被編輯书斜。
(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view//這段代碼意思是先判斷開發(fā)者提供的UITableViewCell是刪除按鈕還是增加按鈕诬辈,然后進入編輯模式,并且調(diào)用tableView自帶的刪除和增加方法荐吉。
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath//實現(xiàn)這個方法的目的是在刪除和增加了一個Cell后焙糟,Cell如何實現(xiàn)位置的移動。
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath?
// Return NO if you do not want the item to be re-orderable.//如果返回NO样屠,item將不會被重構(gòu)穿撮。
導航搜索條也是在DataSource中實現(xiàn)的,其實現(xiàn)的關(guān)鍵是提供三個方法:
-(NSArray*)sectionIndexTitlesForTableView:(UITableView *)tableView//他的返回值是一個數(shù)組痪欲,數(shù)組的每個元素悦穿,就是導航搜索條的每一項。
-(NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section//提供每個Header顯示的東西
-(NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index//提供通過導航搜索條條轉(zhuǎn)的方法
1.3 TableView的Delegate
UITableViewDelegate是為TableView提供Events的解決方法业踢,這個協(xié)議中所有的方法都是@optional栗柒。
其中有幾個比較關(guān)鍵的方法,需要寫下來:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[self performSegueWithIdentifier:@"PassValue" sender:indexPath];
}//這個方法主要是提供Cell的點擊事件知举,如果用戶點擊了Cell瞬沦,將返回這個方法中的代碼
使用Delegate的方法再配合Segue的方法,可以將不同Cell的值傳給下一個界面雇锡,這也是本次通訊錄作業(yè)中比較關(guān)鍵的代碼逛钻,下面就是如何實現(xiàn)Cell的傳值的代碼。是通過Segue的傳值锰提,和indexPath屬性來唯一確定一個Cell绣的,并且傳值給下一個。
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"PassValue"]) {
UITableView * tv=(UITableView* )sender;
ViewController * vc=(ViewController*)segue.destinationViewController;
vc.toName=self.NameData[[tv indexPathForSelectedRow].row];
vc.toNumber=self.NumberData[[tv indexPathForSelectedRow].row];
vc.row=[tv indexPathForSelectedRow].row;
}//這段代碼比較關(guān)鍵的地方是:vc.toName=self.NameData[[tv indexPathForSelectedRow].row]; 后面的 [indexPathForSelecteRow].row意思是返回選中Cell的row值欲账,我的工程是比較簡單的屡江,數(shù)組中的索引一一對應(yīng)TableView中Cell的row值,所以返回row當作數(shù)組的索引赛不,就能簡單的返回指定Cell中顯示的數(shù)據(jù)(Section是1惩嘉,如果不為1,那么返回的索引應(yīng)該是Section+row)
再來看看視屏中介紹的其它Delegate方法對應(yīng)的TableView的事件處理方法:
這是老師視頻中綜合介紹Delegate各項方法的合集踢故,很詳細文黎,在此不在敖述了。
1.4 定制Cell
? 如果只是使用系統(tǒng)提供的UITableViewCell殿较,UITableView控件的表格行只支持有限的樣式耸峭,而且每個表格行只包含textLabel、detailTextLabel淋纲、UIImageView 這三個控件劳闹。所以在開發(fā)實踐中DIY自己的Cell是普遍的做法。
由于對于xib不是很熟悉,在看完視頻后本涕,決定學會掌握前面兩種定制Cell的方法业汰,分別是:
1、繼承UITAbleViewCell定制Cell菩颖。通過繼承UITableViewCell來添加任意控件样漆,設(shè)置任意樣式。
2晦闰、使用動態(tài)單元格原型定制Cell放祟。在本次通訊錄的作業(yè)中,筆者就使用了這種方法呻右,由于是在Interface Builder中定制Cell跪妥,所以感覺非常方便,而且只要在Cell屬性中窿冯,為identifier添加一個值,就可以使用前面提到的dequeueReusableCellWithIdentifier:方法确徙,使用Cell醒串,所以感覺十分方便。
在經(jīng)過一段時間的學習后鄙皇,感覺最適合我的定制Cell方法是將前文提到的兩種方法結(jié)合使用芜赌,來定制Cell。這樣定制的Cell使用起來十分方便伴逸,而且獨立性很高缠沈,也方便復(fù)用,具體的定制方法错蝴,不在多說了洲愤。只要按照老師講的視頻練習幾遍,比看上百份介紹方法更為可靠和實用顷锰。關(guān)鍵只有一點柬赐,自己拖控件在Cell上時,不太方便訪問到控件時官紫,用可通過調(diào)用Tag方法來訪問控件肛宋,示列代碼如下:
UILabel * Name=(UILabel*)[cell viewWithTag:1];//通過 ViewWithTag:獲取到對象控件,再強制轉(zhuǎn)會類型束世,將其對象賦予一個實例對象來訪問內(nèi)部的屬性酝陈。
二、CollectionView
通過對CollectionView的認識毁涉,應(yīng)該說CollectionView是TableView的擴展沉帮,是在對其在原用的基礎(chǔ)上,加強對于美化界面的能力。也就說CollectionView中的許多可設(shè)置項都可以在TableView中找到相似的設(shè)置遇西。
先來看看其最基本的界面構(gòu)成:
可以看到馅精,CollectionView基本模版是模仿書架做的,其中的“書”就是collectionView的Cells了粱檀。
這里重點看一下CollectionView的比較重要的組成部分
1洲敢、Items:該屬性用于設(shè)置UICollectionView的單元格原型的數(shù)量。想同于TableView中的Cell茄蚯。
2压彭、Layout:該屬性用于指定UICollectionView所使用的布局對象,它可以支持Flow渗常、Custom兩個屬性壮不,如果指定Flow屬性值,則表明使用UICollectionView FlowLayout布局對象皱碘;如果指定Custom屬性值询一,則表明會使用自定義的UICollectionViewLayout布局對象。
3癌椿、Scroll Direction:該屬性實際上來自于UICollectionViewFlowLayout布局對象健蕊,如果將Layout屬性設(shè)置為“Custom”屬性值,該下拉屬性選擇器就會消失踢俄。該屬性用于設(shè)置該控件的滾動方向缩功,它支持Vertical和Horizontal兩個屬性值,分別代表垂直滾動和水平滾動都办。
4嫡锌、Accessories: 該屬性置頂是否顯示UICollectionView分區(qū)的Supplementary Views和Decoration View。
應(yīng)該說CollectionView最為重要的就是其界面的布局了琳钉,每個Item的位置是交給UICollectionViewFlowLayout來管理的势木,每當要創(chuàng)建一個Item時,CollectionView都會向UICollectionViewFlowLayout要Item的顯示位置歌懒,所以學好CollectionView必須掌握UICollectionViewFlowLayout中的常用方法跟压,下面收集了一些常用方法,分享給同學(這些方法均是在協(xié)議<UICollectionViewDelegateFlowLayout>中):
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;//該方法返回的CGSize值歼培,將控制指定NSIndexPath對應(yīng)的單元格大小
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;
//該方法返回的UIEdgeInsets對象將控制指定分區(qū)上下左右空白區(qū)域的大小
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section;//控制指定分區(qū)內(nèi)最小的行間距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section;//值將控制指定分區(qū)內(nèi)最小的行間距震蒋。
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section;//控制指定分區(qū)的頁眉控件的大小
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section;//控制指定分區(qū)的頁腳控件的大小