【问题标题】:Dynamically change cell size according to image in a UICollectionView根据 UICollectionView 中的图像动态更改单元格大小
【发布时间】:2014-02-03 10:37:58
【问题描述】:

我在水平集合视图中显示从服务器接收的动态图像。当我设置collectionview时,我设置了这个:

-(void)setupCollectionView{
[self setupPageControlView];
self.screensCollectionView.delegate=self;
self.screensCollectionView.dataSource=self;
[self.screensCollectionView registerNib:[UINib nibWithNibName:@"FGAppScreensCollectionViewItemCell" bundle:nil] forCellWithReuseIdentifier:@"screenCell"];


UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
[flowLayout setMinimumInteritemSpacing:0.0f];
[flowLayout setMinimumLineSpacing:0.0f];
[flowLayout setItemSize:CGSizeMake(165, 255)];
//[self.screensCollectionView setPagingEnabled:YES];
[self.screensCollectionView setCollectionViewLayout:flowLayout];

}

对于 cellForRowAtIndexPath,我像这样下载图像:

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier = @"screenCell";

FGAppScreensCollectionViewItemCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];

NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:[self.imageURLArray objectAtIndex:indexPath.row]]];

UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[spinner startAnimating];
[spinner setFrame:CGRectMake(50, 100, 20, 20)];
[cell.contentView addSubview:spinner];
[cell.screenImageView setImageWithURLRequest:urlRequest placeholderImage:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
    //STOP THE SPINNER
    for (UIView* view in [cell.contentView subviews]) {
        if ([view isKindOfClass:[UIActivityIndicatorView class]]) {
            [view removeFromSuperview];
        }
    }
    cell.screenImageView.image = image;

} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
    //
}];
[cell.screenImageView setImageWithURL:[NSURL URLWithString:[self.imageURLArray objectAtIndex:indexPath.row]]];
if (self.delegate) {
      UITapGestureRecognizer* g = [[UITapGestureRecognizer alloc] initWithTarget:self.delegate action:@selector(showPopUpImageView:)];
      [cell.screenImageView addGestureRecognizer:g];
}

return cell;

}

但是,集合视图中显示纵向和横向图像。肖像图像显示得很好,但风景图像在集合视图中显得很小。 我需要做的是根据图像大小调整单元格的大小,以便它们填充正确的纵横比

我在下面添加了这样的方法,但问题是它在开始时立即为所有单元格调用,并且一旦我在 cellForRowAtIndexPath 方法中下载图像就不会被调用:

    - (CGSize)collectionView:(UICollectionView *)collectionView
              layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath

{

return CGSizeMake(165, 255);

}

因此,我想知道如何实现此功能,如果需要这方面的更多信息,请告诉我?

【问题讨论】:

  • 你好,你有什么解决办法吗?

标签: ios objective-c uicollectionview uicollectionviewcell uicollectionviewlayout


【解决方案1】:

-setImageWithURLRequest:...中,当图片加载时,将其缓存在哈希表中,然后用当前图片路径调用-reloadItemsAtIndexPaths:,重新加载单元格,从而导致CollectionView重新检查单元格的大小.

确保在查找图像时查阅哈希表。在 collectionView 项目在屏幕外滚动并再次打开的情况下,这也将为您节省额外的网络访问。

请注意,我担心如果您使用 UICollectionReusableView 子类,您的代码可能会失败,因为单元格可以在其图像加载之前重新使用,因此图像会加载到错误的位置。

【讨论】:

    【解决方案2】:

    但是添加一个 UICollectionView 的委托方法。

    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
    {
        UIImageView *image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[arryOfImg objectAtIndex:indexPath.row]]];
    
        //You may want to create a divider to scale the size by the way..
        return CGSizeMake((image.frame.size.width)/4.0, (image.frame.size.height)/4.0);
    }
    

    【讨论】:

    • 这种方法的问题是这个方法可能在图像实际出现之前被调用。
    • 拥有所有图像后,您必须重新加载您的收藏视图
    猜你喜欢
    • 2014-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    • 2012-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多