所谓的视觉差就是TableView在滚动的时候,可见的Cell都处于滑动状态,但是偏移量各不同,从而达到的一种视觉效果。
由于上传图片有大小要求,所以质量会有点问题!
OK,如何完成的?
恩,原理就这样子
默认显示的时候
<br />
向下滑动的时候
<br />
向上滑动的时候
通过上面三个图就知道,要在滚动TableView的时候计算图片的Y值,来达到移动的效果。
计算代码以及注释
- (void)cellOnTableView:(UITableView *)tableView didScrollView:(UIView *)view{
//将cell的frame转换成View的Frame
CGRect rect = [tableView convertRect:self.frame toView:view];
//视图的Frame的一半 减去 所看到的每个Cell的Y(获取滚动的值)
//以屏幕中心为0 获取能看到每个cell离中心点的值
float distanceCenter = CGRectGetHeight(view.frame)*0.5 - CGRectGetMinY(rect);
//图片的高度 - cell的高度 = 图片超出cell的高度部分
float difference = CGRectGetHeight(self.backImage.frame) - CGRectGetHeight(self.frame);
float imageMove = (distanceCenter / CGRectGetHeight(view.frame)) * difference;
//旧的图片Frame
CGRect imageRect = self.backImage.frame;
//计算新的Y值
imageRect.origin.y = imageMove - (difference *0.5);
//赋值
self.backImage.frame = imageRect;
}
<br />
调用
//滚动监听
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
// 获取表视图的可见单元格。(可见的视图)
NSArray *visibleCells = [self.tableview visibleCells];
for (Cell *cell in visibleCells) {
//可见视图设置->背景图片y值
[cell cellOnTableView:self.tableview didScrollView:self.view];
}
}
<br />
然后到这里就可以运行跑起来看效果了,嗯,确实实现了效果,但是先看下内存吧。
下面的图片均运行在真机上
<br />
80+M貌似没多大问题,并且我这里选的也是比较大的图片,这里只加载了10张图片,但是如果图片过多,第一次滑动会卡,不流畅。
于是考虑优化内存,先奉上优化后的,当然我这里只是做一个思路,当然会有更好的解决方案,如果您有更好的解决方案,麻烦留言告知。
在上面的情况下都是10张图片,但是内存消耗却少了很多,少了80M左右,这个优化还是值得去做的。
因为数据源加载的是图片,又因为数据源是强引用,常驻内存,所以从图片入手。
在手机上显示图片,完全不用显示原尺寸,所以我的解决思路就是压缩图片,同时在界面上又基本上看不出来区别。
OK,现在要做的就是压缩图片。
<br />
做法就是根据屏幕的高度,然后在用图片的宽高比去压缩。
+(UIImage * _Nullable)imageCompressForWidth:(UIImage * _Nonnull)sourceImage targetWidth:(CGFloat)defineWidth{
//根据原图片计算值压缩后的尺寸
CGSize imageSize = sourceImage.size;
CGFloat bili = imageSize.width / imageSize.height;
CGFloat width = defineWidth * 2;
CGFloat height = width * bili;
//开启绘图
UIGraphicsBeginImageContextWithOptions(CGSizeMake(width, height), 1, 1);
//绘图到当前上下文
[sourceImage drawInRect:CGRectMake(0, 0, width, height)];
//获取新图片
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
//关闭图片绘制
UIGraphicsEndImageContext();
//返回图片
return newImage;
}
如果你对图片绘制不是很熟悉
这里有一个传送门
由于图片过大,所以Demo打包为ZIP文件 ,如果对您有一点帮助,麻烦star一下,Thanks