tableView的數據源及代理方法

UITableView數據源(dataSource)和代理(delegate)

UITableView需要一個數據源(dataSource)來顯示數據,UITableView會向數據源查詢一共有多少行數據以及每一行顯示什麼數據等。沒有設置數據源的UITableView只是個空殼。凡是遵守UITableViewDataSource協議的OC對象,都可以是UITableView的數據源

通常都要爲UITableView設置代理對象(delegate)以便在UITableView觸發一下事件時做出相應的處理,比如選中了某一行。凡是遵守了UITableViewDelegate協議的OC對象,都可以是UITableView的代理對象。一般會讓控制器充當UITableViewdataSourcedelegate

 

UITableViewDataSource

 

@required

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;

section分區一共有多少行

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

創建第section分區第row行的UITableViewCell對象(indexPath包含了sectionrow)

@optional

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;

一共有多少個分區

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;

section分區的頭部標題

- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section;

section分區的底部標題

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath;

某一行是否可以編輯(刪除)

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath;

某一行是否可以移動來進行重新排序

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView;

UITableView右邊的索引欄的內容

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

選中了UITableView的某一行

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

某一行的高度

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section

section分區頭部的高度

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section

section分區尾部的高度

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section

section分區頭部顯示的視圖

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section

section分區尾部顯示的視圖

- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath

設置每一行的等級縮進(數字越小,等級越高)

 

UITableViewCell

 

UITableView的每一行都是一個UITableViewCell,通過dataSource

tableView:cellForRowAtIndexPath:方法來初始化每一行

UITableViewCellUIView的子類,內部有個默認的子視圖:contentViewcontentViewUITableViewCell所顯示內容的父視圖,並負責顯示一些輔助指示視圖。輔助指示視圖的作用是顯示一個表示動作的圖標,可以通過設置UITableViewCellaccessoryType來顯示,默認是UITableViewCellAccessoryNone(不顯示輔助指示視圖),其他值如下:

UITableViewCellAccessoryDisclosureIndicator 

UITableViewCellAccessoryDetailDisclosureButton

UITableViewCellAccessoryCheckmark

 

UITableViewCellcontentView

 

contentView下默認有3個子視圖,其中的2個是UILabel(通過UITableViewCelltextLabeldetailTextLabel屬性訪問),第3個是UIImageView(通過UITableViewCellimageView屬性訪問)

UITableViewCell還有一個UITableViewCellStyle屬性,用於決定使用contentView的哪些子視圖,以及這些子視圖在contentView中的位置

 

UITableViewCell對象的重用原理

 

iOS設備的內存有限,如果用UITableView顯示成千上萬條數據,就需要成千上萬個UITableViewCell對象的話,那將會耗盡iOS設備的內存。要解決該問題,需要重用UITableViewCell對象

重用原理:當滾動列表時,部分UITableViewCell會移出窗口,UITableView會將窗口外的UITableViewCell放入一個對象池中,等待重用。當UITableView要求dataSource返回UITableViewCell時,dataSource會先查看這個對象池,如果池中有未使用的UITableViewCelldataSource會用新的數據配置這個UITableViewCell,然後返回給UITableView,重新顯示到窗口中,從而避免創建新對象

還有一個非常重要的問題:有時候需要自定義UITableViewCell(用一個子類繼承UITableViewCell),而且每一行用的不一定是同一種UITableViewCell(如短信聊天佈局),所以一個UITableView可能擁有不同類型的UITableViewCell,對象池中也會有很多不同類型的UITableViewCell,那麼UITableView在重用UITableViewCell時可能會得到錯誤類型的UITableViewCell

解決方案:UITableViewCell有個NSString *reuseIdentifier屬性,可以在初始化UITableViewCell的時候傳入一個特定的字符串標識來設置reuseIdentifier(一般用UITableViewCell的類名)。當UITableView要求dataSource返回UITableViewCell時,先通過一個字符串標識到對象池中查找對應類型的UITableViewCell對象,如果有,就重用,如果沒有,就傳入這個字符串標識來初始化一個UITableViewCell對象

 

重用UITableViewCell對象

 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 

{

    static NSString *identifier = @"UITableViewCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];

    if (cell == nil) {

        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];

     }

    cell.textLabel.text = [NSString stringWithFormat:@"Text %i", indexPath.row];

    return cell;

}

 

UITableViewCell的常用屬性

 

設置背景

backgroundView

設置被選中時的背景視圖

selectedBackgroundView

 

selectionStyle屬性可設置UITableViewCell被選中時的背景顏色:

UITableViewCellSelectionStyleNone  沒有顏色

UITableViewCellSelectionStyleBlue  藍色(默認)

