TableView系列--知识点

变更记录

序号 | 录入时间 | 备注
— | — | — | —
1 | 2016-09-06 | 新建文章
2 | 2018-04-14 | 合并整理
3 | 2018-05-29 | 整理目录

TableViewCell知识重点

每个TableViewCell里带一个contentView,cell的textLabel和imageView都是加载在contentView里的,所以以后要在cell上添加控件最好在contentView上添加,以免不必要的错误。

contentView.png

创建自定义TableViewCell

  1. 首先调用cellForRowAtIndexPath方法,如果是加载nib可以在ViewDidLoad中先注册nib文件的cell:
1
2
UINib * nib = [UINib nibWithNibName:NSStringFromClass([MZTableViewCell class])  bundle:nil];
[self.tableView registerNib:nib forCellReuseIdentifier:@"mzCellNib"];
  1. 然后从缓存池里查找
1
2
static NSString *reuseID = @"mzCellNib";
MZTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseID];
  1. 如果storyboard中有cell的话,设置storyboard中cell的重用标识,在缓存池中也能找到:

storyboard设置cell.png

  1. 如果缓存池没有,storyboard里面也木有这样标识的cell的话就有两种方式来创建:

4.1 创建一个继承自UITableViewCell的子类,比MZTableViewCell

1
2
3
if (cell == nil) {
cell = [[MZTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseID];
}

4.2 也可以自己创建cell:从Nib里加载cell

1
2
3
4
if (cell == nil) {
//加载xib文件加载cell,方法放回的是一个数组,取最后一个对象
cell = [[[NSBundle mainBundle loadNibNamed:NSStringFromClass([MZTableViewCell class]) owner:nil options:nil] lastObject];
}

注 如果nib,storyboard和.m文件中同时存在自定义的cell的话,需要注意cell的重用标识和代码的执行顺序,这里贴一张UIView的生命周期:

viewLifeCycle.png

TableViewController注意点

  • TableViewController中自带了一个tableView,继承了代理和数据源协议。其中的self.viewself.tableView都指的是所自带的tableView。

  • TableViewController还有一个UIRefreshControl,可以用来实现下拉刷新的效果。

  • UIRefreshControl使用非常简单,但是必须是在UITableViewController子类使用,而不能在UIViewController子类中使用。例如CustomViewController继承自UIViewController,那么就不能使用UIRefreshControl

  • UIRefreshControl使用很简单,如下代码,RootTableViewController继承自UITableViewController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//RootTaleiewController.h 
@interface RootTableViewController:UITableViewController
{
}
@end
//RootTableViewController.m file
@interface RootTableViewController()

@end
@implementation RootTableViewController
//省略不相干代码

- (void)viewDidLoad
{
[super viewDidLoad];
//初始化UIRefreshControl
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged];
[self setRefreshControl:refreshControl];
}

解释一下下面的代码:

当用户向下下拉刷新的时候,refresh触发,这时候请求url链接中的内容。这里使用AFNetworking来解析,代码块中的内容就是解析成功之后,设置数据源self.tweets中的内容,然后刷新UITableView界面,然后向UIRefreshControl对象发送endRefreshing消息,停止UIRefreshControl的动画效果。如果失败的话,也要停止UIRefreshControl的动画效果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
- (void)refresh:(id)sender
{
NSURL *url = [NSURL URLWithString:@"http://search.twitter.com/search.json?q=ios%20development&rpp=100&include_entities=true&result_type=mixed/"];
// Initialize URL Request
NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:url];
// JSON Request Operation
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:urlRequest success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSArray *results = [(NSDictionary *)JSON objectForKey:@"results"];
if ([results count]) {
self.tweets = results;
// Reload Table View
[self.tableView reloadData];
// End Refreshing
[(UIRefreshControl *)sender endRefreshing];
}
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
// End Refreshing
[(UIRefreshControl *)sender endRefreshing];
}];
// Start Operation
[operation start];
}
@end

UITableView重要的API

1
2
3
4
5
6
7
8
9
@protocol UITableViewDelegate<NSObject, UIScrollViewDelegate>
@optional
// Display customization 这里是展示cell的时候的回调
- (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);
- (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);

设定高度(注意estimatedHeightForRowAtIndexPath方法)

1
2
3
4
5
6
7
8
9
// Variable height support
- (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);

Section的头尾

