优化UITableView滚动性能

自定义的cell如下:

第一个:Instruments测试,iphone4 38fps-45fps,iphone3G 25fps

// table with normal XIB based cells
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"CustomCell";

CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier: CellIdentifier];
if (cell == nil) {

NSArray *nib = [[UINib nibWithNibName:@"CustomCell" bundle:nil] instantiateWithOwner:self options:nil];
cell = (CustomCell*)[nib objectAtIndex:0];
}

// other initialization goes here
    cell.titleLabel.text = [NSString stringWithFormat:@"Row %d", indexPath.row];
    cell.subTitleLabel.text = [NSString stringWithFormat:@"Row %d", indexPath.row];
    cell.timeTitleLabel.text = @"yesterday";
    cell.thumbnailImage.image = [UIImage imageNamed:@"iOS6"];

    cell.selectionStyle = UITableViewCellSelectionStyleNone;

return cell;
}

第二个,优化之后的代码为,Instruments测试 iphone 4/iphone 4s接近60帧每秒

// table with with built in cells
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }

    // Configure the cell...
    cell.textLabel.text = [NSString stringWithFormat:@"Row %d", indexPath.row];
    cell.detailTextLabel.text = [NSString stringWithFormat:@"Row %d", indexPath.row];

    cell.imageView.image = [UIImage imageNamed:@"ios5"];

    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    return cell;
}

第三,使用Loren Bricher提供的技术,几乎每台设备都达到了60fps,包括iphone3G

Loren BricherTwitter中写了关于Tweetie中流畅滚动的内容。以下代码就是使用Loren提供的技术来为UITableView创建自定义表单元。

// table with with custom drawn cells
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"CustomDrawnCell";

CustomDrawnCell *cell = (CustomDrawnCell*)[tableView dequeueReusableCellWithIdentifier: CellIdentifier];
if (cell == nil)
{
cell = [[CustomDrawnCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}

    [cell setTitle:[NSString stringWithFormat:@"Row %d", indexPath.row]
          subTitle:[NSString stringWithFormat:@"Row %d", indexPath.row]
              time:@"yesterday"
         thumbnail:[UIImage imageNamed:@"ios5"]];

// other initialization goes here
return cell;
}

ABTableViewCell类

#import <UIKit/UIKit.h>

// to use: subclass ABTableViewCell and implement -drawContentView:

@interface ABTableViewCell : UITableViewCell
{
UIView *contentView;
}

- (void)drawContentView:(CGRect)r; // subclasses should implement

@end
#import "ABTableViewCell.h"

@interface ABTableViewCellView : UIView
@end

@implementation ABTableViewCellView

- (void)drawRect:(CGRect)r
{
[(ABTableViewCell *)[self superview] drawContentView:r];
}

@end

@implementation ABTableViewCell

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {
contentView = [[ABTableViewCellView alloc]initWithFrame:CGRectZero];
contentView.opaque = YES;
[self addSubview:contentView];
}
return self;
}

- (void)setFrame:(CGRect)f
{
[super setFrame:f];
CGRect b = [self bounds];
b.size.height -= 1; // leave room for the seperator line
[contentView setFrame:b];
}

- (void)setNeedsDisplay
{
[super setNeedsDisplay];
[contentView setNeedsDisplay];
}

- (void)drawContentView:(CGRect)r
{
// subclasses should implement this
}

@end

CustomDrawCell类

#import <UIKit/UIKit.h>
#import "ABTableViewCell.h"

@interface CustomDrawnCell : ABTableViewCell  {

    NSString *_title;
    NSString *_subTitle;
    NSString *_timeTitle;
    UIImage *_thumbnail;
}

- (void)setTitle:(NSString*) title subTitle:(NSString*) subTitle time:(NSString*) time thumbnail:(UIImage *)aThumbnail;

@end
#import "CustomDrawnCell.h"

@implementation CustomDrawnCell

static UIFont *titleFont = nil;
static UIFont *subTitleFont = nil;
static UIFont *timeTitleFont = nil;