UITableViewCellSelectionStyleGray  灰色

 

自定義UITableViewCell

 

一般有兩種方式:

用一個xib文件來描述UITableViewCell的內容

通過代碼往UITableViewCellcontentView中添加子視圖,在初始化方法(比如initinitWithStyle:reuseIdentifier:)中添加子控件,在layoutSubviews方法中分配子控件的位置和大小

 

UITableView的編輯模式

 

UITableView有個editing屬性,設置爲YES時,可以進入編輯模式。在編輯模式下,可以管理表格中的行,比如改變行的排列順序、增加行、刪除行,但不能修改行的內容

多種方式開啓編輯模式

@property(nonatomic,getter=isEditing) BOOL editing

- (void)setEditing:(BOOL)editing animated:(BOOL)animated

 

刪除UITableView的行

 

首先要開啓編輯模式

實現UITableViewDataSource的如下方法:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 

{

    // 如果UITableView提交的是刪除指令

    if (editingStyle == UITableViewCellEditingStyleDelete) {

        // 刪除真實數據

         // [self.data removeObjectAtIndex:indexPath.row];

        // 刪除UITableView中的某一行(帶動畫效果)

        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];

        // 如果不考慮動畫效果,也可以直接[tableView reload];

    }

}

 

移動UITableView的行

 

首先要開啓編輯模式

實現UITableViewDataSource的如下方法(如果沒有實現此方法,將無法換行)

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath 

{

    int from = sourceIndexPath.row;

    int to = destinationIndexPath.row;

    if (from == to) return;

    // 交換數據

    // [self.data exchangeObjectAtIndex:from withObjectAtIndex:to];

}

 

選中UITableView的行

 

當某行被選中時會調用此方法(UITableViewDelegate的方法)

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 

{

    //取消選中某一行,讓被選中行的高亮顏色消失(帶動畫效果)

    [tableView deselectRowAtIndexPath:indexPath animated:YES];

}

 

UITableView常用方法

 

- (id)initWithFrame:(CGRect)frame style:(UITableViewStyle)style

初始化一個UITableView,並且設置表格樣式

- (void)reloadData   重新訪問數據源,刷新界面

- (NSInteger)numberOfSections  分區的個數

- (NSInteger)numberOfRowsInSection:(NSInteger)section

section分區的行數

- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath

通過indexPath找到對應的UITableViewCell對象

- (void)setEditing:(BOOL)editing animated:(BOOL)animated

是否要開啓編輯模式

- (void)deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated

取消選中某一行,讓被選中行的高亮顏色消失(帶動畫效果)

- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier

通過identifier(緩存)池中找到對應的UITableViewCell對象

- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation

移除indexPaths範圍內的所有行

@property(nonatomic,readonly) UITableViewStyle style 表格樣式

@property(nonatomic,assign) id <UITableViewDataSource> dataSource

數據源

@property(nonatomic,assign) id <UITableViewDelegate> delegate 代理

@property(nonatomic,getter=isEditing) BOOL editing 是否爲編輯模式

@property(nonatomic) UITableViewCellSeparatorStyle separatorStyle

設置分隔線的樣式

@property(nonatomic,retain) UIColor *separatorColor

設置分隔線的顏色

@property(nonatomic,retain) UIView *tableHeaderView

表頭顯示的視圖

@property(nonatomic,retain) UIView *tableFooterView

表尾顯示的視圖

@property(nonatomic) BOOL allowsSelection

是否允許選中行

@property(nonatomic) BOOL allowsSelectionDuringEditing

是否允許在編輯模式下選中行

@property(nonatomic) BOOL allowsMultipleSelection

是否允許選中多行

@property(nonatomic) BOOL allowsMultipleSelectionDuringEditing

是否允許在編輯模式下選中多行

 

UITableViewController

 

UIViewController的子類,UITableViewController默認扮演了3種角色:視圖控制器、UITableView的數據源和代理

UITableViewControllerview是個UITablView,UITableViewController負責設置和顯示這個對象。UITableViewController對象被創建後,會將這個UITableView對象的dataSourcedelegate指向UITableViewController自己

 

 

 

 

一、UITableView

1.數據展示的條件

1> UITableView的所有數據都是由數據源(dataSource)提供的,所以要想在UITableView展示數據,必須設置UITableViewdataSource數據源對象

2> 要想當UITableViewdataSource對象,必須遵守UITableViewDataSource協議,實現相應的數據源方法

3> UITableView想要展示數據的時候,就會給數據源發送消息(調用數據源方法),UITableView會根據方法返回值決定展示怎樣的數據

2.數據展示的過程

