UITableView的編輯模式
實現UITableView簡單的刪除功能(左滑出現刪除按鈕)
首先UITableView需要進入編輯模式。實現下面的方法,即使什么代碼也不寫也會進入編輯模式:
}
在一些應用中可能會看到,當用戶點擊一個按鈕的時候,UITableView里面的cell的左邊會出現一個紅色圓,里面是一個-,當點擊這個-的時候會出現左滑效果,出現Delete按鈕。如何實現的呢?
UITableView有一個editing屬性,如果將這個屬性設置為YES,那么就會進入編輯模式;同樣,設置為NO,就會退出。
上面的提到的例子,當用戶點擊按鈕的時候,就進入編輯模式,編輯模式默認的形式就是在左邊有一個紅色-,當用戶點擊的時候自帶左滑效果出現Delete按鈕。當用戶點擊Delete按鈕的時候又會調用上面提到的方法。
所以說了這么多,只需要將editing設置為YES并實現上面的方法就可以達到上述效果。
UITableViewCell的重用
UITableViewCell如果在tableView:cellForRowAtIndexPath:方法中,像其他類一樣,使用下面的方式創建:
蘋果實際上是幫我們提高了性能了的。假設要顯示200行數據,如果同時創建200個cell,那么無疑會非常消耗性能,并且并沒有太大的意義――因為有些cell根本還沒有顯示出來。
所以在使用UITableView的時候,只有在cell即將顯示的時候才會調用tableView:cellForRowAtIndexPath:方法,也就是說,如果有200行數據,那么只會創建我們可以看到的cell,而那些看不到的數據,則不會創建對應的cell。
比如在手機屏幕上可以同時顯示5個cell(編號為0 - 4),那么當用戶向上滑tableView的時候,第6個cell即將出現,而第1個cell還未消失,所以此時會創建6個UITableViewCell。當第7個cell出現,那么第1個cell就會完全從屏幕上消失,此時這個UITableViewCell的對象將被銷毀,并且第7個cell被創建。以此類推,當有新的cell出現,那么就會創建一個新的cell,銷毀消失的那個cell。
這樣雖然不必同時創建200個cell,但是在不斷地創建-銷毀cell,性能上依然會有問題。
蘋果提供的更好的方法是將cell復用,而不是銷毀。
每次有新的cell出現的時候(也就是tableView:cellForRowAtIndexPath:方法執行的時候),不應該直接創建一個cell,而是應該去緩沖池中查找有沒有可復用的cell,如果有,那么就重用這個cell;如果沒有,則創建一個cell。這樣無論數據是200行,2000行還是20000行,實際上創建的只是屏幕可見的cell的個數。
還是上面的例子,當第7個cell即將出現,第1個cell消失,此時并不會銷毀第一個cell,而是將它放入緩沖池中等待復用。此時第7個cell會首先去緩沖池中尋找是否有可復用的cell,發現有(就是消失的第1個cell),那么就會拿來復用,而不是重新創建。這樣一來,消失一個,下次就會重用這個,這樣就可以保證創建最少數量的cell,仍然可以滿足需求。
實現cell的重用可以采用下面的方法:
使用代碼自己來創建新的cell:
return cell;
}
當cell為nil,需要創建新的cell的時候,使用的是initWithStyle:reuseIdentifier:方法,而不是init方法,這樣做是因為創建新的cell的時候需要綁定一個identifier,這樣在重用的時候才能找到可重用的相同類型。如果使用init方法則沒有綁定identifier,這樣在重用的時候無法成功找到對應的可重用的cell。
一般在if(!cell)中,也就是在新創建cell的時候,將一些只需要初始化一次的屬性進行初始化,而不是在這個括號的外面。因為在括號外面會執行多次,而這些屬性并不需要多次設置。同樣,如果不同的cell需要設置不同屬性或數據,那么需要在括號外執行,因為括號外面每次cell出現都會執行到,這樣可以保證不用的cell對應不同的屬性或數據。如果將本該設置不同cell對應不同屬性的代碼放在括號里面,在復用cell的時候不會重新覆蓋這些數據,會出現不正確的結果,早晨數據冗余的問題。
另一種方法是自動創建新的cell:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:cellIdentifier];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
cell.textLabel.text = @"hello";
return cell;
}
這個方法省去了我們自己手動創建cell,但是也有不足:蘋果提供給我們的cell的樣式,除了默認的,我們都不能用了。
第一種方法我們通過手動創建cell,使用initWithStyle:reuseIdentifier:可以傳入不同的style來創建蘋果為我們提供的cell,但是在第二種方法中無法實現了。
第二種方法更多的時候用在我們自定義Cell。雖然無法使用更多的系統自帶樣式,但是我們首先可以注冊自定義的cell的類(將UITableViewCell換成自定義的Cell),然后仍然首先去緩沖池中找有沒有可重用cell,如果沒有,則根據注冊的cell來創建cell并綁定identifier。當然,在使用dequeueReusableCellWithIdentifier:的時候,返回的應該也是自定義的Cell類型。
注冊的不僅可以是Class,還可以是nib,也就是說可以注冊通過xib創建的cell,和上面的方法同理。
還可以直接通過Storyboard,設置好prototype cell的identifier,在dequeueReusableCellWithIdentifier:中就可以直接使用cell,既不用提前注冊,也不用手動創建cell。
新聞熱點
疑難解答