1
2
3
// Section header & footer information. Views are preferred over title should you decide to provide both
- (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

Selection选择事件

1
2
3
4
5
6
7
8
9
10
11
12
// 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);
- (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0);
- (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0);
// 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);

编辑状态

1
2
3
4
5
6
7
8
9
10
// 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;
- (nullable NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(3_0) __TVOS_PROHIBITED;
- (nullable NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED; // supercedes -tableView:titleForDeleteConfirmationButtonForRowAtIndexPath: if return value is non-nil
// 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;
// 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 __TVOS_PROHIBITED;
- (void)tableView:(UITableView*)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath __TVOS_PROHIBITED;

Calling sequence for reordering a row in a table view.png

上图中当tableView进入到edit模式的时候,tableView会去对当前可见的cell逐个调用dataSource的tableView:canMoveRowAtIndexPath:方法(此处官方给出的流程图有点儿问题),决定当前cell是否显示recordering控件,当开始进入拖动cell进行拖动的时候,每滑动过一个cell的时候,会去调用delegate的tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:方法,去判断当前划过的cell位置是否可以被替换,如果不行则给出建议的位置。当用户放手时本次reordering操作结束,调用dataSource中的tableView:moveRowAtIndexPath:toIndexPath:方法更新tableView对应的数据。

当tableView进入编辑模式以后,cell上面显示的delete还是insert除了跟cell的editStyle有关,还与 tableView的delegate的tableView:editingStyleForRowAtIndexPath:方法的返回值有关(在这里唠叨一句,其实delegate提供了很多改变cell属性的机会,如非必要,还是不要去实现这些方法,因为执行这些方法也造成一定的开销)。

delete和insert的流程如下苹果官方文档中给出的图所示:

Calling_sequence_for_inserting_or_deleting_rows_in_a_table_view.png
定义长按cell的copy和paste

1
2
3
4
  // Copy/Paste.  All three methods must be implemented by the delegate.
- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(5_0);
- (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);

设定cell的焦点

使用Apple TV遥控器控制屏幕上的用户界面 = =

1
2
3
4
5
// 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);

Data刷新 (刷新可见行,visibleCell,基于cell重用机制)

1
2
3
// 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.

行所对应的视图关系和坐标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@property (nonatomic, readonly) NSInteger numberOfSections;
- (NSInteger)numberOfRowsInSection:(NSInteger)section;
- (CGRect)rectForSection:(NSInteger)section; // includes header, footer and all rows
- (CGRect)rectForHeaderInSection:(NSInteger)section;
- (CGRect)rectForFooterInSection:(NSInteger)section;
- (CGRect)rectForRowAtIndexPath:(NSIndexPath *)indexPath;
- (nullable NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point; // returns nil if point is outside of any row in the table
- (nullable NSIndexPath *)indexPathForCell:(UITableViewCell *)cell; // returns nil if cell is not visible
- (nullable NSArray<NSIndexPath *> *)indexPathsForRowsInRect:(CGRect)rect; // returns nil if rect not valid
- (nullable __kindof UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath; // returns nil if cell is not visible or index path is out of range
@property (nonatomic, readonly) NSArray<__kindof UITableViewCell *> *visibleCells;
@property (nonatomic, readonly, nullable) NSArray<NSIndexPath *> *indexPathsForVisibleRows;
- (nullable UITableViewHeaderFooterView *)headerViewForSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);
- (nullable UITableViewHeaderFooterView *)footerViewForSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);

滚动列表到某一行或者临近行

1
2
- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated;
- (void)scrollToNearestSelectedRowAtScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated;

行的插入、删除、刷新

1
2
3
4
5
6
7
8
9
10
11
// Row insertion/deletion/reloading.
- (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);
- (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);
- (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath NS_AVAILABLE_IOS(5_0);

UITableView的一些特性总结

一、属性

  • dataSource —设置UITableViewDataSource的代理
  • delegate —设置UItableViewDelegate的代理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*当header、footer、cell的高度是固定值的话,用该方法直接设置表的高度,无需调用表的delegate方法设置它们的高度 eg:_table.rowHeight = 60 */  
/*sectionHeaderHeight、sectionFooterHeight、rowHeight -- 设置表头、尾、cell的高度
sectionIndexColor -- 设置sectionIndexTitle(表索引子母)的颜色 */

@property (nonatomic) NSInteger sectionIndexMinimumDisplayRowCount; // show special section index list on right when row count reaches this value. default is 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
估算元素的高度 // NS_AVAILABLE_IOS(7_0)
[objc] view plain copy
/*
连接文章 介绍了estimatedRowHeight的用的场景。(适用动态的cell.height的适配)
*/
理解iOS 8中的Self Sizing Cells和Dynamic Type
estimatedRowHeight --- 设置表格行的估算高度以改善性能
estimatedSectionHeaderHeight、estimatedSectionFooterHeight ----- 设置Section头和Section尾估算高度以改善性能

- (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);
separatorEffect -------- 表的分割线(毛玻璃效果)//默认的分割线的色调暗

效果图:

1
2
3
4
5
6
UIImageView *backImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"4.jpg"]]; 
self.myTableView.backgroundView = backImageView;
UIBlurEffect *blureffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
UIVibrancyEffect *vinb = [UIVibrancyEffect effectForBlurEffect:blureffect];
self.myTableView.separatorEffect = vinb;
//cell.backgroundColor = [UIColor clearColor];

二、方法

初始化方法:
  • initWithFrame:———–设置表的大小和位置
  • initWithFrame:style———设置表的大小,位置和样式(组,单一)
  • setEditing:———-表格进入编辑状态,无动画
  • setEditing: animated:———表格进入编辑状态,有动画
  • reloadData—————刷新整个表视图
  • reloadSectionIndexTitles——–刷新索引栏
  • numberOfSections———–获取当前所有的组
  • numberOfRowsInSection:———获取某个组有多少行
  • rectForSection:———-获取某个组的位置和大小
  • rectForHeaderInSection:———获取某个组的头标签的位置和大小
  • rectForFooterInSection:———–获取某个组的尾标签的位置和大小
  • rectForRowAtIndex:———–获取某一行的位置和大小
  • indexPathForRowAtPoint————-点击某一个点,判断是在哪一行上的信息。
  • indexPathForCell:————获取单元格的信息
  • indexPathsForRowsInRect:———在某个区域里会返回多个单元格信息
  • cellForRowAtIndexPath:————-通过单元格路径得到单元格
  • visibleCells———–返回所有可见的单元格
  • indexPathsForVisibleRows——–返回所有可见行的路径
  • headerViewForSection:——–设置头标签的视图
  • footerViewForSection;———-设置尾标签的视图
  • UITableViewHeaderFooterView的使用说明
1
2
- (nullable UITableViewHeaderFooterView *)headerViewForSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);  
- (nullable UITableViewHeaderFooterView *)footerViewForSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section  
{
static NSString *HeaderIdentifier = @"header";
//表头、尾UITableViewHeaderFooterView的重用机制
//CustomHeaderView *myHeader = [tableView dequeueReusableHeaderFooterViewWithIdentifier:HeaderIdentifier];
if(!myHeader) {
// [tableView registerClass:[CustomHeaderView class] forHeaderFooterViewReuseIdentifier:HeaderIdentifier];
myHeader = [[[NSBundle mainBundle] loadNibNamed:@"CustomHeaderView"
owner:self
options:nil] objectAtIndex:0];
}

[myHeader.btnSomething setTitle:@"-" forState:UIControlStateNormal];
[myHeader.lblSomething setText:[NSString stringWithFormat:@"Section: %d",section]];

return myHeader;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomHeaderView *theHeaderView = (CustomHeaderView*)[tableView <span style="color:#FF0000;">headerViewForSection</span>:indexPath.section];
NSLog(@"%@",theHeaderView);

[theHeaderView.lblSomething setAlpha:theHeaderView.lblSomething.alpha-0.1];
[theHeaderView.btnSomething setTitle:@"+" forState:UIControlStateNormal];
}

重用机制(2个)

dequeueReusableCellWithI dentifier:——— 获取重用队列里的cell单元格

1
2
3
/**< 使用这个方法之前必须是使用了registerNib:forCellReuseIdentifier:<span>或者</span>registerClass:forCellReuseIdentifier:方法注册了Cell 
*/
dequeueReusableHeaderFooterViewWithIdentifier -------获取重用队列里的UITableViewHeaderFooterView的单元格

注册一个包含指定标示符的cell or haderFooterView 的nib对象/类

1
2
3
4
5
- (void)registerNib:(nullable UINib *)nib forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(5_0);  
- (void)registerClass:(nullable Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);

- (void)registerNib:(nullable UINib *)nib forHeaderFooterViewReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);
- (void)registerClass:(nullable Class)aClass forHeaderFooterViewReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);

