点击时从 UICollectionView 中的单元格获取图像

Posted

技术标签:

【中文标题】点击时从 UICollectionView 中的单元格获取图像【英文标题】:get Image from cell in a UICollectionView on tap 【发布时间】:2013-11-02 08:10:10 【问题描述】:

所以我想要实现的是当用户点击 UICollectionView 中的一个单元格时,该单元格中的图像会显示在下一个 UIView 上。

为了实现这一点,我使用了委托方法 -(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath 和 NSUserDefaults。我就是这样做的

    点击单元格 从#1单元格的UIImageView获取图片 将图像转换为 NSData 将数据放入 NSUserDefaults 对下一个视图控制器执行转场 从 NSUserDefaults 中获取数据 转换为 UIImage 并在 UIImageView 中显示。

代码如下:

-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
    NewsfeedCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
    NSData *data = [[NSData alloc]initWithData:UIImagePNGRepresentation(cell.ItemImageView.image)];
    NSLog(@"Before Data %@", data);
    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
    [def setObject:data forKey:@"feedData"];
    [def synchronize];
    [self performSegueWithIdentifier:@"itemTappedSegue" sender:self];  


- (void)viewDidLoad

    [super viewDidLoad];
    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
    NSData *data = [def objectForKey:@"feedData"];
    NSLog(@"After Data:%@", data);
    UIImage *image = [[UIImage alloc]initWithData:data];
    self.imageView.image = image;

应该有效,但无效。我得到随机结果。有时下一个 UIView 中没有图像,有时有图像但不是我点击的那个。

EDIT::这里是cellForItemAtIndexpath的实现

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
static NSString *CellIdentifier = @"Cell";
NewsfeedCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
if(response2.count > 0)
    cell.usernameLabel.text = [self getUsername:[response2 objectAtIndex:indexPath.item]];
    [UIApplication sharedApplication].networkActivityIndicatorVisible =YES;
    dispatch_queue_t getUserAvatar = dispatch_queue_create("Avatar downloader", NULL);
    dispatch_queue_t getFeed = dispatch_queue_create("Feed downloader", NULL);
    dispatch_async(getUserAvatar, ^
        NSString *urlString = [self getAvatarUrl:[response2 objectAtIndex:indexPath.item]];
        NSURL *url = [[NSURL alloc]initWithString:urlString];
        NSData *avatarData = [NSData dataWithContentsOfURL:url];
        dispatch_async(dispatch_get_main_queue(), ^
            cell.DPImageView.layer.masksToBounds = YES;
            cell.DPImageView.layer.cornerRadius = 6.0f;
            cell.DPImageView.image = [UIImage imageWithData:avatarData];
        );
    );
    dispatch_async(getFeed, ^
        NSString *URLString = [self getFeedUrl:[response2 objectAtIndex:indexPath.item]];
        NSURL *URL = [[NSURL alloc]initWithString:URLString];
        NSData *feedData = [NSData dataWithContentsOfURL:URL];
        dispatch_async(dispatch_get_main_queue(), ^
            cell.ItemImageView.image = [UIImage imageWithData:feedData];
            cell.ItemImageView.layer.masksToBounds = YES;
            cell.LikeBtn.hidden = NO;
            cell.CommentBtn.hidden = NO;
            cell.usernameLabel.hidden = NO;
            cell.DPImageView.hidden = NO;
        );
    );
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

else
    //cell.ItemImageView.image = [UIImage imageNamed:@"NoFeed.png"];
    cell.LikeBtn.hidden = YES;
    cell.CommentBtn.hidden = YES;
    cell.usernameLabel.hidden = YES;
    cell.DPImageView.hidden = YES;

return cell;

【问题讨论】:

【参考方案1】:

你为什么这样做:

    NewsfeedCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];

? 您需要获取 indexPath 的单元格,而不是从池中创建单元格。 使用:

NewsFeedCell *cell = [collectionView cellForItemAtIndexPath:indexPath];

相反。

【讨论】:

【参考方案2】:

didSelectItemAtIndexPath:方法中改行

-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
    NewsfeedCell *cell = [collectionView cellForItemAtIndexPath:indexPath]; // put this line in place of creating cell

    NSData *data = [[NSData alloc]initWithData:UIImagePNGRepresentation(cell.ItemImageView.image)];
    NSLog(@"Before Data %@", data);
    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
    [def setObject:data forKey:@"feedData"];
    [def synchronize];
    [self performSegueWithIdentifier:@"itemTappedSegue" sender:self];  

【讨论】:

我现在正在处理这件事。上一次点击的图像。如果我第一次点击图像(图像 A),在下一个视图中我什么也得不到。我回去然后点击另一个图像(图像 B)我从上一个点击中得到图像 A 能否展示cellForItemAtIndexPath: 方法的实现 很抱歉回复晚了,但我已经添加了实现【参考方案3】:

也许你已经解决了这个问题,但我遇到了类似的问题,发现UICollectionView 从 0 开始。

例如,我的图像被命名为 image_1、image_2 等等。但是如果我从 image_1 开始,那么第一个单元格中就没有任何东西,所以你必须从 image_0、image_1 等等开始......

希望这对任何人都有帮助。

【讨论】:

以上是关于点击时从 UICollectionView 中的单元格获取图像的主要内容,如果未能解决你的问题,请参考以下文章

Swift 在 UITableViewCell 内的 UICollectionView 的单选/多选模式下进行选择/取消选择

如何修复滚动时从 UICollectionViewCell 中消失的图像

如何处理 UICollectionView 中的背景点击

滚动 UICollectionView 时保留 UICollectionViewCell

UICollectionView 点击选择多个单元格

当不透明度为 0% 时从元素中移除点击