UITableView是工程開發中最經常使用到的UI控制元件,但是你真的瞭解它嘛,這裡記錄幾點有用的但你可能並不知道的。
- 當我們的資料未能顯示滿一螢幕的時候,UITableView會顯示多餘的橫線,這個時候你如果希望去掉這些橫線,你可以加上這句話。
1self.tableView.tableFooterView = [[UIView alloc]init]; - UITableView的分割線預設是開頭空15畫素點的(好像是15來著~~),產品經理有時候希望能夠定格顯示,那麼你可能會這麼做。
1self.tableView.separatorInset = UIEdgeInsetsZero;
但是你很快就會發現這麼做並沒有效果,這是因為separatorInset
這個屬性在iOS7以後就已經失效了,但是我們還是能夠達到同樣的效果,你可以在你的tablevView的代理協議實現介面加上下面這段程式碼:
12345678910111213141516171819202122/*** 分割線頂頭*/-(void)viewDidLayoutSubviews{if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {[self.tableView setSeparatorInset:UIEdgeInsetsMake(0,0,0,0)];}if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {[self.tableView setLayoutMargins:UIEdgeInsetsMake(0,0,0,0)];}}-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {[cell setSeparatorInset:UIEdgeInsetsZero];}if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {[cell setLayoutMargins:UIEdgeInsetsZero];}}
再次執行,好了我們的UITableView終於頂頭顯示分割線了。 - 很多情況下我們的UITableViewCell的高度是動態不確定的,比如說很多聊天的介面都需要我們去動態的計算cell的高度,你可能會在
heightForRowAtIndexPath
代理協議方法中返回你計算好的cell高度,然後在蘋果推出約束以後,我們其實有更加方便的方法去實現相同的效果。你可以嘗試在你的程式碼中加入以下兩行程式碼:
12self.tableView.estimatedRowHeight = 68.0;self.tableView.rowHeight = UITableViewAutomaticDimension;
再次執行你的程式,其實你發現了好像你的cell並沒有動態的返回高度,這是因為上面說了,這兩行程式碼必須配合約束來使用。
我們拖出一個SB,然後在cell上放上一個label,講label的numberOfLines
屬性設定為0,然後設定好label的上下左右約束,然後再對label的內容進行賦值,再次執行你的程式,這個時候你的cell就會動態的顯示高度了,label的高度取決於你的內容的多少,同時按照你的約束進行顯示。
-你可能寫過這樣下面這樣的程式碼
1234567-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{[tableView deselectRowAtIndexPath:indexPath animated:true];[tableView beginUpdates];ROW--;//此操作表示減少資料來源的個數。[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationRight];[tableView endUpdates];}
用一個動畫來刪除某一個cell,其中有兩行程式碼特別有意思:
12[tableView beginUpdates];[tableView endUpdates];
這倆吧其實和[tableView reloadData]
作用類似,但是這倆貨卻能非常輕鬆的創造出不錯的效果,比如說和我們上一點說的用約束來控制label的行高相結合的是的時候,我們先來看一下效果:
一個tableView點選縮放的效果
其實我的程式碼很少,核心程式碼只有以下幾行:
1 2 3 4 5 6 7 8 9 10 11 12 |
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ [tableView deselectRowAtIndexPath:indexPath animated:true]; UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; UILabel *label = [cell.contentView viewWithTag:1000]; [tableView beginUpdates]; if (label.numberOfLines == 0) { label.numberOfLines = 1; }else{ label.numberOfLines = 0; } [tableView endUpdates]; } |
我用SB建立了一個UITableView,然後在cell上放置了一個label,初始化label 的numberOfLines
然後在介面上設定tableView
1 2 |
self.tableView.estimatedRowHeight = 68.0; self.tableView.rowHeight = UITableViewAutomaticDimension; |
然後在他的點選動作中改變label的numberOfLines
,同時結合使用:
1 2 |
[tableView beginUpdates]; [tableView endUpdates]; |
像上面po出來的程式碼那樣,這個時候你如果使用[tableView reloadData]也能夠達到改變cell高度的效果,但是介面上就不會有使用[tableView beginUpdates]那麼流暢,以此類推,其實在很多地方都可以用[tableView beginUpdates]
來代替[tableView reloadData]
來達到更好的效果.
- 你可能會經常忽略UITableView的一些屬性和回撥,必須下面這個方法:
12345678910111213-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{CGFloat offSet = tableView.contentOffset.y;if (offSet<=0) {return;}CGRect oldRect = cell.frame;CGRect newRect = cell.frame;newRect.origin.x += 50;cell.frame = newRect;[UIView animateWithDuration:0.5 animations:^{cell.frame = oldRect;}];}
如果你這麼寫會簡單的有一個展示的動畫,這個回撥就是在cell展示到螢幕的時候發起的動作。
還有這個屬性:tableView.visibleCells
,你的產品經理可能會要求你的cell在滾動的時候進行一些展示類的動畫—-滾動的時候進行展開收起之類的,這樣的話你可以這麼做:
12345678-(void)scrollViewDidScroll:(UIScrollView *)scrollView{for (UITableViewCell *cell in _tableView.visibleCells) {/*** 你可以在這裡對當前的cell進行一些操作**/}}
這個屬性會返回即將展示到螢幕上的cell,而放在這個滾動的回掉中你就可以對你的cell進行不停的調整了,具體能做出什麼動畫,就靠你的想象能力了。 - tableView可能會造成你的Controller過於龐大,或許你可以使用MVVM類似的構架來瘦身你的Controller。。。。。。