Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/117.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UICollectionView将图像添加到单元格_Ios_Uiview_Uiimage_Uicollectionview_Uicollectionviewcell - Fatal编程技术网

Ios UICollectionView将图像添加到单元格

Ios UICollectionView将图像添加到单元格,ios,uiview,uiimage,uicollectionview,uicollectionviewcell,Ios,Uiview,Uiimage,Uicollectionview,Uicollectionviewcell,我正在做一个项目,它使用UICollectionView来显示可能有图像也可能没有图像的数据 我使用的方法是检查图像url是否为空,然后在单元格中添加一个ImageView - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { if (question.picture != (id)[NSNu

我正在做一个项目,它使用
UICollectionView
来显示可能有图像也可能没有图像的数据

我使用的方法是检查图像url是否为空,然后在单元格中添加一个ImageView

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    if (question.picture != (id)[NSNull null]) {
        //add AsyncImageView to cell
        imageView.contentMode = UIViewContentModeScaleAspectFill;
        imageView.clipsToBounds = YES;
        imageView.tag = IMAGE_VIEW_TAG;
        [cell addSubview:imageView];
        [[AsyncImageLoader sharedLoader] cancelLoadingImagesForTarget:imageView];
        imageView.imageURL = [NSURL URLWithString:question.picture];
    }
}
对于没有图像的单元格,单元格应如下所示:

但是,其中一些用户仍然会添加带有裁剪图像的ImageView,导致如下情况:

我尝试过使用SDWebImage,但仍然没有解决问题

另一个问题是,当我向下滚动
UICollectionView
时,我会看到一些图像首先显示为上面显示的图像,然后在加载完成后更改为正确的图像,我不知道是什么导致了问题


请帮我解决这两个问题,我非常感谢您的帮助。

首先,您在手机中添加图像的方式非常危险。原因是您的单元格正在被重用(例如,当您滚动或重新加载数据时),这些图像在重用时永远不会被删除。因此,您将开始在任何地方使用它们,甚至可以在单元格中多次出现图像。以下是两种方法:

  • 第一种方法(好的方法):将UICollectionViewCell子类化,并给子类一个“imageView”属性。然后在CustomCollectionViewCell.m文件中执行此操作:

    // Lazy loading of the imageView
    - (UIImageView *) imageView
    {
        if (!_imageView) {
            _imageView = [[UIImageView alloc] initWithFrame:self.contentView.bounds];
            [self.contentView addSubview:_imageView];
         }
         return _imageView;
     }
    
    // Here we remove all the custom stuff that we added to our subclassed cell
    -(void)prepareForReuse
    {
        [super prepareForReuse];
    
        [self.imageView removeFromSuperview];
        self.imageView = nil;
    }
    
    然后在ViewController中,您必须声明collectionViewCells的新类,如下所示:

    [self.collectionView registerClass:[CustomCollectionViewCell class] forCellWithReuseIdentifier:@"cell"];
    
    它将确保在重用时正确删除图像,而且在collectionView委托中设置单元格更容易

  • 第二种方式(脏方式),即每次加载新单元时删除视图:

    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView                 cellForItemAtIndexPath:(NSIndexPath *)indexPath
    {
        for (UIView *subview in [cell.contentView subviews]) {
            [subview removeFromSuperview];
        }
    
        if (question.picture != (id)[NSNull null]) {
            //add AsyncImageView to cell
            imageView.contentMode = UIViewContentModeScaleAspectFill;
            imageView.clipsToBounds = YES;
            imageView.tag = IMAGE_VIEW_TAG;
            [cell.contentView addSubview:imageView];
            [[AsyncImageLoader sharedLoader] cancelLoadingImagesForTarget:imageView];
            imageView.imageURL = [NSURL URLWithString:question.picture];
        }
    }
    
    这种方法简单得多,但我不推荐它:p

现在试试这个,让我知道你的bug是如何演变的。

Swift 4的代码 func collectionView(collectionView:UICollectionView,numberOfItemsInSection:Int)->Int{ 返回1 } func collectionView(collectionView:UICollectionView,cellForItemAt indexPath:indexPath)->UICollectionViewCell{ let cell=collectionView.dequeueReusableCell(withReuseIdentifier:“cell”,for:indexath) var-imageview:UIImageView=UIImageView(帧:CGRect(x:50,y:50,宽度:200,高度:200)); var img:UIImage=UIImage(名为:“您的图像名称”) imageview.image=img cell.contentView.addSubview(imageview) } 返回单元 } func collectionView(collectionView:UICollectionView,布局collectionViewLayout:UICollectionViewLayout,SizeFormiteIndeXPath indexPath:NSIndexPath)->CGSize{ 返回CGSize(宽:50,高:414) }
非常感谢你!您提供的第一个解决方案确实有效,解决了所有问题。谢谢!:)我觉得这很有用。特别是prepareForReuse()方法和所需的清理。当我发现我的牢房发生了多起事件,或者看起来有多个标题标签时,我把它们放在我的牢房里,以测试collectionview的顺序。最后!!我的问题是,即使我取消设置了图像(imageView.image=nil),也会显示我的旧图像。这就成功了:[self.imageView removeFromSuperview];几个月的头痛一下子就解决了!你的链接不好虽然这个答案可能是正确的和有用的,但是如果你想解释一下它是如何帮助解决问题的,你会更喜欢这个答案。如果有一个变化(可能是无关的)导致它停止工作,并且用户需要了解它曾经是如何工作的,那么这在将来变得特别有用。 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 1 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) var imageview:UIImageView=UIImageView(frame: CGRect(x: 50, y: 50, width: 200, height: 200)); var img : UIImage = UIImage(named:"Your image name") imageview.image = img cell.contentView.addSubview(imageview) } return cell } func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { return CGSize(width: 50, height: 414) }