UITableView用得較多,遇到的情況也較多,單獨記錄一篇。 一、零散的技巧 二、取cell 三、cell高度 四、導航欄、TableView常見問題相關 一、零散的技巧 1、 cell的選中效果是cell的屬性,可以有的有,無的無。 2、cell的下劃線是Table的屬性,全部有,或全部無。 ...
UITableView用得較多,遇到的情況也較多,單獨記錄一篇。
一、零散的技巧
二、取cell
三、cell高度
四、導航欄、TableView常見問題相關
一、零散的技巧
1、 cell的選中效果是cell的屬性,可以有的有,無的無。
// 自定義cell self.selectionStyle = UITableViewCellSelectionStyleNone; // 取cell cell.selectionStyle = UITableViewCellSelectionStyleNone;
2、cell的下劃線是Table的屬性,全部有,或全部無。
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
3、cell下劃線左邊頂住屏幕左邊。
cell.preservesSuperviewLayoutMargins = NO; cell.layoutMargins = UIEdgeInsetsZero; cell.separatorInset = UIEdgeInsetsZero;
後續補充:也可以隱藏掉系統的下劃線,自定義LineView,要多寬就多寬,且可以實現不同cell不同下劃線樣式。
4、cell的重用ID,可以用類名
NSStringFromClass([MyCell class])
二、取cell
1、cell初始化的一些區別
1)、TableViewCell
1-1)、沒註冊
沒註冊的(一開始會取不到): cell = 從隊列取 if(cell取不到) { 創建cell 創建子視圖,加tag } cell從tag取子視圖,刷新 tag 或 屬性
1-2)、註冊
註冊的(100%取得到): cell = 從隊列取(有indexPath的方法) 刷新 tag 或 屬性 ( 系統取不到,會走自定義的initWithStyle:reuseIdentifier: if(cell創建成功) { 創建子視圖,加tag } )
2)、CollectionViewCell
2-1)、沒註冊
2-2)、註冊
註冊的(100%取得到): cell = 從隊列取(有indexPath的方法) if(cell取得到) { (判斷是否有子視圖)創建子視圖 } 刷新 tag 或 屬性 collectionViewCell 流程有點不同 1、沒 TableViewCell 的 initWithStyle:reuseIdentifier: 2、但 每次都能從隊列取到 3、所以 需要判斷取到的cell是否有子視圖,不然會不斷創建
2、載入XIB
1)、從多個cell樣式的XIB載入。只有1個cell樣式,可直接lastObject載入。(先根據不同的ID取,取不到再載入。)
1-1)、獲取XIB里的所有對象
NSArray *cellArry = [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([MyTableCell class]) owner:self options:nil];
1-2)、讀取對應的Cell樣式,此時的參數type為枚舉,或基本數據類型。
cell = [cellArry objectAtIndex:type];
2)、在 UIView + xxx 的類別文件里,可以添加這個類。方便載入單種Cell樣式的XIB。
+ (instancetype)viewFromXib { return [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self) owner:nil options:nil] lastObject]; }
三、cell高度
0、 有展開功能的cell,每次都要計算。
無展開功能的cell,可弄數組、模型存數據,以免每次計算。
貌似系統計算的(下麵的3、4、),耗時都長?複雜的cell滑動不流暢?所以還是能手動就手動咯(下麵的1、2、)?
1、自定義cell類方法
+ (CGFloat)getCellHeight { return 44; } + (CGFloat)getCellHeightWithData:(id)data { // 手動計算label的高度 return 計算高度; }
後續補充:對於固定高度,沒問題,好用。對於根據Data計算的,根據情況保存計算高度。
2、模型(只有屬性的特殊類)
後續補充:通過get方法讀取。需要才計算(懶載入),可能還要判斷是否計算過,否則每次都要計算?
3、系統自動計算(iOS6後,UIView的類別UIConstraintBasedLayoutFittingSize,控制項需要全是 Autolayout 約束?)
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { // 取出不帶 indexPath 的 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([MyCell class])]; // 填充數據 //cell.model = model[indexPath.row]; [cell initData:data[indexPath.row]]; // 計算高度 // UILayoutFittingCompressedSize 返回最小可能的值 // UILayoutFittingExpandedSize 返回最大可能的值 cellHeight = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height + 0.5f; return cellHeight; }
後續補充:1、根據情況保存計算高度。
2、普通View非Cell,的高度計算也可用,但同樣要 Autolayout 約束。
3、註冊cell,一般是取出帶indexPath的。不帶indexPath一般是在自寫cell重用機制的用的。
但是,還可以取出一個普通的cell樣式,不帶 indexPath。來填充數據,計算高度。
4、對3、補充,如果是xib可以用 NSBundle。
5、對3、再補充,可以弄個局部變數,用懶載入獲取普通cell,不用每次都獲取。
4、
四、導航欄、TableView常見問題相關
1、導航欄、TableView
//調整contentInset。
//NO:不調整,按設定的frame、contentInset的顯示
//YES:會調整contentInset.top的高,讓顯示的頂在導航欄下麵,【有滑過半透明效果】
self.automaticallyAdjustsScrollViewInsets =NO;
//調整frame
// UIRectEdgeNone //會頂在導航欄下麵【沒有滑過半透明效果】
// UIRectEdgeTop //對齊原點
// UIRectEdgeLeft //對齊左邊
// UIRectEdgeBottom //對齊頂部
// UIRectEdgeRight //對齊右邊
// UIRectEdgeAll //對齊所有
self.edgesForExtendedLayout = UIRectEdgeNone;
//導航欄半透明
self.navigationController.navigationBar.translucent = YES;
//隱藏navigationBar(1、它推過的所有的VC共用1個Bar;2、用繼承View的hidden屬性,隱藏不了!)
self.navigationController.navigationBarHidden=YES;
後續補充:iOS11後 automaticallyAdjustsScrollViewInsets 廢棄,不過還需要做版本判斷。
詳見“2、iOS11”
2、iOS11(此處參考簡書 “iOS 11 安全區域適配總結”--sonialiu)
1)、TableView 預設開啟Cell高度估算,關掉。
[UITableView appearance].estimatedRowHeight = 0; [UITableView appearance].estimatedSectionHeaderHeight = 0; [UITableView appearance].estimatedSectionFooterHeight = 0;
2)、ScrollView新增安全區域。
2-1)、如果之前讓TabelView頂住屏幕,然後設置頂部內邊距 = 20+44,剛好在導航欄下麵的話,
會被系統向下偏移64的 SafeAreaInsets,再加上自己設置的64,就出現下移64問題。
2-2)、同理,沒導航欄的時候,也會下移20 -> 狀態欄的高度。
2-3)、以前若設置 automaticallyAdjustsScrollViewInsets = YES 讓系統自動調整,不會有問題
解決方案:添加下麵,相當於 automaticallyAdjustsScrollViewInsets = NO
#ifdef __IPHONE_11_0 if ([tableView respondsToSelector:@selector(setContentInsetAdjustmentBehavior:)]) { [UIScrollView appearance].contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; } #endif
2-4)、contentInsetAdjustmentBehavior 其他類型
UIScrollViewContentInsetAdjustmentScrollableAxes: adjustedContentInset = ( 可滾動方向 ? safeAreaInset + contentInset : contentInset );
UIScrollViewContentInsetAdjustmentNever: adjustedContentInset = contentInset;
UIScrollViewContentInsetAdjustmentAlways: adjustedContentInset = safeAreaInset + contentInset;
UIScrollViewContentInsetAdjustmentAutomatic: (controller里automaticallyAdjustsScrollViewInsets = YES) && (controller被navigation包含) == Always,否則 == Axes