iOS Tableview优化

第一 CPU考虑方向

1. 对象创建;

1.1 Tableview初始化

#pragma 懒加载
- (UITableView *)tableView{
    if (!_tableView) {
        _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - self.cycleScrollView2.frame.size.height)];
        _tableView.delegate = self;
        _tableView.dataSource = self;
        [self.view addSubview:_tableView];
    }
    return _tableView;
}


1.2 复用cell


  • 从 iOS 6 以后,我们在 UITableView 和 UICollectionView 中可以复用 Cell以及各个 Section 的 Header 和 Footer。

  • 确保TableviewCell/Header/Footer使用了复用机制, 而不是每一次都创建;

@interface HomeVC ()<UITableViewDataSource, UITableViewDelegate>

@property (nonatomic, strong) UITableView *tableView;

@end


static NSString *cellId = @"Cell";

@implementation HomeVC

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.myTableView.delegate = self;
    self.myTableView.dataSource = self;
//第一种注册cell<nib文件类HomeTableViewCell>
    [self.tableView registerNib:[UINib nibWithNibName:@"HomeTableViewCell" bundle:nil] forCellReuseIdentifier:cellId];
    
//第二种注册Cell<纯手工打造的HomeVC>
// [self.tableView registerClass:[HomeVC class]forCellReuseIdentifier:cellId];
    
}

#pragma 代理

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    //获取重用池中的cell
    HomeTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
    //如果没有取到,就初始化
    if (!cell) {
        cell = [[HomeTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
    }
    
    cell.cellNameLab.text = @"Name";
    return cell;
}

1.2.1 以下为重用相关API

// 复用 Cell:
- [UITableView dequeueReusableCellWithIdentifier:];
- [UITableView registerNib:forCellReuseIdentifier:];
- [UITableView registerClass:forCellReuseIdentifier:];
- [UITableView dequeueReusableCellWithIdentifier:forIndexPath:];
// 复用 Section 的 Header/Footer:
- [UITableView registerNib:forHeaderFooterViewReuseIdentifier:];
- [UITableView registerClass:forHeaderFooterViewReuseIdentifier:];
- [UITableView dequeueReusableHeaderFooterViewWithIdentifier:];


2. TabelView 代理

2.1 避免快速滑动情况下开过多线程。

cell中的图片开线程异步加载<SDWebImage(异步操作)>。但是线程开过多了会造成资源浪费,内存开销过大。图片过多时可以不要一滚动就走cellForRow方法,可以在scrollview的代理方法中做限制当滚动开始减速的时候才加载显示在当前屏幕上的cell(通过tableview的dragging和declearating两个状态也能判断)


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    
 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
    //如果没有取到,就初始化
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
    }
    cell.textLabel.text = @"Name";

    BOOL canLoad = !self.tableView.dragging && !_tableView.decelerating;
    if  (canLoad) {
        //开始loaddata,异步加载图片
        NSLog(@"开始加载图片");
    }
    return cell;
}


// 滚动停止时,触发该函数
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    //刷新tableview
   // [self.tableView reloadData];


 //在此刷新的是屏幕上显示的cell的内容
    NSArray *visiblePaths = [self.tableView indexPathsForVisibleRows];
    //获取到的indexpath为屏幕上的cell的indexpath
    [self.tableView reloadRowsAtIndexPaths:visiblePaths withRowAnimation:UITableViewRowAnimationRight];

}


3 图片圆角

第一种方法: layer.cornerRadius

imageView.layer.cornerRadius = imageView.frame.size.width/2.0;  
// 隐藏边界
imageView.layer.masksToBounds = YES;

第二种方法: 头像使用蒙版+贝塞尔曲线加圆角


CAShapeLayer *layer = [[CAShapeLayer alloc] init];

UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.icon.width / 2, self.icon.height / 2) radius:self.icon.width / 2  startAngle:0 endAngle:M_PI * 2 clockwise:YES];

layer.path = path.CGPath;
self.icon.layer.mask = layer;
  

第三种方法:
stackoverflow


    UIImageView *iconImage = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    [self.view addSubview:iconImage];
    
    // Get your image somehow
    UIImage *image = [UIImage imageNamed:@"image.jpg"];
    // Begin a new image that will be the new image with the rounded corners
    // (here with the size of an UIImageView)
    UIGraphicsBeginImageContextWithOptions(iconImage.bounds.size, NO, [UIScreen mainScreen].scale);
    // Add a clip before drawing anything, in the shape of an rounded rect
    [[UIBezierPath bezierPathWithRoundedRect:iconImage.bounds cornerRadius:10.0] addClip];
    // Draw your image
    [image drawInRect:iconImage.bounds];
    // Get the image, here setting the UIImageView image
    iconImage.image = UIGraphicsGetImageFromCurrentImageContext();
    // Lets forget about that we were drawing
    UIGraphicsEndImageContext();

第四种方法:






4 异步加载图片

第一种方法: SDWebImage的使用


[imageView sd_setImageWithURL:url completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
            imageView.image = image;
}];

优化UITableViewCell高度计算

Tip

1. 使用不透明视图, 如非必要, 可以设置opaque为yes;
2. 图片的alpha尽量不设置透明度;
3. cellForRowAtIndexPath不要做耗时操作, 
   * 读取文件/写入文件;
   * 尽量不要去添加和移除view;
4.   




作者:HowardHuang
链接:https://www.jianshu.com/p/e3b3e9fb8a6c

猜你喜欢

转载自blog.csdn.net/u013712343/article/details/81000350