之前在UITableViewCell系列之(一)让你的cell支持二次编辑中说过,很早就想系统的写一篇关于UITableViewCell的文章,目的是总结一下自己在项目开发中用过的一些关于UITableViewCell的特殊用法。但是苦于最近很忙,零碎的时间不够用,没有时间停留在文章的脉络和排版上,只能把我所想写的文章拆开,以短篇的形式拿出来。如下是我所要说的视觉差滚动效果(即:滚动tableView时候,每一行的图片都会根据滚动方向和滚动距离的不同进行移动,给人一种图片在移动的视觉体验),由于下面gif图失真卡顿严重,真实效果大家可以参考demo,不喜欢按部就班地看步骤的同学,也可以直接看代码。
visionDiff.gif
备注:
demo中cell是用xib文件定义、布局的,而非代码的方式
注意事项:
1. cell的imageView的上、下边距要超出cell,不然tableView滚动的时候没有多余的部分显示。约束设置如下:
Snip20160730_1.png
2. 控制器不能使UITableViewController,只能是UIViewController的view上添加一个UITableView
3. demo中涉及到了坐标系转换的问题,不了解坐标系转换的可以参考如下两个方法的使用:
// - (CGRect)convertRect:(CGRect)rect toView:(nullable UIView *)view;
// 把以A视图为坐标系的rect1转换为以B视图为坐标系的rect2并返回rect2
CGRect rect2 = [A convertRect:rect1 toView:B];
// - (CGRect)convertRect:(CGRect)rect fromView:(nullable UIView *)view;
// 把以B视图为坐标系的frame1转换为以B视图为坐标系的frame2并返回frame2
CGRect frame2 = [A convertRect:frame1 fromView:B];
主要代码如下:
1. cell.m文件中
- (void)updateBackImageViewYForTableView:(UITableView *)tableView andView:(UIView *)view {
// 1.cell在view坐标系上的frame
CGRect frameOnView = [tableView convertRect:self.frame toView:view];
// 2.cell 和 view 的中心距离差
CGFloat distanceOfCenterY = CGRectGetHeight(view.frame) * 0.5 - CGRectGetMinY(frameOnView);
// 3.cell 和 backImageView的高度差
CGFloat distanceH = CGRectGetHeight(self.backImageView.frame) - CGRectGetHeight(self.frame);
// 4.计算图片Y值偏移量
CGFloat distanceWillMove = distanceOfCenterY / CGRectGetHeight(view.frame) * distanceH;
// 5.更新图片的Y值
CGRect backImageFrame = self.backImageView.frame;
backImageFrame.origin.y = distanceWillMove - distanceH * 0.5;
self.backImageView.frame = backImageFrame;
}
2. 控制器.m文件中
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// 1.获取当前屏幕上显示的所有的cell
NSArray *visibleCells = [self.tableView visibleCells];
for (WSTableViewCell *cell in visibleCells) {
// 2.更新cell的imageView的Y坐标值
[cell updateBackImageViewYForTableView:self.tableView andView:self.view];
}
}