beginUpdatesendUpdates两个方法,是配合起来使用的,标记了一个tableView的动画块。分别代表动画的开始开始和结束。两者成对出现,可以嵌套使用。
一般,在添加,删除,选择 tableView中使用,并实现动画效果。在动画块内,不建议使用reloadData方法,如果使用,会影响动画。

调用范例

  • beginUpdates——–只添加或删除才会更新行数
  • endUpdates———添加或删除后会调用添加或删除方法时才会更新
  • insertSections:withRowAnimation:———–插入一个或多个组,并使用动画
  • insertRowsIndexPaths:withRowAnimation:——-插入一个或多个单元格,并使用动画
  • deleteSections:withRowAnimation:——–删除一个或多个组,并使用动画
  • deleteRowIndexPaths:withRowAnimation:——–删除一个或多个单元格,并使用动画
  • reloadSections:withRowAnimation:———更新一个或多个组,并使用动画
  • reloadRowIndexPaths:withRowAnimation:————-更新一个或多个单元格,并使用动画
  • moveSection:toSection:————-移动某个组到目标组位置
  • moveRowAtIndexPath:toIndexPath:———–移动个某个单元格到目标单元格位置
  • indexPathsForSelectedRow———-返回选择的一个单元格的路径
  • indexPathsForSelectedRows———返回选择的所有的单元格的路径
  • selectRowAtIndexPath:animation:scrollPosition———设置选中某个区域内的单元格
  • deselectRowAtIndexPath:animation:———-取消选中的单元格

