1、cell复用
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TXTestCell *cell = (TXTestCell *)[tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
return cell;
}
2、延迟数据绑定
cellForRowAtIndexPath:cell还没有被展示出来
willDisplayCell:在cell实例生成之后调用,可以在这里进行数据绑定
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
}
3、cell高度给定方式
1、定高,直接给定cell的高度,不需要实现代理,系统默认44pt
self.tableView.rowHeight = 100;
2、动态高度,需要实现代理给出高度,实现代理后rowHeight给出的高度将为无效高度。在这个方法中我们需要提高cell高度的计算效率。
self.tableView.estimatedRowHeight = 118.f;
self.tableView.rowHeight = UITableViewAutomaticDimension;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return indexPath.row >0 ? 59.f : 63.f;
}
4、cell的渲染
1、当有图像时,预渲染图像,详情见《Improving Image Drawing Performance on iOS》
2、不要使用透明背景,将cell的opaque设置为YES,背景色不要使用clearColor,尽量不要使用阴影渐变等。
3、混合操作是GPU执行,我们可以用CPU渲染,这样混合操作就不会执行,可以在UIView的drawRect方法中自定义绘制。
4、减少subviews的个数和层级。子控件的层级越深,渲染到屏幕上所需要的计算量就越大;如多用drawRect绘制元素,替代用view显示。
5、少用subviews的透明图层。对于不透明的View,设置opaque为YES,这样在绘制该View时,就不需要考虑被View覆盖的其他内容(尽量设置Cell的view为opaque,避免GPU对Cell下面的内容也进行绘制)。
6、CALayer给Cell中View加阴影会引起性能问题,如下面代码会导致滚动时有明显的卡顿:
view.layer.shadowColor = color.CGColor;
view.layer.shadowOffset = offset;
view.layer.shadowOpacity = 1;
view.layer.shadowRadius = radius;
7、我们在cell上添加系统控件的时候,实际上系统都会调用底层的接口进行绘制,大量添加控件时,会消耗很大的资源并且也会影响渲染的性能。当使用默认的UITableViewCell并且在它的ContentView上面添加控件时会相当消耗性能。所以目前最佳的方法还是继承UITableViewCell,并重写drawRect方法。
8、在实现drawRect方法的时候,它的参数rect就是我们需要绘制的区域,在rect范围之外的区域我们不需要进行绘制,否则会消耗相当大的资源。
9、异步优化UI,不要阻塞主线程。
10、cell上的数据源分页加载。
5、离屏渲染
引起离屏渲染
1、为图层设置遮罩(layer.mask);
2、将图层的layer.masksToBounds = YES
view.clipsToBounds = YES;
3、将图层layer.allowsGroupOpacity = YES和layer.opacity小于1.0;
4、为图层设置阴影(layer.shadow *);
5、为图层设置layer.shouldRasterize = YES;
6、具有layer.cornerRadius,layer.edgeAntialiasingMask,layer.allowsEdgeAntialiasing的图层;
7、文本(任何种类,包括UILabel,CATextLayer,Core Text等);
8、使用CGContext在drawRect :方法中绘制大部分情况下会导致离屏渲染,甚至仅仅是一个空的实现。
解决离屏渲染
使用贝塞尔曲线UIBezierPath和Core Graphics框架绘制圆角
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
imageView.image = [UIImage imageNamed:@"myImg"];
//开始对imageView进行画图
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0);
//使用贝塞尔曲线画出一个圆形图
[[UIBezierPath bezierPathWithRoundedRect:imageView.bounds cornerRadius:imageView.frame.size.width] addClip];
[imageView drawRect:imageView.bounds];
imageView.image = UIGraphicsGetImageFromCurrentImageContext();
//结束画图
UIGraphicsEndImageContext();
[self.view addSubview:imageView];
使用CAShapeLayer和UIBezierPath设置圆角
UIImageView *imageView = [[UIImageViewalloc]initWithFrame:CGRectMake(100,100,100,100)];
imageView.image=[UIImageimageNamed:@"myImg"];
UIBezierPath *maskPath = [UIBezierPathbezierPathWithRoundedRect:imageView.boundsbyRoundingCorners:UIRectCornerAllCornerscornerRadii:imageView.bounds.size];
CAShapeLayer *maskLayer = [[CAShapeLayeralloc]init];
//设置大小
maskLayer.frame = imageView.bounds;
//设置图形样子
maskLayer.path = maskPath.CGPath;
imageView.layer.mask = maskLayer;
[self.viewaddSubview:imageView];
用CAShapeLayer的内存消耗少,渲染速度快,建议使用
6、shadow优化
对于shadow,如果图层是个简单的几何图形或者圆角图形,我们可以通过设置shadowPath来优化性能,能大幅提高性能。示例如下:
imageView.layer.shadowColor = [UIColorgrayColor].CGColor;
imageView.layer.shadowOpacity = 1.0;
imageView.layer.shadowRadius = 2.0;
UIBezierPath *path = [UIBezierPathbezierPathWithRect:imageView.frame]
imageView.layer.shadowPath = path.CGPath;
7、其他的一些方法
1.当我们需要圆角效果时,可以使用一张中间透明图片蒙上去。
2.使用ShadowPath指定layer阴影效果路径。
3.使用异步进行layer渲染(Facebook开源的异步绘制框架AsyncDisplayKit)。
4.设置layer的opaque值为YES,减少复杂图层合成。
5.尽量使用不包含透明(alpha)通道的图片资源。
- 尽量设置layer的大小值为整形值。
7.直接让美工把图片切成圆角进行显示,这是效率最高的一种方案。
8.很多情况下用户上传图片进行显示,可以让服务端处理圆角。
9.使用代码手动生成圆角Image设置到要显示的View上,利用UIBezierPath(CoreGraphics框架)画出来圆角图片