使用 didSelect 方法在 viewDidLoad 之后在单元格中显示图像

Posted

技术标签:

【中文标题】使用 didSelect 方法在 viewDidLoad 之后在单元格中显示图像【英文标题】:Show image in Cell after viewDidLoad using didSelect method 【发布时间】:2019-09-13 21:55:02 【问题描述】:

我有一个单元格,其中包含一个空的 UIImageView 和一个嵌套在包含一行图像的 collectionView 中。我创建了一个 didSelect 函数,我想突出显示选定的行并在空的 UIImageView 中显示它的图像。

我尝试了 reloadData 功能,应用程序崩溃了。我在没有 reloadData 函数的情况下尝试了它,并且索引路径的项目仅突出显示。

class DisplayImageCell: UICollectionViewCell, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout 

    private let displayCell = "DisplayImageCell"

    let imageContainer: UIImageView = 
        let imageContainer = UIImageView()
        imageContainer.clipsToBounds = true
        imageContainer.backgroundColor = UIColor(patternImage: (UIImage(imageLiteralResourceName: "ic_person_outline_white_2x").withRenderingMode(.alwaysTemplate)))
        imageContainer.isUserInteractionEnabled = true
        imageContainer.translatesAutoresizingMaskIntoConstraints = false
        return imageContainer
    ()

    let pictureCollection: UICollectionView = 
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        layout.minimumLineSpacing = 5
        layout.minimumInteritemSpacing = 10
        let imageContainer = UICollectionView(frame: .zero, collectionViewLayout: layout)
        imageContainer.showsHorizontalScrollIndicator = false
        imageContainer.clipsToBounds = true
        imageContainer.tintColor = .yellow
        imageContainer.isUserInteractionEnabled = true
        imageContainer.translatesAutoresizingMaskIntoConstraints = false
        return imageContainer
    ()

    override init(frame: CGRect) 
        super.init(frame: frame)
        backgroundColor = .clear

        pictureCollection.dataSource = self
        pictureCollection.delegate = self
        pictureCollection.register(ImageCell.self, forCellWithReuseIdentifier: displayCell)

        addSubview(imageContainer)
        NSLayoutConstraint.activate([
            imageContainer.topAnchor.constraint(equalTo: topAnchor),
            imageContainer.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 0.80),
            imageContainer.widthAnchor.constraint(equalTo: widthAnchor)
            ])

        addSubview(pictureCollection)
        NSLayoutConstraint.activate([
            pictureCollection.topAnchor.constraint(equalTo: imageContainer.bottomAnchor, constant: 10),
            pictureCollection.bottomAnchor.constraint(equalTo: bottomAnchor),
            pictureCollection.widthAnchor.constraint(equalTo: widthAnchor)
            ])

    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return 7
    

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: displayCell, for: indexPath) as! ImageCell
        let imageOption = ImageOption(rawValue: indexPath.row)
        cell.iconImageView.image = imageOption?.icon()
        return cell
    

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
        return CGSize(width: pictureCollection.frame.height, height: pictureCollection.frame.height)
    

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
        updateCell(having: indexPath, selected: true)
    

    func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) 
        updateCell(having: indexPath, selected: false)
    

    func collectionView(_ collectionView: UICollectionView, didHighlightItemAt indexPath: IndexPath) 
        updateCell(having: indexPath, selected: true)
    

    func collectionView(_ collectionView: UICollectionView, didUnhighlightItemAt indexPath: IndexPath) 
        updateCell(having: indexPath, selected: false)
    

    private class ImageCell: UICollectionViewCell 

        let iconImageView: UIImageView = 
            let iv = UIImageView()
            iv.contentMode = .scaleAspectFit
            iv.clipsToBounds = true
            iv.translatesAutoresizingMaskIntoConstraints = false
            iv.isUserInteractionEnabled = true
            return iv
        ()

        override init(frame: CGRect) 
            super.init(frame: .zero)

            backgroundColor = .blue

            addSubview(iconImageView)
            NSLayoutConstraint.activate([
                iconImageView.heightAnchor.constraint(equalTo: heightAnchor),
                iconImageView.widthAnchor.constraint(equalTo: widthAnchor),
                iconImageView.centerXAnchor.constraint(equalTo: centerXAnchor),
                iconImageView.centerYAnchor.constraint(equalTo: centerYAnchor)
                ])

        

        required init?(coder aDecoder: NSCoder) 
            fatalError("init(coder:) has not been implemented")
        
    
    func updateCell(having indexPath: IndexPath, selected: Bool) 

        let selectedBackgroundColor = UIColor(red: 41/255.0, green: 211/255.0, blue: 241/255.0, alpha: 1.0)
        let defaultBackgroundColor = UIColor.blue
        let imageSlot = DisplayImageCell()
        let ep = EditProfileController()

        if let cell = pictureCollection.cellForItem(at: indexPath) 
            cell.contentView.backgroundColor = selected ? selectedBackgroundColor : defaultBackgroundColor
            imageSlot.imageContainer.image = UIImage(named: "ThumbsUp")
            ep.collectionView.reloadData()
        
    

Empty Imageview 的预期结果是显示所选 indexPath.row 的图像。当我尝试重新加载 collectionView 时,我发现一个 nil 值的致命错误。

【问题讨论】:

为什么要创建let imageSlot = DisplayImageCell()let ep = EditProfileController()这两个新实例? @NickBurinok 配置文件控制器是包含生成此单元格的 CollectionView 的类。我调用 DisplayImageCell 的一个实例,因为该函数是在私有类中创建的,并且为了引用 Empty UIImageView 我必须调用 imageSlot。 问题是您实际上并没有获得对现有类的引用,而是创建了它的新实例。 @NickBurinok 谢谢你提供的信息。出于某种原因,我认为我必须在新函数中进行引用,而我所要做的就是提取用于为单元格生成图像的相同信息,而不是尝试从单元格本身中提取信息 不客气! 【参考方案1】:

如果您想在imageContainer 中显示从集合视图的数据源中选择的图像,您可以像在cellForItemAt indexPath 中一样在didSelectItemAt indexPath 中获取图像:

let imageOption = ImageOption(rawValue: indexPath.item)

然后

imageContainer.image = imageOption?.icon()

调用reloadData()没有实际必要,因为collection view的数据源还没有更新。

【讨论】:

以上是关于使用 didSelect 方法在 viewDidLoad 之后在单元格中显示图像的主要内容,如果未能解决你的问题,请参考以下文章

表点击和 didselect 方法冲突

使用 SearchController 后的 DidSelect 导致快速崩溃

为啥 UICollectionView didSelect 方法不起作用?

如何在 didselect 上展开 collectionview 单元格以显示更多信息?

如何在表格视图的 didSelect 上显示弹出框

在选择表格单元格“didSelect”时如何将图像解析到另一个视图?