UITableViewDataSource代理方法:

  • numberOfSectionsInTableView:————设置表格的组数
  • tableView:numberOfRowInSection:———-设置每个组有多少行
  • tableView:cellForRowAtIndexPath:———设置单元格显示的内容
  • tableView:titleForHeaderInSection:———设置组表的头标签视图
  • tableView:titleForFooterInSection:———–设置组表的尾标签视图
  • tableView:canEditRowAtIndexPath:———设置单元格是否可以编辑
  • tableView:canMoveRowAtIndexPath:——–设置单元格是否可以移动
  • tableView:sectionIndexTitleForTableView:atIndex:——-设置指定组的表的头标签文本
  • tableView:commitEditingStyle:forRowAtIndexPath:———-编辑单元格(添加,删除)
  • tableView:moveRowAtIndexPath:toIndexPath ——- 单元格移动
  • tableView:indentationLevelForRowAtIndexPath ——- 返回行层次的深度

1
2
3
4
5
6
7
/* 
- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [indexPath row];
}
*/
//NS_AVAILABLE_IOS(8_0)
  • tableView:editActionsForRowAtIndexPath —– 自定义左滑动的编辑功能样式(UITableViewRowAction)
  • tableView:titleForDeleteConfirmationButtonForRowAtIndexPath —— 改变默认左滑动出现的字样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
- (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;
}

UITableViewDelegate代理方法: (iOS8以上)

tableView:willDisplayFooterView:forSection:tableView:willDisplayHeaderView:forSection:可以正常被调用
在iOS7(iOS6没测试)上却没有被调用
原来iOS7必须同时实现了Header和Footer这个delegate才会被调用所以

1
2
3
4
5
6
7
8
9
10
11
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section  
{
return 0.f;
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *view = [UIView new];
view.backgroundColor = [UIColor clearColor];
return view;
}
  • tableView: willDisplayHeaderView: forSection: ——– 设置当前section头的样式
  • tableView: willDisplayCell:forRowAtIndexPath:———–设置当前的单元格
1
2
3
4
5
6
7
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 
{
cell.transform = CGAffineTransformMakeTranslation(320, 0);
[UIView animateWithDuration:indexPath.row*0.2 animations:^{
cell.transform = CGAffineTransformIdentity;
}];
}
  • tableView: heightForRowAtIndexPath:———–设置每行的高度
  • tableView:tableViewheightForHeaderInSection:———–设置组表的头标签高度
  • tableView:tableViewheightForFooterInSection:————-设置组表的尾标签高度
  • tableView: viewForHeaderInSection:———-自定义组表的头标签视图
  • tableView: viewForFooterInSection: ———-自定义组表的尾标签视图
  • tableView:accessoryButtonTappedForRowWithIndexPath:———–设置某个单元格上的右指向按钮的响应方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    UIImage *image= [ UIImage imageNamed:@"man" ];  
UIButton *button = [ UIButton buttonWithType:UIButtonTypeCustom ];
CGRect frame = CGRectMake( 0.0 , 0.0 , image.size.width , image.size.height );
button.frame = frame;
[button setBackgroundImage:image forState:UIControlStateNormal ];
button.backgroundColor = [UIColor clearColor ];
[button addTarget:self
action:@selector(accessoryButtonIsTapped:event:) forControlEvents:UIControlEventTouchUpInside];

- (void)accessoryButtonIsTapped:(id)sender event:(id)event{
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:currentTouchPosition];
if(indexPath != nil)
{
[self tableView:self.tableView accessoryButtonTappedForRowWithIndexPath:indexPath];
}
}
  • tableView:willSelectRowAtIndexPath:———–获取将要选择的单元格的路径
  • tableView:didSelectRowAtIndexPath:———–获取选中的单元格的响应事件
  • tableView: tableViewwillDeselectRowAtIndexPath:————获取将要未选中的单元格的路径
  • tableView:didDeselectRowAtIndexPath:———–获取未选中的单元格响应事件NS_AVAILABLE_IOS(9_0)
  • remembersLastFocusedIndexPath ——– 使用Apple TV遥控器控制屏幕上的用户界面
1
2
3
4
- (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);
  • cellLayoutMarginsFollowReadableWidth ——- 判断是否需要根据内容留有空白

参考博文

  1. UITableView学习笔记
文章作者: MichaelMao
文章链接: http://frizzlefur.com/2016/09/06/TableView%E7%B3%BB%E5%88%97--%E7%9F%A5%E8%AF%86%E7%82%B9/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 MMao
我要吐槽下