如何从解析中检索图像并在 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];
每次集合视图重复使用它时,都会继续向您的单元格添加图像视图
我正在构建一个应用程序,它将从解析服务器查询一组图像(缩略图),然后在集合视图中显示它们,类似于在用户个人资料页面中在 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];
每次集合视图重复使用它时,都会继续向您的单元格添加图像视图