如何从解析中检索图像并在 UICollectionView 中设置 UIImageview

How to retrieve images from parse and set UIImageview in UICollectionView

我正在构建一个应用程序,它将从解析服务器查询一组图像(缩略图),然后在集合视图中显示它们,类似于在用户个人资料页面中在 instagram 上完成的方式。我创建了一个成功从后端查询数据的方法:

-(void)queryForTable {

PFQuery *query = [PFQuery queryWithClassName:@"VideoApp"];
NSString * author = [[PFUser currentUser] objectForKey:@"FBName"];
[query whereKey:@"author" equalTo:author];
[query orderByAscending:@"createdAt"];
[query setCachePolicy:kPFCachePolicyNetworkOnly];



    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if (!error) {
            NSLog(@"Successfully retrieved %d objects", objects.count);
            [self.collectionView reloadData];
            userVideosArray = [[NSMutableArray alloc] initWithCapacity:objects.count];

            for (PFObject *object in objects) {
                PFFile *thumbnail = [object objectForKey:@"video_thumbnail"];
                [thumbnail getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
                    if (!error) {
                        NSLog(@"Fetching image");
                        [userVideosArray addObject:[UIImage imageWithData:data]];
                    } else {
                        NSLog(@"Error: %@ %@", error, [error userInfo]);
                    }
                }];
            }
        }
    }];

}

该方法从后端成功获取了四个对象,并在ViewDidLoad方法中调用。 然后在集合视图 cellForRowAtIndexPath 方法中,我尝试将查询的对象图像设置为 collectionviewcell 上的 UIImageview,如下所示:

-(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    //CollectionViewcellCollectionViewCell * cell = (CollectionViewcellCollectionViewCell*)[collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];


    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 70, 70)];
    imageView.backgroundColor = [UIColor grayColor];
    [cell addSubview:imageView];


    PFQuery *query = [PFQuery queryWithClassName:@"VideoApp"];
   NSString * info = [[PFUser currentUser] objectForKey:@"FBName"];
    [query whereKey:@"author" equalTo:info];
    imageView.image = [UIImage imageWithData:[userVideosArray objectAtIndex:indexPath.row]];




    return cell;
}

我一直在 imageView.image = [UIImage imageWithData:[userVideosArray objectAtIndex:indexPath.row]]; 上收到 NSException。不能 100% 确定原因。有什么想法吗?

您应该在处理接收到的数据后更新 collectionView,而不是之前。您对 [self.collectionView reloadData] 的调用欺骗了对 cellForItemAtIndexPath 的调用,我的猜测是 userVideosArray 尚未包含您期望的那么多项目。

总之,崩溃了。试试这个来防止崩溃:

if (indexPath.item < userVideosArray.count)
    imageView.image = [UIImage imageWithData:userVideosArray[indexPath.item]];

顺便说一下,在使用 collectionView 时,我建议使用 item 而不是 row,因为一个 collectionView 行可能包含多个项目。您现在知道自己在做什么,并且可以使用 row,但稍后 row 与 item 术语可能会混淆。

您正在这样做:

1) reloadData:错误,因为您在执行此操作之前没有更新任何数组。我假设这是 findObjectsInBackgroundWithBlock 的副作用,这绝对是错误的,因为只有执行 reloadData 的对象才应该负责更新数据源的数据。

2) 初始化 userVideosArray 没有项目 (userVideosArray.count == 0)。查看您的错误并知道 cellForItemAtIndexPath 被调用我假设 -collectionView:numberOfItemsInSection: 使用其他不同的数组来告诉错误的项目数,因为您试图从 userVideosArray 可能有不同数量的项目

3) 用背景中的项目填充 userVideosArray。牢记 1 和 2 可以为我们提供崩溃的答案。 cellForItemAtIndexPath 您正在尝试获取尚未加载的项目

顺便说一句:[cell addSubview:imageView]; 每次集合视图重复使用它时,都会继续向您的单元格添加图像视图