UITableView 使用细节

引言:


# 一. 隐藏多余 cell

self.tableView.tableFooterView = [[UIView alloc] init];

# 二. 分割线相关


// 去掉整个 tableView 的分割线:
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;

// 去掉某一个行 cell 的分割线:
cell.separatorInset = UIEdgeInsetsMake(0, ScreenWidth, 0, 0);

// 分割线顶到头部
self.tableView.separatorInset = UIEdgeInsetsZero;
self.tableView.layoutMargins = UIEdgeInsetsZero;

// 分割线颜色
self.tableView.separatorColor = [UIColor redColor];

# 三. 隐藏滚动条

// 垂直方向
self.tableView.showsVerticalScrollIndicator = NO;

// 竖直方向
self.tableView.showsHorizontalScrollIndicator = NO;

# 四. cell点击效果

// 点击无样式
cell.selectionStyle = UITableViewCellSelectionStyleNone;

// 自定义点击样式 - view
cell.selectedBackgroundView = [[UIView alloc] init];
cell.selectedBackgroundView.backgroundColor = [UIColor yellowColor];

// 自定义点击样式 - image
cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"xxx"]];

// 右边辅助按钮样式
cell.accessoryType = UITableViewCellAccessoryDetailButton;

// 类似 button 点击闪烁效果
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
	[tableView deselectRowAtIndexPath:indexPath animated:NO];
}

# 五. TableView 自动布局

// TableviewCell 使用SB约束好, 根据大小自动布局
// 使用SB布局的Cell ,直接使用下面代码达到自动布局目的
self.tableView.estimatedRowHeight = 44;
self.tableView.rowHeight = UITableViewAutomaticDimension;

# 六. 自定义分区头

注意:自定义分区头,tableView 的样式使用Plain就可以。

  1. 自定义视图,继承自UITableViewHeaderFooterView
  2. 设置headerView 的行高:
self.orderTableView.sectionHeaderHeight = 42;
  1. 注册 headerView:
[self.tablView registerNib:[UINib nibWithNibName:NSStringFromClass([CustomHeaderView class]) bundle:nil] forHeaderFooterViewReuseIdentifier:@"header"];
  1. 实现代理方法:
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
	CustomHeaderView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"header"];
	headerView.titleL.text = self.orders[section][@"date"];
	return headerView;
}

# 七. 获取 TableView 可视区域


// 方式一
// 直接返回一个 UITableViewCell 的数组,对于自定义 cell 处理起来比较繁琐
self.tableView.visibleCells;

// 方式二
// 返回一个 NSIndexPath 的数组,可以使用 indexPath.row 去获取数据、获取 cell
self.tableView.indexPathsForVisibleRows;

// 方式三
// 改方法可使用在代理回调比较多的设计中
NSIndexPath *index = [[NSIndexPath alloc] init];
CGRect cellR = [self.tableView rectForRowAtIndexPath:index];
if ((self.tableView.contentOffset.y - cellR.origin.y) < self.tableView.lc_height ||
(cellR.origin.y - self.tableView.contentOffset.y) > self.tableView.lc_height) {
	NSLog(@"此时的 cell不在 tableview 的可视区域来了");
}

// 注意:1和2 在自动根据数据伸长的 cell 好像不太好用。

# 八. 禁止分区头跟随 TableView 滚动

// 滚动视图代理
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
	if (scrollView == self.tableView) {
		CGFloat headerHeight = 42;
		if ((scrollView.contentOffset.y <= headerHeight) && (scrollView.contentOffset.y >= 0)) {
			scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
		} else if (scrollView.contentOffset.y >= headerHeight) {
			scrollView.contentInset = UIEdgeInsetsMake(-headerHeight, 0, 0, 0);
		}
	}
}

# 九. 程序不执行代理方法

当网络请求后,设置reloadData来刷新表格时,有时会不执行代理方法。

如果设置-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView代理方法,并且返回值是根据请求结果来设置分区个数的话,数值有可能为0。

原因:

当返回的分区头个数0时,tableView 的其他代理方法都不会执行。 开发中要注意:分区个数为0的情况。


# 十. 滚到视图顶部

# 方法一

[self.tableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];

# 方法二

[self.tableView setContentOffset:CGPointMake(0,0) animated:NO];

# 方法三

注意: 要判断数据是否为空的情况。

// 滚到顶部
if (self.loanList.count != 0) {
	NSIndexPath *indexPat = [NSIndexPath indexPathForRow:0 inSection:0];
	[self.tableView scrollToRowAtIndexPath:indexPat atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}

# 十一. Cell点击事件响应延迟

# 问题描述:

当某个cell同时满足了以下三个条件(暂且给这个cell命名为cellX):

  1. cellX为第一个被点击的cell或cellX被点击前的cell点击事件也出现了延迟问题
  2. cellX的selectionStyle为UITableViewCellSelectionStyleNone;
  3. cell的点击响应事件不是[self.navigationController pushViewController:VC animated:YES];时,会出现事件响应延迟的问题,大概会延迟5到9秒左右。

当cellX不能同时满足上述三个条件时,不会出现响应延迟现象。

# 问题解决:

方法1: 不设置cellX的selectionStyle或设置cellX的selectionStyle设置为除UITableViewCellSelectionStyleNone的其他几种样式。

方法2: 不管设置cellX的selectionStyle为什么类型,只要在tableView的点击代理方法中添加[tableView deselectRowAtIndexPath:indexPath animated:NO];方法即可,代码如下:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    // 解决cell的点击延迟问题
    [tableView deselectRowAtIndexPath:indexPath animated:NO];
}