美文网首页
UITableView中cell图文高度自适应问题

UITableView中cell图文高度自适应问题

作者: 远处那片海 | 来源:发表于2016-08-25 16:15 被阅读56次

    该方法仅用于后台数据中未给出图片尺寸的情况。

    该方法主要有以下几个要点:

    • tableView的加载流程
    1. 获取cell数量
    2. 获取cell高度
    3. 加载cell内容
    • SDWebImage的其它类
    1. SDWebImageDownloader
    2. SDImageCache

    具体代码如下:

    #pragma mark - Table view datasource and delegate
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return [aArray count];  // aArray 为一个数组,保留每个 cell 对应的 model
    }
    
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        // 先从缓存中查找图片
        UIImage *img = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey: imgKey ];
    
        // 没有找到已下载的图片就使用默认的占位图,当然高度也是默认的高度了,除了高度不固定的文字部分。
        if (!img) {
            img = CachedImage( placeholder name );
        }
    
        CGFloat height = [MyCustomCell heightWithImage:img text:text]; // 根据传入的动态内容计算 cell 的高度
        return height;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *identifier = @"Cell Identifier";
        MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    
        // 如果没有可以复用的 cell 就新建一个
        if (!cell) {
            cell = [[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault
                                         reuseIdentifier:identifier];
        }
    
        // 配置 cell
        [self configureCell:cell atIndexPath:indexPath];
    
        return cell;
    }
    
    - (void)configureCell:(MyCustomCell *)cell atIndexPath:(NSIndexPath *)indexPath
    {
        // 正常的设置文字和其他内容
    
        // 开始加载图片
        NSString *imgURL = [self.aArray[indexPath.row] valueForKey: imgKey ];    // 图片 url
        UIImage *cachedImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:imgURL];
    
        // 没有已经下载好的图片
        if ( !cachedImage ) {
            // 要是当前 table view 没有在被拖动或者自由滑行
            if ( !self.tableView.dragging && !self.tableView.decelerating ) {
                // 下载当前 cell 中的图片
                [self downloadImage:imgURL forIndexPath:indexPath];
            }
            // cell 中图片先用缓存的占位图代替
            [cell setSpitslotImage:CachedImage(@"placeholder")];
        } else {
            // 找到了缓存的图片,直接插缓存的图片
            [cell setSpitslotImage:cachedImage];
        }
    }
    
    - (void)downloadImage:(NSString *)imageURL forIndexPath:(NSIndexPath *)indexPath
    {
        __weak typeof(self) target = self;
    
        // 利用 SDWebImage 框架提供的功能下载图片
        [[SDWebImageDownloader sharedDownloader] downloadImageWithURL:URLFromString(imageURL)
        options:SDWebImageDownloaderUseNSURLCache
        progress:^(NSUInteger receivedSize, long long expectedSize) {
         // Do nothing
        }
        completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {
    
        // 保存图片
        [[SDImageCache sharedImageCache] storeImage:image forKey:imageURL toDisk:YES]; // 别忘了保存到磁盘上
    
        // 延迟在主线程更新 cell 的高度
        [target performSelectorOnMainThread:@selector(reloadCellAtIndexPath:)       // 至于这步的原因是为了防止刷的太快了崩溃
                                 withObject:indexPath waitUntilDone:NO];            // 这步会把 selector 的调用放到主线程的 run loop 里排队
        }];                                                                         // 风险就是要是这个队列里排队的比较多,
                                                                                    // 这个后插入的方法执行会被延迟
    }
    
    // 这个方法没什么好解释的了
    - (void)loadImageForOnScreenRows
    {
        NSArray *visiableIndexPathes = [self.tableView indexPathsForVisibleRows];
    
        for(NSInteger i = 0; i < [visiableIndexPathes count]; i++)
        {
            NSString *imgURL = [self.aArray[i] valueForKey: imgKey ];
            [self downloadImage:imgURL forIndexPath:visiableIndexPathes[i]];
        }
    }
    
    // 方法名为什么叫这个。。。。是我太懒了,之前写的是刷新某一行的数据,然后发现效率不高,还容易崩溃
    // 最后直接刷新全部数据了。。
    // 但是别认为调用 table view 的 reloadData 效率就不高,回顾下上面的步骤
    // reloadData 实际上就是向代理要行数,要行高,对**显示出来**的 cell 填充数据
    // 我的那份代码的瓶颈就是 计算行高和填充数据,不过现在看来没什么不流畅的,所以就没什么问题
    // 其实,为了性能考虑,还是最好服务器返回 每个 cell 中的图片的宽高,现在的做法只是临时解决后台xx的问题。。。。。。
    - (void)reloadCellAtIndexPath:(NSIndexPath *)indexPath
    {
        [self.tableView reloadData];
    }
    
    #pragma mark - Scroll view delegate
    - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
    {   
        // table view 停止拖动了
        if (!decelerate) {
            [self loadImageForOnScreenRows];
        }
    }
    
    - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
    {
        // table view 停止滚动了
        [self loadImageForOnScreenRows];
    }
    

    摘自:http://www.tuicool.com/articles/iMNrAf

    相关文章

      网友评论

          本文标题:UITableView中cell图文高度自适应问题

          本文链接:https://www.haomeiwen.com/subject/vsrasttx.html