- (void)setTitle:(NSString*) aTitle subTitle:(NSString*) aSubTitle time:(NSString*) aTimeTitle thumbnail:(UIImage *)aThumbnail
{
    if (_title != aTitle) {
        _title = aTitle;
    }

    if (_subTitle != aSubTitle) {
        _subTitle = aSubTitle;
    }

    if (_timeTitle != aTimeTitle) {
        _timeTitle = aTimeTitle;
    }

    if (_thumbnail != aThumbnail) {
        _thumbnail = aThumbnail;
    }

    [self setNeedsDisplay];
}

+(void) initialize
{
    titleFont = [UIFont systemFontOfSize:17];
    subTitleFont = [UIFont systemFontOfSize:13];
    timeTitleFont = [UIFont systemFontOfSize:10];
}

+(void) dealloc
{
    [super dealloc];
}

-(void) drawContentView:(CGRect)r
{
    static UIColor *titleColor;
    titleColor = [UIColor darkTextColor];
    static UIColor *subTitleColor;
    subTitleColor = [UIColor darkGrayColor];
    static UIColor *timeTitleColor;
    timeTitleColor = [UIColor colorWithRed:0 green:0 blue:255 alpha:0.7];

    CGContextRef context = UIGraphicsGetCurrentContext();

    if(self.highlighted || self.selected)
{
CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);
CGContextFillRect(context, CGRectMake(0, 0, self.frame.size.width, self.frame.size.height));
CGContextSetFillColorWithColor(context, titleColor.CGColor);
}
else
{
CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
CGContextFillRect(context, CGRectMake(0, 0, self.frame.size.width, self.frame.size.height));
CGContextSetFillColorWithColor(context, titleColor.CGColor);
}

    [titleColor set];
    [_thumbnail drawInRect:CGRectMake(12, 4, 35, 35)];
    [_title drawAtPoint:CGPointMake(54, 3)
                    forWidth:200
                    withFont:titleFont
                    fontSize:17
               lineBreakMode:UILineBreakModeTailTruncation
          baselineAdjustment:UIBaselineAdjustmentAlignCenters];    

    [subTitleColor set];
    [_subTitle drawAtPoint:CGPointMake(54, 23)
               forWidth:200
               withFont:subTitleFont
               fontSize:13
          lineBreakMode:UILineBreakModeTailTruncation
     baselineAdjustment:UIBaselineAdjustmentAlignCenters];    

    [timeTitleColor set];
    [_timeTitle drawAtPoint:CGPointMake(262, 3)
                  forWidth:62
                  withFont:timeTitleFont
                  fontSize:10
             lineBreakMode:UILineBreakModeTailTruncation
        baselineAdjustment:UIBaselineAdjustmentAlignCenters];    

}
@end

具体源码在这里

优化UITableView滚动性能

时间: 2024-08-25 05:48:05

优化UITableView滚动性能的相关文章

UITableView滚动性能优化

影响 UITableView 滚动的流畅性的原因 1.在代理方法中做了过多的计算占用了 UI 线程的时间 2.Cell里的图片吃GPU(在tableView:cellForRowAtIndexPath:中) 3.Cell 中 view 的组织复杂 关于第一点,首先要明白 tableview 的代理(这里指 datasource 和 delegate 的那套方法,下同)方法的调用顺序,和时机.对于一般的应用会有如下顺序: 1.向代理要 number Of Rows. 2.对于每行向代理要 heig

手机端优化列表滚动性能——分页加载

现在在手机端列表滚动随处可见,拿现在大家都在用的微信来说,朋友圈就是一个列表,和好友发信息界面就是一个列表. 如果列表长度不长,比如你微信朋友圈一共就只有两三个人分享过他们的动态,那没问题,如果你是大屏手机估计还不用滚动就已经看完了. 但那有可能吗?有也只是少数.我们现在每天刷朋友圈那都是几屏几屏这样刷的. 我们设定一屏有五个人分享的动态,每一个动态里面有5个dom节点,即一屏有25个dom节点. 我们开始刷朋友圈,才看了四屏就已经100个节点了,再往下刷成百甚至上千个dom节点都出来了,那你手