1> 先調用數據源的

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

得知一共有多少組

2> 然後調用數據源的

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

得知第section組一共有多少行

3> 然後調用數據源的

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

得知第indexPath.section組 第indexPath.row 行顯示怎樣的cell(顯示什麼內容)

3.常見數據源方法

1> 一共有多少組

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

2> section組一共有多少行

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

3> indexPath.section組 第indexPath.row行顯示怎樣的cell(顯示什麼內容)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

4> section組顯示怎樣的頭部標題

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;

5> section組顯示怎樣的尾部標題

- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section;

4.tableView刷新數據的方式

1> 修改模型數據

2> 刷新表格

* reloadData 整體刷新(每一行都會刷新)

* - (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation

局部刷新

5.性能優化

1> 定義一個循環利用標識

static NSString *ID = @"C1";

2> 從緩存池中取出可循環利用的cell

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];

3> 如果緩存池中沒有可循環利用的cell

if (cell == nil) 

{

    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];

}

4> 覆蓋cell上面的數據

cell.textLabel.text = [NSString stringWithFormat:@"%d行數據", indexPath.row];

 

 

 

1.UITableView繼承UIScrollView.

2.實例一城市列表思路:

步驟一:創建UITableViewUITableView樣式爲組

步驟二:設置UITableView的數據源方法。

步驟三:實現UITableView的數據源方法,此方法會自動調用。

  1. 返回有多少組
  2. 返回一組有多少行
  3. 返回每一行顯示的UITableViewCell(繼承UIView),initWithStyle使用這個方法調用。
  4. 注意UITableView的數據源的方法普遍都是以tableView開頭。

步驟四:用數組管理數據。

步驟五:每個數組中都是一個字典,key:header,footer,cityes.

3.擴展性好:指的是需求改了,代碼不需要怎麼改。

4.創建模型的時候,自定義一個工廠方法(類方法)接口給外界調用。

工廠方法好處:簡化對象的實例化,快速創建對象。

5.UITableViewCell

UITableViewCellStyleDefault 

UITableViewCellStyleValue1

UITableViewCellStyleSubtitle

UITableViewCellStyleValue2

6.UITableViewCell設置右邊輔助視圖accessoryType;

UITableViewCellAccessoryDisclosureIndicator

UITableViewCellAccessoryDetailDisclosureButton

UITableViewCellAccessoryCheckmark

7.快捷創建代碼方法中<#   #>用法。

8.中文字前面不要加\,會把\後面的中文轉義,正確描述:圖書/音像

9.UIAlertView

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"產品信息展示" message:@"哈哈哈哈哈" delegate:nil cancelButtonTitle:@"ABC" otherButtonTitles:@"123",@"456", nil];

// 彈出UIAlertView

[alert show];

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"產品信息展示" message:@"哈哈哈哈哈" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"確定", nil];

// 彈出UIAlertView

[alert show];

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"產品信息展示" message:p.name delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"確定", nil];

alert.alertViewStyle = UIAlertViewStyleLoginAndPasswordInput;

// 彈出UIAlertView

[alert show];

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"產品信息展示" message:p.name delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"確定", nil];

alert.alertViewStyle = UIAlertViewStylePlainTextInput;

// 彈出UIAlertView

[alert show];

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"產品信息展示" message:p.name delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"確定", nil];

alert.alertViewStyle = UIAlertViewStyleSecureTextInput;

// 彈出UIAlertView

[alert show];

10.監聽UIAlertView的事件.

步驟一:設置UIAlertView的代理

步驟二:遵守UIAlertView的協議

步驟三:實現UIAlertView的按鈕點擊協議方法。

11.按鈕方法內部實現

步驟一: 取出文本框文字 

注意UIAlertView中的文本框的角標是根據UIAlertView從上到下第幾個文本框決定的。最上面的文本框角標爲0.

步驟二:  修改模型數據

步驟三:  刷新表格

12.UITableView中的reloadData,會重新整個表格。

13.-(void)reloadRowsAtIndexPaths:(NSArray*)indexPaths withRowAnimation:(UITableViewRowAnimation)animation

// 指定刷新indexPaths數組裏的行數。

注意indexPaths裏存儲的是NSIndexPath對象

14.UITableView的性能優化

UITableView默認只會加載出現在屏幕上面的cell,沒當有一個cell移除屏幕,就會存儲到緩存池裏找。

性能優化步驟:

步驟一:定義cell的標識(不需要每次都創建cell標識,因此需要使用staticstatic標識只會在第一次創建,以後都不會創建了。

步驟二:從緩存池裏取cell

步驟三:判斷取出cell是否爲空,如果爲空就手動創建cell

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