ios - 如何异步加载UITableViewcell图像,以便滚动不会滞后

标签 ios objective-c uitableview asynchronous

我已经尝试过使用ASyncImageView来实现此目的,但是对于如何针对特定情况实现它,我有些困惑。我目前有一个MatchCenterViewController,其中包含一个表。它正在同步加载单元格的图像,这在滚动表时会导致很多延迟。如何修改加载远程图像的方式,使其异步完成?我的代码如下:

#import "MatchCenterViewController.h"
#import <UIKit/UIKit.h>
#import "MatchCenterCell.h"

@interface MatchCenterViewController () <UITableViewDataSource, UITableViewDelegate>

@property (nonatomic, strong) UITableView *matchCenter;
@property (nonatomic, assign) BOOL matchCenterDone;
@property (nonatomic, assign) BOOL hasPressedShowMoreButton;

@end



@implementation MatchCenterViewController


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
    }
    return self;
}


- (void)viewDidLoad
{
    [super viewDidLoad];

    _matchCenterDone = NO;
    _hasPressedShowMoreButton = NO;

    // Set up MatchCenter table
    self.matchCenter = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewCellStyleSubtitle];
    self.matchCenter.frame = CGRectMake(0,70,320,self.view.frame.size.height-100);
    self.edgesForExtendedLayout = UIRectEdgeAll;
    self.matchCenter.contentInset = UIEdgeInsetsMake(0.0f, 0.0f, CGRectGetHeight(self.tabBarController.tabBar.frame), 0.0f);
    _matchCenter.dataSource = self;
    _matchCenter.delegate = self;
    [self.view addSubview:self.matchCenter];

    self.expandedSection = -1;

    _matchCenterArray = [[NSArray alloc] init];

    // Refresh button
    UIImageView *refreshImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"refresh.png"]];
    refreshImageView.frame = CGRectMake(280, 30, 30, 30);
    refreshImageView.userInteractionEnabled = YES;
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(refreshPressed:)];
    [refreshImageView addGestureRecognizer:tapGesture];
    [self.view addSubview:refreshImageView];


    // Preparing for MC and indicating loading
    self.matchCenterArray = [[NSArray alloc] init];

    UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    activityIndicator.center = CGPointMake(self.view.frame.size.width / 2.0, self.view.frame.size.height / 2.0);
    [self.view addSubview: activityIndicator];

    [activityIndicator startAnimating];

    _matchCenterDone = NO;

    // Disable ability to scroll until table is MatchCenter table is done loading
    self.matchCenter.scrollEnabled = NO;

    [PFCloud callFunctionInBackground:@"MatchCenter3"
                       withParameters:@{}
                                block:^(NSArray *result, NSError *error) {

                                    if (!error) {
                                        _matchCenterArray = result;

                                        [activityIndicator stopAnimating];

                                        [_matchCenter reloadData];

                                        _matchCenterDone = YES;
                                        self.matchCenter.scrollEnabled = YES;
                                        NSLog(@"Result: '%@'", result);
                                    }
                                }];

}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return _matchCenterArray.count;
}

//the part where i setup sections and the deleting of said sections

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return 21.0f;
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    return 40;
}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
//code snipped out for conciseness
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
//Header code snipped out for conciseness
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSDictionary *currentSectionDictionary = _matchCenterArray[section];
    NSArray *top3ArrayForSection = currentSectionDictionary[@"Top 3"];

    return (top3ArrayForSection.count-1 < 1) ? 1 : top3ArrayForSection.count-1;
}

// Cell layout
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Initialize cell
    static NSString *CellIdentifier = @"MatchCenterCell";
    MatchCenterCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (!cell) {
        // if no cell could be dequeued create a new one
        cell = [[MatchCenterCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }

    //[cell.contentView addSubview:cell.priceLabel];
    [cell.contentView addSubview:cell.conditionLabel];

    // No cell seperators = clean design
    tableView.separatorColor = [UIColor clearColor];

    NSDictionary *currentSectionDictionary = _matchCenterArray[indexPath.section];
    NSArray *top3ArrayForSection = currentSectionDictionary[@"Top 3"];

    if (top3ArrayForSection.count-1 < 1) {

        // title of the item
        cell.textLabel.text = @"No items found, but we'll keep a lookout for you!";
        cell.textLabel.font = [UIFont systemFontOfSize:12];

    }

    else {

        // title of the item
        cell.textLabel.text = _matchCenterArray[indexPath.section][@"Top 3"][indexPath.row+1][@"Title"];
        cell.textLabel.font = [UIFont systemFontOfSize:14];

        // price + condition of the item
        NSString *price = [NSString stringWithFormat:@"$%@", _matchCenterArray[indexPath.section][@"Top 3"][indexPath.row+1][@"Price"]];
        NSString *condition = [NSString stringWithFormat:@"%@", _matchCenterArray[indexPath.section][@"Top 3"][indexPath.row+1][@"Item Condition"]];

        cell.detailTextLabel.text = [NSString stringWithFormat:@"%@ - %@", price, condition];
        cell.detailTextLabel.textColor = [UIColor colorWithRed:0/255.0f green:127/255.0f blue:31/255.0f alpha:1.0f];

        // image of the item
        NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:_matchCenterArray[indexPath.section][@"Top 3"][indexPath.row+1][@"Image URL"]]];
        [[cell imageView] setImage:[UIImage imageWithData:imageData]];

        cell.imageView.layer.masksToBounds = YES;
        cell.imageView.layer.cornerRadius = 2.5;

    }

    return cell;
}


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == self.expandedSection || indexPath.row <= 3) {
        return 65;
    }
    return 0;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (_matchCenterDone == YES) {
        self.itemURL = _matchCenterArray[indexPath.section][@"Top 3"][indexPath.row+1][@"Item URL"];
        [self performSegueWithIdentifier:@"WebViewSegue" sender:self];
    }
} 

@end

@implementation MoreButton
@end

最佳答案

// Use background thread to avoid the laggy tableView
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    // Download or get images here
    NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"url"]];
    UIImage *cellImage = [[UIImage alloc] initWithData:imageData];

    // Use main thread to update the view. View changes are always handled through main thread
    dispatch_async(dispatch_get_main_queue(), ^{
        // Refresh image view here
        [cell.imageView setImage:cellImage];
        [cell.imageView.layer setMasksToBounds:YES];
        [cell.imageView.layer setCornerRadius:2.5f];
        [cell setNeedsLayout];
    });
});

关于ios - 如何异步加载UITableViewcell图像,以便滚动不会滞后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26920632/

相关文章:

ios - 我应该在导入 GooglePlus.framework 时检查 "Copy items if needed"吗?

objective-c - 从自定义单元格返回 NSIndexPath ? (UITableView)

objective-c - 每次从 ios 应用程序的钥匙串(keychain)访问中获取钥匙串(keychain)保存的密码时返回 "0"

ios - 自定义 UITableView 部分索引

swift - Swift 中的 Eureka 库 : How can I loop rows?

ios - 来自苹果评论的崩溃日志

ios - 如何测试与其他设备通信的应用程序?

ios - 转换为数组后无法显示数据

ios - pagemenu-navigation 右栏按钮项(不能按tabs隐藏)

ios - 核心数据支持的 UITableView 在删除单元格时出错