tableView的屬性
TableView的樣式
tablview 初始化,xib的定義
typedef NS_ENUM(NSInteger, UITableViewStyle) {
UITableViewStylePlain, // regular table view 標準的表視圖風格
UITableViewStyleGrouped // preferences style table view 有選擇樣式的分組的表視圖風格
};

)
scrollPosition參數決定定位的相對位置
self.tableView scrollToRowAtIndexPath:<#(nonnull NSIndexPath *)#> atScrollPosition:<#(UITableViewScrollPosition)#> animated:<#(BOOL)#>
typedef NS_ENUM(NSInteger, UITableViewScrollPosition) {
UITableViewScrollPositionNone, //同UITableViewScrollPositionTop
UITableViewScrollPositionTop, //定位完成后,將定位的行顯示在tableView的頂部
UITableViewScrollPositionMiddle, //定位完成后,將定位的行顯示在tableView的中間
UITableViewScrollPositionBottom //定位完成后,將定位的行顯示在tableView最下面
}; // scroll so row of interest is completely visible at top/center/bottom of view
行變化(插入、刪除、移動的動畫類型)
插入時的動畫效果:UITableViewRowAnimationFade
self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
typedef NS_ENUM(NSInteger, UITableViewRowAnimation) {
UITableViewRowAnimationFade, //淡入淡出
UITableViewRowAnimationRight, //從右滑入 // slide in from right (or out to right)
UITableViewRowAnimationLeft , //從左滑入
UITableViewRowAnimationTop, //從上滑入
UITableViewRowAnimationBottom, //從下滑入
UITableViewRowAnimationNone, //沒有動畫 // available in iOS 3.0
UITableViewRowAnimationMiddle, // available in iOS 3.2. attempts to keep cell centered in the space it will/did occupy
UITableViewRowAnimationAutomatic = 100 // 自動選擇合適的動畫// available in iOS 5.0. chooses an appropriate animation style for you
};
tableViewCell右滑時自定義添加多個按鈕
typedef NS_ENUM(NSInteger, UITableViewRowActionStyle) {
UITableViewRowActionStyleDefault = 0,
UITableViewRowActionStyleDestructive = UITableViewRowActionStyleDefault,
UITableViewRowActionStyleNormal

)
//設置可以編輯
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
//設置編輯操作:刪除
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleDelete;
}
//自定義按鈕
-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewRowAction *layTopRowAction1 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"刪除" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
NSLog(@"點擊了刪除");
[tableView setEditing:NO animated:YES];
}];
layTopRowAction1.backgroundColor = [UIColor redColor];
UITableViewRowAction *layTopRowAction2 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"置頂" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
NSLog(@"點擊了置頂");
[tableView setEditing:NO animated:YES];
}];
layTopRowAction2.backgroundColor = [UIColor greenColor];
UITableViewRowAction *layTopRowAction3 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"更多" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
NSLog(@"點擊了更多");
[tableView setEditing:NO animated:YES];
}];
layTopRowAction3.backgroundColor = [UIColor blueColor];
NSArray *arr = @[layTopRowAction1,layTopRowAction2,layTopRowAction3];
return arr;
}
自定義添加多個按鈕的方法
+ (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style title:(nullable NSString *)title handler:(void (^)(UITableViewRowAction *action, NSIndexPath *indexPath))handler; //加block
@property (nonatomic, readonly) UITableViewRowActionStyle style;
@property (nonatomic, copy, nullable) NSString *title;
@property (nonatomic, copy, nullable) UIColor *backgroundColor; default background color is dependent on style 默認背景顏色取決于系統
@property (nonatomic, copy, nullable) UIVisualEffect* backgroundEffect;
為視圖實現特殊效果(模糊)
UITableViewDelegate
通常都要為UITableView設置代理對象(delegate),以便在UITableView觸發一下事件時做出相應的處理,比如選中了某一行。凡是遵守了UITableViewDelegate協議的OC對象,都可以是UITableView的代理對象。

)
@optional UITableViewDelegate<NSObject, UIScrollViewDelegate>
自定義
cellForRowAtIndexPath與willDisplayCell的區別
cellForRowAtIndexPath是data source協議中一個必須實現的方法,willDisplayCell是delegate協議中一個可選的方法。
cellForRowAtIndexPath中創建一個可重用的cell實例,我們應該盡量快的返回創建的cell,對于數據的綁定之類的操作應該放到willDisplayCell中去處理;
willDisplayCell在cell 在tableview展示之前就會調用,此時cell實例已經生成,所以不能更改cell的結構,只能是改動cell上的UI的一些屬性(例如label的內容等)
// Display customization
# 將要展示cell/header/footer
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
//將要顯示指定索引處的單元格
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);
//將要顯示指定區的表頭視圖
- (void)tableView:(UITableView *)tableView willDisplayFooterView:(UIView *)view forSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);
//將要顯示指定區的表尾視圖
# 完成展示cell/header/footer
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath NS_AVAILABLE_IOS(6_0);
//完成顯示指定索引處的單元格
- (void)tableView:(UITableView *)tableView didEndDisplayingHeaderView:(UIView *)view forSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);
//完成顯示指定區的表頭視圖
- (void)tableView:(UITableView *)tableView didEndDisplayingFooterView:(UIView *)view forSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);
//完成顯示指定區的表視圖
可變高度支持
// Variable height support 可變高度支持
#每個cell、section-header、section-footer高度的返回(這里高度通過協議返回,是為了table能準確的定位出來要顯示的Cell-index,從而滿足UITableView的重用機制
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
//單元格行高
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
//指定區的表頭高度
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;
//指定區的表尾/頁腳高度
設置行高(估計值)
// Use the estimatedHeight methods to quickly calcuate guessed values which will allow for fast load times of the table.
// If these methods are implemented, the above -tableView:heightForXXX calls will be deferred until views are ready to be displayed, so more expensive logic can be placed there.
# 設置行高,頭視圖高度和尾視圖高度的估計值(對于高度可變的情況下,提高效率)
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(7_0);
//指定索引處的估算行高
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForHeaderInSection:(NSInteger)section NS_AVAILABLE_IOS(7_0);
//指定區估算的表頭/頁眉高度
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForFooterInSection:(NSInteger)section NS_AVAILABLE_IOS(7_0);
//指定區估算的表尾/頁腳高度
/*
self.tableView.rowHeight=UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight=44.0;
[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
在 cellforrow 里調用 [cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
要結合起來 我之前 用Storybord做cell自使用 就使用這個方法
*/
section組頭部以及尾部
// Section header & footer information. Views are preferred over title should you decide to provide both
#第section組頭部以及尾部顯示什么控件
- (nullable UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
// ——為指定區的頁眉定制視圖 custom view for header. will be adjusted to default or specified header height
- (nullable UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section;
//——為指定區的頁腳定制視圖 custom view for footer. will be adjusted to default or specified footer height
輔助
// Accessories (disclosures).
# 當cell的accessaryType為UITableViewCellAccessoryFetailDisclosureButton時,點擊accessaryView將會調用delegate的tableView:accessoryButtonTappedForRowWithIndexPath方法。否則只只是didSelectRowAtIndexPath; (accessaryView 輔助視圖)
- (UITableViewCellAccessoryType)tableView:(UITableView *)tableView accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath NS_DEPRECATED_IOS(2_0, 3_0);
//指定索引處的表格行的附件類型
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath;
//指定索引處的表格行的附件按鈕被輕擊時
組(高亮)
// Selection
// -tableView:shouldHighlightRowAtIndexPath: is called when a touch comes down on a row.
// Returning NO to that message halts the selection process and does not cause the currently selected row to lose its selected look while the touch is down.
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0);
//當前選中的row是否高亮
- (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0);
//指定row高亮
- (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0);
//通知委托表視圖的指定行不在高亮顯示,一般是點擊其他行的時候
cell選擇和取消選擇
#cell選擇和取消選擇
// Called before the user changes the selection. Return a new indexPath, or nil, to change the proposed selection.
- (nullable NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath;
//將要選擇指定索引處的表格行
- (nullable NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(3_0);
//將要取消選擇指定索引處的表格行
已經選擇匯總和已經取消選擇選中后調用的函數
// Called after the user changes the selection.
已經選擇匯總和已經取消選擇選中后調用的函數
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
//已經選擇指定索引處的表格行
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(3_0);
//已經取消選擇指定索引處的表格行
編輯
// Editing
// Allows customization of the editingStyle for a particular cell located at 'indexPath'. If not implemented, all editable cells will have UITableViewCellEditingStyleDelete set for them when the table has editing property set to YES.
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath;
typedef NS_ENUM(NSInteger, UITableViewCellEditingStyle) {
UITableViewCellEditingStyleNone,
UITableViewCellEditingStyleDelete, //刪除樣式
UITableViewCellEditingStyleInsert //插入樣式
};
//返回指定索引位置表格行的編輯風格/樣式
- (nullable NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(3_0);
//返回指定索引處表格行上刪除確認按鈕上的標題文字
- (nullable NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(8_0);
//指定索引行的表格行的編輯操作,返回 UITableViewRowAction對象組成的數組 supercedes(推遲,取代,接下來) -tableView:titleForDeleteConfirmationButtonForRowAtIndexPath: if return value is non-nil
// 8.0后側滑菜單的新接口,支持多個側滑按鈕。
行縮進
// Controls whether the background is indented while editing. If not implemented, the default is YES. This is unrelated to the indentation level below. This method only applies to grouped style table views.
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath;
//判斷當編輯指定索引處的表格行時是否將要 indent(縮進,訂貨),默認所有的表格行編輯狀態時都會縮進,只對grouped的TableView有效
或者cell.shouldIndentWhileEditing = NO;
開始與完成編輯
// The willBegin/didEnd methods are called whenever the 'editing' property is automatically changed by the table (allowing insert/delete/move). This is done by a swipe activating a single row
- (void)tableView:(UITableView*)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath;
//將要開始編輯指定索引處的表格行
- (void)tableView:(UITableView*)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath;
//指定索引處的表格行編輯完成
移動
// Moving/reordering
// Allows customization of the target row for a particular row as it is being moved/reordered
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath;
// 移動特定的某行(注意區別之前的tableView:moveRowAtIndexPath:toIndexPath方法。當手指按住reorde accessory view移動時,只要有row moved/reordered都會調用該方法,而前者方法只有當手指放開reorder accessory view時,結束move/order操作才會調用自己。返回值代表進行移動操作后回到的行,如果設置為當前行,則不論怎么移動都會回到當前行
NSInteger類型的值——縮進水平
// Indentation
- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath;
//返回NSInteger類型的值——縮進水平 return 'depth' of row for hierarchies
彈出選擇菜單時會調用此方法(BOOL) 選擇菜單項完成之后調用此方法(void)
// Copy/Paste. All three methods must be implemented by the delegate.
- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(5_0);
//長按出來的Copy/Paste操作 (復制粘貼)----->通知委托是否在指定行顯示菜單,返回值為YES時,長按顯示菜單
- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender NS_AVAILABLE_IOS(5_0);
//彈出選擇菜單時會調用此方法(復制、粘貼、全選、剪切)
- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender NS_AVAILABLE_IOS(5_0);
//選擇菜單項完成之后調用此方法
Focus 焦點
// Focus 焦點
- (BOOL)tableView:(UITableView *)tableView canFocusRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(9_0);
- (BOOL)tableView:(UITableView *)tableView shouldUpdateFocusInContext:(UITableViewFocusUpdateContext *)context NS_AVAILABLE_IOS(9_0);
- (void)tableView:(UITableView *)tableView didUpdateFocusInContext:(UITableViewFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator NS_AVAILABLE_IOS(9_0);
- (nullable NSIndexPath *)indexPathForPreferredFocusedViewInTableView:(UITableView *)tableView NS_AVAILABLE_IOS(9_0);
UITableView : UIScrollView <NSCoding>
繼承于UIscrollView ->有scrollView的屬性
scrollView
tableView 初始化 基本屬性
- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style NS_DESIGNATED_INITIALIZER; // must specify style at creation. -initWithFrame: calls this with UITableViewStylePlain
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;
@property (nonatomic, readonly) UITableViewStyle style;
//tableView 的樣式
@property (nonatomic, weak, nullable) id <UITableViewDataSource> dataSource;
@property (nonatomic, weak, nullable) id <UITableViewDelegate> delegate;
@property (nonatomic) CGFloat rowHeight; // will return the default value if unset 行高
@property (nonatomic) CGFloat sectionHeaderHeight; // will return the default value if unset 組頭的高度
@property (nonatomic) CGFloat sectionFooterHeight; // will return the default value if unset 組尾的高度
@property (nonatomic) CGFloat estimatedRowHeight NS_AVAILABLE_IOS(7_0); // default is 0, which means there is no estimate 估算行高,默認0
@property (nonatomic) CGFloat estimatedSectionHeaderHeight NS_AVAILABLE_IOS(7_0); // default is 0, which means there is no estimate 估算組頭的高度
@property (nonatomic) CGFloat estimatedSectionFooterHeight NS_AVAILABLE_IOS(7_0); // default is 0, which means there is no estimate 估算組尾的高度
@property (nonatomic) UIEdgeInsets separatorInset NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR; // allows customization of the frame of cell separators 允許更改分割線的frame
//UIEdgeInsets:CGFloat top, left, bottom, right; // specify amount to inset (positive) for each of the edges. values can be negative to 'outset'
@property (nonatomic, strong, nullable) UIView *backgroundView NS_AVAILABLE_IOS(3_2); // the background view will be automatically resized to track the size of the table view. this will be placed as a subview of the table view behind all cells and headers/footers. default may be non-nil for some devices. 背景視圖(自動匹配tableView視圖大小),設置互作為列表視圖的子視圖,切在所有cell和headers/footers的后面,默認為nil
Data 數據的刷新
- (void)reloadData; // reloads everything from scratch. redisplays visible rows. because we only keep info about visible rows, this is cheap. will adjust offset if table shrinks 刷新列表
- (void)reloadSectionIndexTitles NS_AVAILABLE_IOS(3_0); // reloads the index bar. 刷新你section這個方法常用語新加或者刪除了索引類別二無需率先呢整個表視圖的情況下
##
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation NS_AVAILABLE_IOS(3_0); // 刷新某些組
3
Info 信息
@property (nonatomic, readonly) NSInteger numberOfSections; // 列表的組數
- (NSInteger)numberOfRowsInSection:(NSInteger)section; // 某一組有多少行
- (CGRect)rectForSection:(NSInteger)section; // includes header, footer and all rows 某一組所占的矩形區域(包括header,footer和所有的行)
- (CGRect)rectForHeaderInSection:(NSInteger)section; // 某一組的header所占的矩形區域
- (CGRect)rectForFooterInSection:(NSInteger)section; // 某一組的footer所占的矩形區域
- (CGRect)rectForRowAtIndexPath:(NSIndexPath *)indexPath; // 某一分區的row所占的矩形區域
- (nullable NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point; // returns nil if point is outside of any row in the table 某一點在tableView上所占的分區,如果該點不在tableView的任何row上返回nil
- (nullable NSIndexPath *)indexPathForCell:(UITableViewCell *)cell; // returns nil if cell is not visible 某一行所在的分區,如果改行是不可見的返回nil
- (nullable NSArray<NSIndexPath *> *)indexPathsForRowsInRect:(CGRect)rect; // returns nil if rect not valid 某一矩形區域內所有行所在的所有分區,返回元素為NSIndexPath類型的數組。當該矩形是一個無效值時,返回nil
- (nullable __kindof UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath; // returns nil if cell is not visible or index path is out of range 某一分區的cell沒如果改cell是不可見的或者indexPath超出了返回則返回nil
@property (nonatomic, readonly) NSArray<__kindof UITableViewCell *> *visibleCells; // 所有可見的cell,只讀數組型(數組類型為UITableViewCell)
@property (nonatomic, readonly, nullable) NSArray<NSIndexPath *> *indexPathsForVisibleRows; // 所有可見行所在的分區,只讀數組型(NSIndexPath)
- (nullable UITableViewHeaderFooterView *)headerViewForSection:(NSInteger)section NS_AVAILABLE_IOS(6_0); // 某一組的header視圖(常用語自定義headerView用)
- (nullable UITableViewHeaderFooterView *)footerViewForSection:(NSInteger)section NS_AVAILABLE_IOS(6_0); // 某一組的footer視圖(常用語自定義footerView用)
- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated; //使表視圖定位到某一位置(行)
- (void)scrollToNearestSelectedRowAtScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated; // 使表視圖定位到選中行
Row insertion/deletion/reloading. 插入 刪除 刷新
// 這兩個方法,是配合起來使用的,標記了一個tableView的動畫快。分別代表動畫的開始和結束。兩者成對出現,可以嵌套使用。一般,在添加,刪除,選擇tableView中使用,并實現動畫效果。在動畫快內,不建議使用reloadData方法,如果使用,會影響動畫
- (void)beginUpdates; // allow multiple insert/delete of rows and sections to be animated simultaneously. Nestable 允許多個插入/行和段被同時刪除動畫。可排序
- (void)endUpdates; // only call insert/delete/reload calls or change the editing state inside an update block. otherwise things like row count, etc. may be invalid. 只調用插入/刪除/重載呼叫或改變一更新區塊內的編輯狀態。然而對于行數等屬性可能是無效的
- (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation; // 插入某些組
- (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation; // 刪除某些組
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation NS_AVAILABLE_IOS(3_0); // 刷新某些組
- (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection NS_AVAILABLE_IOS(5_0); // 一定組section到組newSection的位置
- (void)insertRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation; // 插入某些行
- (void)deleteRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation; // 刪除某些行
- (void)reloadRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation NS_AVAILABLE_IOS(3_0); // 刷新tableView指定行的數據
- (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath NS_AVAILABLE_IOS(5_0); // 移動分區indexPath的行到分區newIndexPath
Editing 編輯
/ Editing. When set, rows show insert/delete/reorder controls based on data source queries 編輯、設置之后,行的顯示會基于數據源查詢插入/刪除/重排序的控制
@property (nonatomic, getter=isEditing) BOOL editing; // default is NO. setting is not animated. // 設置是否是編輯狀態(編輯狀態下的cell左邊會出現一個減號,編輯右邊會劃出刪除按鈕)
- (void)setEditing:(BOOL)editing animated:(BOOL)animated;
@property (nonatomic) BOOL allowsSelection NS_AVAILABLE_IOS(3_0); // default is YES. Controls whether rows can be selected when not in editing mode 當不再編輯模式時,是否可以選中,默認YES
@property (nonatomic) BOOL allowsSelectionDuringEditing; // default is NO. Controls whether rows can be selected when in editing mode 當處在編輯模式時,是否可以選中。默認NO
@property (nonatomic) BOOL allowsMultipleSelection NS_AVAILABLE_IOS(5_0); // default is NO. Controls whether multiple rows can be selected simultaneously 是否可以同時選中。默認NO
@property (nonatomic) BOOL allowsMultipleSelectionDuringEditing NS_AVAILABLE_IOS(5_0); // default is NO. Controls whether multiple rows can be selected simultaneously in editing mode 當處在編輯模式時,是否可以同時選中。默認NO
Selection 選中
@property (nonatomic, readonly, nullable) NSIndexPath *indexPathForSelectedRow; // returns nil or index path representing section and row of selection. 選中的行所在的分區(單選)
@property (nonatomic, readonly, nullable) NSArray<NSIndexPath *> *indexPathsForSelectedRows NS_AVAILABLE_IOS(5_0); // returns nil or a set of index paths representing the sections and rows of the selection. 選中的行所在的所有分區(多選)
// Selects and deselects rows. These methods will not call the delegate methods (-tableView:willSelectRowAtIndexPath: or tableView:didSelectRowAtIndexPath:), nor will it send out a notification. 代碼收到選中與取消選中某行,注意:這兩個方法將不會回調代理中的方法
- (void)selectRowAtIndexPath:(nullable NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scrollPosition;
- (void)deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated;
Appearance 外觀
@property (nonatomic) NSInteger sectionIndexMinimumDisplayRowCount; // show special section index list on right when row count reaches this value. default is 0 設置索引欄最小顯示行數。先在右側專門章節索引列表當行數達到此值。默認值是0
@property (nonatomic, strong, nullable) UIColor *sectionIndexColor NS_AVAILABLE_IOS(6_0) UI_APPEARANCE_SELECTOR; // color used for text of the section index 設置索引欄字體顏色
@property (nonatomic, strong, nullable) UIColor *sectionIndexBackgroundColor NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR; // the background color of the section index while not being touched 設置索引欄背景顏色
@property (nonatomic, strong, nullable) UIColor *sectionIndexTrackingBackgroundColor NS_AVAILABLE_IOS(6_0) UI_APPEARANCE_SELECTOR; // the background color of the section index while it is being touched 設置索引欄被選中時的顏色
@property (nonatomic) UITableViewCellSeparatorStyle separatorStyle __TVOS_PROHIBITED; // default is UITableViewCellSeparatorStyleSingleLine 設置分割線的風格
typedef NS_ENUM(NSInteger, UITableViewCellSeparatorStyle) {
UITableViewCellSeparatorStyleNone,
UITableViewCellSeparatorStyleSingleLine,
UITableViewCellSeparatorStyleSingleLineEtched // This separator style is only supported for grouped style table views currently
} __TVOS_PROHIBITED;
@property (nonatomic, strong, nullable) UIColor *separatorColor UI_APPEARANCE_SELECTOR __TVOS_PROHIBITED; // default is the standard separator gray 設置分割線顏色
@property (nonatomic, copy, nullable) UIVisualEffect *separatorEffect NS_AVAILABLE_IOS(8_0) UI_APPEARANCE_SELECTOR __TVOS_PROHIBITED; // effect to apply to table separators 設置分割線毛玻璃效果(iOS8之后可用)
@property (nonatomic) BOOL cellLayoutMarginsFollowReadableWidth NS_AVAILABLE_IOS(9_0); // if cell margins are derived from the width of the readableContentGuide.
@property (nonatomic, strong, nullable) UIView *tableHeaderView; // accessory view for above row content. default is nil. not to be confused with section header 設置tableView頭視圖
@property (nonatomic, strong, nullable) UIView *tableFooterView; // accessory view below content. default is nil. not to be confused with section footer 設置tableView尾視圖
- (nullable __kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier; // Used by the delegate to acquire an already allocated cell, in lieu of allocating a new one. 從復用池張取cell
- (__kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0); // newer dequeue method guarantees a cell is returned and resized properly, assuming identifier is registered 獲取一個已注冊的cell
- (nullable __kindof UITableViewHeaderFooterView *)dequeueReusableHeaderFooterViewWithIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0); // like dequeueReusableCellWithIdentifier:, but for headers/footers 從復用池獲取頭視圖或尾視圖
注冊cell
// Beginning in iOS 6, clients can register a nib or class for each cell.
// If all reuse identifiers are registered, use the newer -dequeueReusableCellWithIdentifier:forIndexPath: to guarantee that a cell instance is returned.
// Instances returned from the new dequeue method will also be properly sized when they are returned.
- (void)registerNib:(nullable UINib *)nib forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(5_0); // 通過xib文件注冊cell
- (void)registerClass:(nullable Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0); // 通過oc類注冊cell
- (void)registerNib:(nullable UINib *)nib forHeaderFooterViewReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0); // 通過xib文件注冊頭視圖和尾視圖
- (void)registerClass:(nullable Class)aClass forHeaderFooterViewReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0); // 通過OC類注冊頭視圖和尾視圖
Focus 焦點
@property (nonatomic) BOOL remembersLastFocusedIndexPath NS_AVAILABLE_IOS(9_0); // defaults to NO. If YES, when focusing on a table view the last focused index path is focused automatically. If the table view has never been focused, then the preferred focused index path is used.
UITableViewDataSourceUITableView
需要一個數據源(dataSource)來顯示數據,UITableView會向數據源查詢一共有多少行數據以及每一行顯示什么數據等。沒有設置數據源的UITableView只是個空殼。凡是遵守UITableViewDataSource協議的OC對象,都可以是UITableView的數據源。
@protocol UITableViewDataSource<NSObject>
![
)
必須實現的
@required
// 每個section下cell的個數(必須實現)
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
// 通過Indexpath返回具體的cell(必須實現)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
協議
返回有多少個section(默認是1)
// 返回有多少個section(默認是1)
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; // Default is 1 if not implemented
每個section上面的標語內容
// 每個section上面的標語內容
- (nullable NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section; // fixed font style. use custom view (UILabel) if you want something different
// 每個section下面的標語內容
- (nullable NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section;
// Editing
// 是否可編輯
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath;
// Moving/reordering
// Allows the reorder accessory view to optionally be shown for a particular row. By default, the reorder control will be shown only if the datasource implements -tableView:moveRowAtIndexPath:toIndexPath:
// 是否可拖拽
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath;
// Index
// 右側索引條需要的數組內容
- (nullable NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView __TVOS_PROHIBITED; // return list of section titles to display in section index view (e.g. "ABCD...Z#")
// 索引值對應的section-index
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index __TVOS_PROHIBITED; // tell table which section corresponds to section title/index (e.g. "B",1))
// Data manipulation - insert and delete support
// After a row has the minus or plus button invoked (based on the UITableViewCellEditingStyle for the cell), the dataSource must commit the change
// Not called for edit actions using UITableViewRowAction - the action's handler will be invoked instead
// 對Cell編輯后的回調
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;
// Data manipulation - reorder / moving support
// 對Cell拖拽后的回調
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath;
UITableViewDataSourcePrefetching(ios 10.0)
@required
// indexPaths are ordered ascending by geometric distance from the table view
- (void)tableView:(UITableView *)tableView prefetchRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
@optional
// indexPaths that previously were considered as candidates for pre-fetching, but were not actually used; may be a subset of the previous call to -tableView:prefetchRowsAtIndexPaths:
- (void)tableView:(UITableView *)tableView cancelPrefetchingForRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
類方法
// 類方法
+ (instancetype)indexPathForRow:(NSInteger)row inSection:(NSInteger)section;
@property (nonatomic, readonly) NSInteger section; // indexPath的組
@property (nonatomic, readonly) NSInteger row; // indexPath的行
補充
/*
----dataSource/delegate方法大概執行順序(所有方法均實現):
1).numberOfSectionsInTableView;有多少section,例如k;
2).tableView:estimatedHeightForHeaderInSection + tableView:estimatedHeightForFooterInSection;計算k-1 section的header、footer大概高度;
3).tableView:numberOfRowsInSection;k-1 section有多少 row;
4).tableView:estimatedHeightForRowAtIndexPath;計算k-1 section中所有row的大概高度;
5).重復1)~4)步驟,直到所有0至k-1的section計算完;
6).sectionIndexTitlesForTableView;索引titles;
7).tableView:heightForRowAtIndexPath;依次計算visible區域(屏幕區域)里每個cell的高度(這里的所有cell記做集合A,決定于屏幕高度和estimatedHeightForXXX方法)
8).tableView:cellForRowAtIndexPath;創建第一個indexPath上的cell
9).tableView:indentationLevelForRowAtIndexPath; indexPath上的cell的縮進;
10).tableView:canEditRowAtIndexPath; indexPath上的cell編輯屬性;
11).tableView:willDisplayCell:forRowAtIndexPath; indexPath上的cell將要顯示;
12),重復8)~11),直到所有visible區域cell(集合A)創建完畢;
13).tableView:heightForHeaderInSection + tableView:heightForFooterInSection + tableView:viewForHeaderInSection + tableView:viewForHeaderInSection;依次計算visible區域里所有section 的header高度、footer高度、viewForHead、viewForFooter;
----執行順序(沒有實現estimatedHeight這些方法):
1).numberOfSectionsInTableView;有多少section,例如k;
2).tableView:heightForHeaderInSection + tableView:heightForFooterInSection;計算k-1 section的header、footer高度;
3).tableView:numberOfRowsInSection;k-1 section有多少 row;
4).tableView:heightForRowAtIndexPath;計算k-1 section中所有row得高度;
5).重復1)~4)步驟,直到所有0至k-1的section計算完
6).sectionIndexTitlesForTableView;索引titles;
7).tableView:cellForRowAtIndexPath;創建第一個indexPath上的cell
8).tableView:indentationLevelForRowAtIndexPath; indexPath上的cell的縮進;
9).tableView:canEditRowAtIndexPath; indexPath上的cell編輯屬性;
10).tableView:willDisplayCell:forRowAtIndexPath; indexPath上的cell將要顯示;
12).重復7)~12),知道所有visible區域(屏幕)cell創建完畢;
13).tableView:viewForHeaderInSection + tableView:viewForHeaderInSection;依次計算visible區域里所有的viewForHead、viewForFooter;
備注:
1.由上可看出,estimatedHeight在加載tableview的時候代替了heightFor方法,heightFor方法只有當cell需要顯示的時候,才會調用。
2.關于estimatedHeightForXXX相關方法,里面的返回值并不能隨意填寫的,應該是真實高度的大概值;因為在加載tableview的時候,當所有的section header/footer row的高度都大概計算完,開始計算高度、并創建visible區域的cell時候,這些cell屬不屬于visible區域的判斷依據就是之前的estimatedHeightForXXX方法返回的值算出來的;例如estimatedHeightForXXX相關方法返回值過大,算出來當前visible(屏幕)區域,包含3個section header 、footer以及里面的row,所以實際創建的時候也是創建這些cell(參考上文中方法執行順序),當這些cell創建完,實際情況高度(heightForXXX方法所得)可能只占visible(屏幕)區域的一半,導致屏幕另一半空白。注意visible區域初始顯示的cell是由estimatedHeightForXXX相關方法決定的,而不是heightForXXX這些方法真實高度決定的,所以有時tableview中visible區域尾部cell顯示不出來或者創建的cell比visible區域cell多,都是estimatedHeightForXXX和heightForXXX方法相差導致的原因。
3.以上方法和ViewController那些方法關系:先執行viewdidload、willAppear等相關方法,再執行numberOfSectionsInTableView系列方法。
*/
詳談屬性設置readwrite、readonly、retain、copy、assign、nonatomic
copy、retain、weak、assign
非ARC
? 1> copy : 只用于NSString\block
? 2> retain : 除NSString\block以外的OC對象
? 3> assign : 基本數據類型、枚舉、結構體(非OC對象),當2個對象相互引用,一端用retain,一端用assign
?2.ARC
? 1> copy : 只用于NSString\block
? 2> strong : 除NSString\block以外的OC對象
? 3> weak : 當2個對象相互引用,一端用strong,一端用weak
4> assgin : 基本數據類型、枚舉、結構體(非OC對象)
atomic,nonatomic
?1.atomic:設置成員變量的@property屬性時,默認為atomic,提供多線程安全。
?2.nonatomic:禁止多線程,變量保護,提高性能。
atomic是Objc使用的一種線程保護技術,基本上來講,是防止在寫未完成的時候被另外一個線程讀取,造成數據錯誤。而這種機制是耗費系統資源的,所以在iPhone這種小型設備上,如果沒有使用多線程間的通訊編程,那么nonatomic是一個非常好的選擇。
__nonnull、nonnull
他們的作用是...
修飾一個屬性的值,或者參數不能為空...
使用的方法和nullable一樣
區別
1 . 可讀性: readonly、readwrite
@property(readwrite,....) valueType value;
這個屬性是變量的默認屬性,就是如果你 (readwrite and readonly 都沒有使用,那么你的變量就是 readwrite屬性 ) ,通過加入 readwrite 屬性你的變量就會有 get 和 set 方法。
property(readonly,...) valueType value;
這個屬性變量就是表明變量只有可讀方法,也就是說,你只能使用它的 get 方法。
2 . assign , setter 方法直接賦值,不進行任何 retain 操作,為了解決原類型與環循引用問題
3 . retain , setter 方法對參數進行 release 舊值再 retain 新值,所有實現都是這個順序
4 . copy ,setter 方法進行 Copy 操作,與 retain 處理流程一樣,先舊值 release ,再 copy 出新的對象,retainCount 為 1 。這是為了減少對上下文的依賴而引入的機制。
5 .nonatomic ,非原子性訪問,不加同步,多線程并發訪問會提高性能。
注意,如果不加此屬性,則默認是兩個訪問方法都為原子型事務訪問。鎖被加到所屬對象實例級 。 所以不加nonatomic 對與多線程是安全的 。
6 . retain vs. Copy
copy :建立一個索引計數為 1 的對象,然后釋放舊對象
retain :釋放舊的對象,將舊對象的值賦予輸入對象,再提高輸入對象的索引計數為 1
那上面的是什么該死的意思呢?
copy 其實是建立了一個相同的對象,而 retain 不是
修改readonly的屬性
修飾詞
1getter=isOn
問題:
@property(nonatomic,getter=isOn) BOOL on; 中的getter = isOn的含義?
2 答案:
如果這個property是 BOOL on, 那么Objc默認創建的 setter 為: - (void)on:(BOOL)setOn { } getter 為: - (BOOL)on { return on; } 但是你可以手動更改 setter 和 getter 方法,就像上面的: getter = xxxOn 的話, getter 就變為: - (BOOL)xxxOn { return on; }
- (nullable NSArray<NSString *> *) (__kindof UITableViewCell *)
__kindof關鍵字的好處在于更加明確了以前id類型無法清晰表達的短板
- (__kindof UITableViewCell *)
表明方法返回的是UITableViewCell或其子類型,比以前的id類型更清晰,更明確。
對了,強制類型轉換,泛型也涉及到強制類型轉換問題,NSArray<__covariant ObjectType>,其中__covariant關鍵字就是表達可以 stringArray = mutStringArray,假如這樣定義數組NSArray<ObjectType>,那stringArray = mutStringArray也會有警告(可以自定義類實現泛型驗證),與__covariant對應的是__contravariant,如果這樣定義數組NSArray<__contravariant ObjectType>,那么mutStringArray = stringArray;也不會有警告了,但這明顯不合理。關于__covariant與__contravariant就不翻譯了(有時候翻譯真不如英文原版)
注1:參考NSDictionary頭文件定義,來思考多參數泛型實現。
- (nullable NSArray<NSString *> *) (__kindof UITableViewCell *)
UITableView的數據源(dataSource)和代理(delegate)
UITableView需要一個數據源(dataSource)來顯示數據,UITableView會向數據源查詢一共有多少行數據以及每一行顯示什么數據等。沒有設置數據源的UITableView只是個空殼。凡是遵守UITableViewDataSource協議的OC對象,都可以是UITableView的數據源。
通常都要為UITableView設置代理對象(delegate),以便在UITableView觸發一下事件時做出相應的處理,比如選中了某一行。凡是遵守了UITableViewDelegate協議的OC對象,都可以是UITableView的代理對象。一般會讓控制器充當UITableView的dataSource和delegate
刪除選中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];
}