一苇倡、UITableView
UITableView基本介紹
UITableView在iOS開發(fā)中是應用最為廣泛的一種控件邮弹。在了解UITableView之前泰鸡,首先看一下iOS開發(fā)中UI控件的組織結構:
從上圖中可以看出滞乙,UITableView它的繼承關系是:
因此UITableView可以響應事件奏纪、支持垂直滾動,?且性能極佳 。
UITableView的結構
UITableView的結構如下圖所示:
可以看出:
一個tableView = 一個tableView HeaderView + 若干個section + 一個tableView FooterView;
一個section = 一個section HeaderView + 若干個cell + 一個section FooterView ;
UITableView的初始化方法為:
// 設置表的大小斩启、位置以及樣式
//(style:包括plain和group)
- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style;
//或者用UIView的初始化方法序调,設置表的大小和位置
- (instancetype)initWithFrame:(CGRect)frame;
UITableView的風格
UITableViewStyle
是一個枚舉,有兩種樣式:
UITableViewStylePlain
和 UITableViewStyleGrouped
:
typedef NS_ENUM(NSInteger, UITableViewStyle) {
UITableViewStylePlain, // 標準的表視圖樣式
UITableViewStyleGrouped // 分組的表視圖樣式
};
兩種樣式如下圖所示:
UITableView的屬性
常用的屬性有:
// 獲取表視圖的樣式(plain和group)
@property (nonatomic, readonly) UITableViewStyle style;
// 可設置UITableViewDataSource的代理
@property (nonatomic, weak, nullable) id <UITableViewDataSource> dataSource;
// 可設置UITableViewDelegate的代理
@property (nonatomic, weak, nullable) id <UITableViewDelegate> delegate;
// tableView的行高兔簇、組頭試圖炕置、組尾視圖的高度,未設置時男韧,返回默認值:-1.0
// 當與代理方法同時實現(xiàn)時,按照代理方法中的高度進行設置
@property (nonatomic) CGFloat rowHeight;
@property (nonatomic) CGFloat sectionHeaderHeight;
@property (nonatomic) CGFloat sectionFooterHeight;
// 性能優(yōu)化(如果實現(xiàn)),估計tableView的行高默垄、組頭試圖此虑、組尾視圖的高度,未設置時口锭,返回默認值:0.0
//在顯示的時候回去調用heightForRowAtIndexPath朦前,真正開始計算
@property (nonatomic) CGFloat estimatedRowHeight;
@property (nonatomic) CGFloat estimatedSectionHeaderHeight;
@property (nonatomic) CGFloat estimatedSectionFooterHeight;
// section的個數(shù)
@property (nonatomic, readonly) NSInteger numberOfSections;
// 返回可見的cells
@property (nonatomic, readonly) NSArray<__kindof UITableViewCell *> *visibleCells;
// 返回可見的位置
@property (nonatomic, readonly, nullable) NSArray<NSIndexPath *> *indexPathsForVisibleRows;
// 設置背景視圖介杆,只能寫入,可根據(jù)tableView 的大小進行自動調整
@property (nonatomic, strong, nullable) UIView *backgroundView
/*
* 編輯相關(Editing)
*/
// 是否允許編輯,默認是NO
@property (nonatomic, getter=isEditing) BOOL editing;
- (void)setEditing:(BOOL)editing animated:(BOOL)animated;
// 在非編輯下韭寸,行是否可以選中春哨,默認為YES
@property (nonatomic) BOOL allowsSelection;
// 在編輯模式下,行是否可以選中恩伺,默認為NO
@property (nonatomic) BOOL allowsSelectionDuringEditing;
// 在非編輯模式下赴背,是否允許同時選擇多行,默認為NO
@property (nonatomic) BOOL allowsMultipleSelection;
// 在編輯模式下晶渠,是否允許同時選擇多行凰荚,默認為NO
@property (nonatomic) BOOL allowsMultipleSelectionDuringEditing;
/*
* 選擇相關(Selection)
*/
// 返回選定cell所對應的indexPath,單行,未選中時返回nil
@property (nonatomic, readonly, nullable) NSIndexPath *indexPathForSelectedRow;
// 返回選定cells所對應的indexPath集合,多行褒脯,未選中時返回nil
@property (nonatomic, readonly, nullable) NSArray<NSIndexPath *> *indexPathsForSelectedRows;
/*
* 顯示相關(Appearance)
*/
// 指定當tableView中多少行的時候開始顯示IndexList便瑟,
// 默認的設置是NSIntegerMax,即默認是不顯示indexList的
@property (nonatomic) NSInteger sectionIndexMinimumDisplayRowCount;
// 索引號顏色
@property (nonatomic, strong, nullable) UIColor *sectionIndexColor;
// 索引號背景顏色(未觸摸/點擊時顯示的背景顏色)
@property (nonatomic, strong, nullable) UIColor *sectionIndexBackgroundColor;
// 跟蹤索引號背景顏色(觸摸/點擊時顯示的背景顏色)
@property (nonatomic, strong, nullable) UIColor *sectionIndexTrackingBackgroundColor;
// cell之間分隔線的樣式(默認是UITableViewCellSeparatorStyleSingleLine)
@property (nonatomic) UITableViewCellSeparatorStyle separatorStyle;
// cell的分割線的偏移番川。(UIEdgeInsets中的right到涂、left起作用???)
@property (nonatomic) UIEdgeInsets separatorInset;
// cell之間的分割線顏色(默認是灰色)
@property (nonatomic, strong, nullable) UIColor *separatorColor;
// 設置毛玻璃效果
@property (nonatomic, copy, nullable) UIVisualEffect *separatorEffect;
// if cell margins are derived from the width of the readableContentGuide.
@property (nonatomic) BOOL cellLayoutMarginsFollowReadableWidth;
// 設置headerView
@property (nonatomic, strong, nullable) UIView *tableHeaderView;
// 設置footerView
@property (nonatomic, strong, nullable) UIView *tableFooterView;
// 記住上次的選擇
@property (nonatomic) BOOL remembersLastFocusedIndexPath;
UITableView的方法
// 表格進入編輯狀態(tài),是否有動畫
- (void)setEditing:(BOOL)editing animated:(BOOL)animated;
/*
* 數(shù)據(jù)相關(Data)
*/
// 刷新整個表視圖
- (void)reloadData;
// 刷新索引欄
- (void)reloadSectionIndexTitles
/*
* 信息相關(Info)
*/
// 獲取某個組有多少行
- (NSInteger)numberOfRowsInSection:(NSInteger)section;
//根據(jù)section或indexPath獲得section颁督、headerView践啄、footerView、row對應的CGRect
// 獲取某個組的位置和大小(包括頭尾試圖和所有行)
- (CGRect)rectForSection:(NSInteger)section
// 取某個組的頭視圖的位置和大小
- (CGRect)rectForHeaderInSection:(NSInteger)section;
// 取某個組的尾視圖的位置和大小
- (CGRect)rectForFooterInSection:(NSInteger)section;
// 獲取某一行的位置和大小
- (CGRect)rectForRowAtIndexPath:(NSIndexPath *)indexPath;
// 根據(jù)point适篙、cell或rect獲得indexPath
// 根據(jù)某一點往核,返回indexPath(如果點不在tableView的任何一行上,則返回nil)
- (nullable NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point;
// 獲取單元格的IndexPath信息(如果cell不可見嚷节,則返回nil)
- (nullable NSIndexPath *)indexPathForCell:(UITableViewCell *)cell;
// 返回某個區(qū)域內(nèi) 多個單元格信息(如果rect無效聂儒,則返回nil)
- (nullable NSArray<NSIndexPath *> *)indexPathsForRowsInRect:(CGRect)rect;
// 通過單元格的indexPath得到單元格
- (nullable __kindof UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath;
// 獲得頭視圖(可進行頭視圖設置)
- (nullable UITableViewHeaderFooterView *)headerViewForSection:(NSInteger)section;
// 獲得尾視圖(可進行尾視圖設置)
- (nullable UITableViewHeaderFooterView *)footerViewForSection:(NSInteger)section;
/*
* 插入、刪除硫痰、更新衩婚、移動
*/
// 二者配合使用
//添加或刪除前必須調用迫横,只添加或刪除才會更新行數(shù)
- (void)beginUpdates;
// 添加或刪除后必須調用肆资,只添加或刪除方法時才會更新
- (void)endUpdates;
//對section進行插入、刪除雹食、更新缓屠、移動操作
// 插入一個或多個section奇昙,并使用動畫
- (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
// 刪除一個或多個section,并使用動畫
- (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
// 更新一個或多個section敌完,并使用動畫
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
// 移動某一個section到目標section位置
- (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection;
//對row進行插入储耐、刪除、更新滨溉、移動操作
// 插入一個或多個row什湘,并使用動畫
- (void)insertRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
// 刪除一個或多個row长赞,并使用動畫
- (void)deleteRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
// 更新一個或多個row,并使用動畫
- (void)reloadRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
// 移動某一個row到目標row位置
- (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath NS_AVAILABLE_IOS(5_0);
/*
* 選擇相關
*/
// 設置選中某個區(qū)域內(nèi)的單元格
- (void)selectRowAtIndexPath:(nullable NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scrollPosition;
// 取消選中的單元格
- (void)deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated;
/*
* 重用機制
*/
// 獲取重用隊列里的cell闽撤,代理調用
- (nullable __kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier;
- (__kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath;
- (nullable __kindof UITableViewHeaderFooterView *)dequeueReusableHeaderFooterViewWithIdentifier:(NSString *)identifier
/*
* 注冊
*/
// 注冊cell
// 注冊xib文件自定義的cell
- (void)registerNib:(nullable UINib *)nib forCellReuseIdentifier:(NSString *)identifier;
// 注冊純代碼自定義的cell
- (void)registerClass:(nullable Class)cellClass forCellReuseIdentifier:(NSString *)identifier;
// 注冊header得哆,footer
// 注冊xib文件自定義的header,footer
- (void)registerNib:(nullable UINib *)nib forHeaderFooterViewReuseIdentifier:(NSString *)identifier;
// 注冊xib文件自定義的header哟旗,footer
- (void)registerClass:(nullable Class)aClass forHeaderFooterViewReuseIdentifier:(NSString *)identifier贩据;
2、UITableView的代理
我們發(fā)現(xiàn)單元格高度热幔、分組標題高度以及尾部說明的高度都需要調整乐设,此時就需要使用代理方法。UITableView代理方法有很多绎巨,例如監(jiān)聽單元格顯示周期近尚、監(jiān)聽單元格選擇編輯操作、設置是否高亮顯示單元格场勤、設置行高等:
// 將要展示的cell會回調(可以在其中對cell進行修改設置)
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
// 將要展示的headView會回調
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section;
// 將要展示的headView會回調
- (void)tableView:(UITableView *)tableView willDisplayFooterView:(UIView *)view forSection:(NSInteger)section;
// 完成視圖展示時回調戈锻,此時已經(jīng)在界面上了
// 完成展示的cell時,會回調
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath;
// 完成展示的headerView時和媳,會回調
- (void)tableView:(UITableView *)tableView didEndDisplayingHeaderView:(UIView *)view forSection:(NSInteger)section;
// 完成展示的footerView時格遭,會回調
- (void)tableView:(UITableView *)tableView didEndDisplayingFooterView:(UIView *)view forSection:(NSInteger)section;
/*
* 高度設置相關
*/
// 設置cell高度(這里高度通過協(xié)議返回,是為了table能準確的定位出要顯示的Cell-index留瞳,從而滿足UITableView的重用機制))
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
// 設置headerView高度
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
// 設置footerView高度
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;
//性能優(yōu)化(如果實現(xiàn))拒迅,加載的時候使用的是本方法,由于是一個固定的值她倘,不需要計算璧微,所以加載速度回很快,在顯示的時候回去調用heightForRowAtIndexPath硬梁,真正開始計算前硫。
// row的估計高度
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath;
// header的估計高度
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForHeaderInSection:(NSInteger)section;
// footer的估計高度
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForFooterInSection:(NSInteger)section;
/*
* 自定義section的頭尾視圖相關
*/
//可設置每個section-header和 footer 的自定義視圖
- (nullable UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
- (nullable UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section;
/*
* row的 Accessoriy 相關
*/
// 可設置cell上Accessory的類型accessaryType(共5種)
- (UITableViewCellAccessoryType)tableView:(UITableView *)tableView accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath;
// 設置cell上右指向Accessory的響應方法(當cell的accessaryType為UITableViewCellAccessoryDetailDisclosureButton時,
// 點擊accessaryView將會調用delegate的tableView:accessoryButtonTappedForRowWithIndexPath方法荧止。否則只是didSelectRowAtIndexPath屹电;)
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath;
/*
* 選擇(selection)相關
*/
// 是否高亮
// cell高亮回調,一般在選中的時候高亮
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath;
// cell一直高亮
- (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath;
// cell選中時不高亮
- (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath;
/* 先點擊row0跃巡,再點擊row1危号,倆著執(zhí)行順序(在下一行將要選中后才取消上一行的選中 ):
willSelectRowAtIndexPath 當前row為:0
didSelectRowAtIndexPath 當前row為:0
willSelectRowAtIndexPath 當前row為:1
willDeselectRowAtIndexPath 當前row為:0
didDeselectRowAtIndexPath 當前row為:0
didSelectRowAtIndexPath 當前row為:1
*/
// 用戶選擇之前調用,將要選中
- (nullable NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath;
// 將要取消選中(此時已選中下一個row)
- (nullable NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath;
// 用戶選中時調用素邪,已經(jīng)選中當前行
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
// 用戶選擇之后調用葱色,取消選中(已經(jīng)選中當前row)
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath;
/*
* 編輯(editing)相關
*/
// 返回編輯的類型1.沒有2.刪除3.插入
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath;
// 刪除提示文本(刪除確認按鈕上的標題文字)
- (nullable NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath;
// 左滑小菜單 可以自定義想要的編輯操作 (要求ios8以上)
- (nullable NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
// 編輯模式下,cell是否需要縮進娘香,默認是YES(縮進)苍狰,否則使用NO(只對grouped的TableView有效。)
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath;
// 用于設置縮進的級別
- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath;
// 編輯狀態(tài)發(fā)生改變時調用
// 指定cell開始編輯時調用
- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath;
// 指定cell編輯完成時調用
- (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(nullable NSIndexPath *)indexPath
/*
* 復制(copy)相關
*/
// 復制的時候三個方法都必須實現(xiàn)
// 是否將要顯示指定cell的菜單
- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath;
// 是否能使用 sender 對指定cell進行執(zhí)行操作
- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender;
//通過 sender 對指定cell執(zhí)行操作
- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender;
/*
* 移動(move)再排序相關
*/
// 移動row時執(zhí)行(將一個指定cell從source處移動到proposed(提議的)目標處 )
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath;
3烘绽、UITableView的數(shù)據(jù)源
由于iOS是遵循MVC模式設計的淋昭,很多操作都是通過代理和外界溝通的,但對于數(shù)據(jù)源控件除了代理還有一個數(shù)據(jù)源屬性安接,通過它和外界進行數(shù)據(jù)交互翔忽。
數(shù)據(jù)源:(一般為控制器)根據(jù)索引路徑(indexPath:可以定位到唯一的一個單元格)為某一個單元格提供數(shù)據(jù)。
索引路徑:(NSIndexpath)擁有兩個屬性section(段)盏檐、row(行)歇式,通過這兩個屬性即可定位UITableView中的唯一一個單元格cell
對于UITableView設置完dataSource(tableView.dataSource=self
)后,需要實現(xiàn)UITableViewDataSource
協(xié)議:
下面兩個代理方法必須實現(xiàn):
@required //必須實現(xiàn)
//每個section下行數(shù)(必須實現(xiàn))
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
//通過indexpath返回cell的具體樣式和內(nèi)容(必須實現(xiàn))
//可以在這里對cell進行設置(*這里使用了可以重復利用 UITableViewCell 的機制*)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
@optional //其他的代理方法可選實現(xiàn):
//返回分組section數(shù)胡野,默認是1
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
/*
* 頭尾標題內(nèi)容(_字體樣式固定材失,可以通過UILable改變_)
*/
//返回每個section頭標題內(nèi)容
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;
//返回每個section尾部標題說明
-(NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section;
/*
* 索引相關
*/
//返回每個section標題索引(可以在這里設置索引)
-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView;
//點擊索引觸發(fā)(告訴tableView哪個section將會響應點擊的索引
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index;
/*
* 編輯相關
*/
//是否可編輯
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath;
// 是否可拖拽(使用代理方法`tableView:moveRowAtIndexPath:toIndexPath:`之前設置)
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath;
//插入/刪除指定數(shù)據(jù)(根據(jù)編輯風格`editingStyle`確定是插入還是刪除)
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;
//重新排序/移動數(shù)據(jù)操作
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath;
cell的編輯風格UITableViewCellEditingStyle是個結構體,共有三個元素:沒有風格硫豆、刪除龙巨、插入:
typedef NS_ENUM(NSInteger, UITableViewCellEditingStyle) {
UITableViewCellEditingStyleNone,
UITableViewCellEditingStyleDelete,
UITableViewCellEditingStyleInsert
};
二、UITableViewCell基本介紹
UITableViewCell的結構
從上圖中可以看到熊响,在UITableView中數(shù)據(jù)只有行的概念旨别,并沒有列的概念,其中每行數(shù)據(jù)都是一個UITableViewCell汗茄。下圖是UITableViewCell內(nèi)置好的控件秸弛,可以看見contentView控件作為父控件,里面包括兩個UILabel控件(textLabel,detailTextLabel),一個UIImage控件(imageView),一個AccessoryView,分別用于容器洪碳、顯示內(nèi)容递览、圖片和詳情(當然,這些子控件并不一定要全部使用):
UITableViewCell的示意圖為:
UITableViewCell的風格
UITableViewCell有四種風格偶宫,根據(jù)不同的分格非迹,各個控件會進行不同的分布。四種風格分別為:
typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
UITableViewCellStyleDefault, //左側顯示textLabel,不顯示detailTextLabel,imageView可選(顯示在最左邊)
UITableViewCellStyleValue1, //左側顯示textLabel,右側顯示detailTextLabel,imageView可選(顯示在最左邊)
UITableViewCellStyleValue2, //左側依次顯示textLabel和detailTextLabel,不顯示imageView
UITableViewCellStyleSubtitle //左上方顯示textLabel,左下方顯示detailTextLabel,imageView可選(顯示在最左邊)
};
UITableViewCellAccessoryType
UITableViewCell中還可顯示accessoryView(輔助指示視圖)纯趋,位于UITableViewCell的最右邊憎兽,accessaryView的樣式UITableViewCellAccessoryType有五種:
typedef NS_ENUM(NSInteger, UITableViewCellAccessoryType) {
UITableViewCellAccessoryNone, //沒有視圖
UITableViewCellAccessoryDisclosureIndicator, //箭頭
UITableViewCellAccessoryDetailButton //button
UITableViewCellAccessoryDetailDisclosureButton, //button和箭頭
UITableViewCellAccessoryCheckmark, //對勾
};
當然,我們也可以通過cell的accessoryView屬性來自定義輔助指示視圖(比如往右邊放一個開關)吵冒。
3纯命、自定義UITableViewCell加載:代碼&xib
代碼自定義
方法一:(使用重用機制alloc一個cell,IDENTIFIER作為重用機制查找的標識)
#define IDENTIFIER @"identifier"
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell* cell = nil;
//使用重用機制痹栖,IDENTIFIER作為重用機制查找的標識亿汞,tableview查找可用cell時通過IDENTIFIER檢索,如果有則cell不為nil
cell = [tableView dequeueReusableCellWithIdentifier:IDENTIFIER];
if (cell == nil) {
cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:IDENTIFIER];//代碼創(chuàng)建的cell需要使用該初始化方法
}
return cell;
}
==注意:以上方式要注意cell創(chuàng)建時的Identifier與tableview dequeueReusableCell時是一樣的揪阿。==
方法二:(首先在viewdidload中調用registerClass注冊cell)
#define IDENTIFIER @"identifier"
首先在viewdidload中注冊cell
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerClass:[TableViewCell class] forCellReuseIdentifier:IDENTIFIER];
}
// 然后在tableview的delegate中
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell* cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:IDENTIFIER];
//這里會發(fā)現(xiàn)疗我,cell一直都不是nil咆畏,不再需要創(chuàng)建
if (cell == nil) {
NSLog(@"cell create at row:%ld", (long)indexPath.row);
}
return cell;
}
==通過注冊cell類的方式,tableView dequeueReusableCellWithIdentifier 總是有值吴裤,即讓tableview自己加載旧找,不再需要手動創(chuàng)建cell,UICollectionViewCell也是類似麦牺。==
xib自定義
方法一:(代理方法中調用 loadNibNamed方法)
#define IDENTIFIER @"identifier"
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell* cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:IDENTIFIER];
if (cell == nil) {
cell = [[NSBundle mainBundle] loadNibNamed:@"TableViewCell" owner:nil options:nil].firstObject;
NSLog(@"cell create at row:%ld", (long)indexPath.row);//此處要使用loadnib方式钮蛛!
}
NSNumber* number = self.array[indexPath.row];
cell.textLabel.text = number.stringValue;
return cell;
}
==注意:TableviewCell為xib的名字,xib中的identifier必須與代碼中的IDENTIFIER定義相同剖膳。==
方法二:(首先在viewdidload中調用registerNib注冊cell)
#define IDENTIFIER @"identifier"
// 首先在viewdidload中注冊cell
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerNib:[UINib nibWithNibName:@"TableViewCell" bundle:nil] forCellReuseIdentifier:IDENTIFIER];
}
// 然后在tableview的delegate中
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell* cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:IDENTIFIER];
if (cell == nil) {
//這里會發(fā)現(xiàn)魏颓,cell一直都不是nil,不再需要創(chuàng)建
NSLog(@"cell create at row:%ld", (long)indexPath.row);
}
return cell;
}
==通過注冊cell類的方式吱晒,讓tableview自己加載甸饱,不再需要手動創(chuàng)建cell。==