怎样优化UITableView的性能

在iOS App中,UITableView应该是使用率最高的.同一时候也是最为复杂的视图. 差点儿全部自带的应用中都能看到它的身影,可见它的重要性. 在使用UITableView时,会常常遇到性能上的问题,普遍表如今滚动时比較卡.特别是table cell中包括图片的情况时. 实际上仅仅要针对性地优化一下,这样的问题就不会有了.有兴趣的能够看看LazyTableImages这个官方的样例程序,尽管也要从网上下载图片并显示.但滚动时丝毫不卡. 首先说下UITableView的原理.有兴趣的能够看看

如何优化UITableView的性能

在iOS App中,UITableView应该是使用率最高的,同时也是最为复杂的视图. 几乎所有自带的应用中都能看到它的身影,可见它的重要性. 在使用UITableView时,会经常遇到性能上的问题,普遍表现在滚动时比较卡,特别是table cell中包含图片的情况时. 实际上只要针对性地优化一下,这种问题就不会有了.有兴趣的可以看看LazyTableImages这个官方的例子程序,虽然也要从网上下载图片并显示,但滚动时丝毫不卡. 首先说下UITableView的原理.有兴趣的可以看看<Abou

优化UITableView滚动的流畅性

影响UITableViewUITableView滚动的流畅性原因: 1. 在代理方法中做了过多的计算占用了 UI 线程的时间 2.同上 3.Cell 中 view 的组织复杂,比如使用layer并不会有太大影响,但是如果layer使用了透明,或者圆角.变形等效果,就会影响到绘制速度. 关于第一点,首先要明白 tableview 的代理(这里指 datasource 和 delegate 的那套方法,下同)方法的调用顺序,和时机.对于一般的应用会有如下顺序: 1.向代理要 number Of Ro

UITableView 滚动流程性优化

影响 UITableView 滚动的流畅性的原因 1. 在代理方法中做了过多的计算占用了 UI 线程的时间 2.同上 3.Cell 中 view 的组织复杂 关于第一点,首先要明白 tableview 的代理(这里指 datasource 和 delegate 的那套方法,下同)方法的调用顺序,和时机.对于一般的应用会有如下顺序: 1.向代理要 number Of Rows. 2.对于每行向代理要 height For Row At Index Path. 3.向代理要 当前屏幕可见的 cell

UITableView的性能优化1

UITableView作为ios中使用最频繁的控件之一,其性能优化也是常常要面对的,尤其是当数据量偏大并且设备性能不足时.本文旨在总结tableview的几个性能优化tips,并且随着认识的深入,本文将持续更新,力求将tableview的优化做到极致! Let`s begin! 治病就要先知道病因,我们先来分析一下影响tableview滚动性能的因素有哪些: 1 2 3 1.cellForRowAtIndexPath方法中处理了过多业务 2.tableviewCell的subview层级太复杂,

UITableView的性能优化

UITableView作为ios中使用最频繁的控件之一,其性能优化也是常常要面对的,尤其是当数据量偏大并且设备性能不足时.本文旨在总结tableview的几个性能优化tips,并且随着认识的深入,本文将持续更新,力求将tableview的优化做到极致! Let`s begin! 治病就要先知道病因,我们先来分析一下影响tableview滚动性能的因素有哪些: 1 2 3 1.cellForRowAtIndexPath方法中处理了过多业务 2.tableviewCell的subview层级太复杂,

【UIKit】UITableView.05 性能优化

UITableView.05 性能优化: [为何要性能优化]:TableView拖屏过程中,不断有对象"消失"在屏幕上,但是这样的对象还是存在的,当拖拉过多后,导致内存严重泄漏. 解决方法:仅提供有限的对象,拖拉过程中,只是将内存地址存放的内容进行改变. [旧代码] -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITable