Swift 如何从UIImageView中清除图像

Swift 如何从UIImageView中清除图像,swift,uicollectionview,uiimage,Swift,Uicollectionview,Uiimage,我在Swift中有以下用于合成布局的代码,但我的图像不会随着单元格的重用而消失 import UIKit class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource { @IBOutlet var collectionView: UICollectionView! let myInset: CGFloat = 4.0 let dataCol

我在Swift中有以下用于合成布局的代码,但我的图像不会随着单元格的重用而消失

import UIKit

class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {

    @IBOutlet var collectionView: UICollectionView!

    let myInset: CGFloat = 4.0

    let dataColors = [UIColor.red, UIColor.blue, UIColor.green, UIColor.magenta, UIColor.purple, UIColor.orange, UIColor.red, UIColor.blue, UIColor.green, UIColor.magenta, UIColor.purple, UIColor.systemYellow, UIColor.red, UIColor.blue, UIColor.green, UIColor.magenta, UIColor.purple, UIColor.orange, UIColor.red, UIColor.blue, UIColor.green, UIColor.magenta, UIColor.purple, UIColor.systemYellow]

    let theImages = [
            "MEN_8882","002","003","004","005","006","001","002","003","004","005","006",
            "MEN_8882","002","003","004","005","006","001","002","003","004","005","006"
    ]


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        collectionView.setCollectionViewLayout(createCustomLayout(), animated: false)
        collectionView.backgroundColor = .white
        self.collectionView.delegate = self
        self.collectionView.dataSource = self

        collectionView.register(QuickCell.self, forCellWithReuseIdentifier: "cellID")
       //configureCollectionView()
    }

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1//dataColors.count
    }
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return dataColors.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellID", for: indexPath) as? QuickCell {
            cell.backgroundColor = dataColors[indexPath.row]
            let mySubView = UIImageView()
            mySubView.image = UIImage(named: theImages[indexPath.row])
            cell.addSubview(mySubView)
            mySubView.translatesAutoresizingMaskIntoConstraints =  false
            mySubView.topAnchor.constraint(equalTo: cell.topAnchor, constant: myInset).isActive = true
            mySubView.leadingAnchor.constraint(equalTo: cell.leadingAnchor, constant: myInset).isActive = true
            mySubView.trailingAnchor.constraint(equalTo: cell.trailingAnchor, constant: myInset * (-1)).isActive = true
            mySubView.bottomAnchor.constraint(equalTo: cell.bottomAnchor, constant: myInset * (-1)).isActive = true
            mySubView.clipsToBounds = true
           // mySubView.layer.cornerRadius = 8
            mySubView.contentMode = .scaleAspectFit
            cell.clipsToBounds = true
            cell.layoutIfNeeded()
            //cell.layer.cornerRadius = 12
            return cell
        } else {
            return UICollectionViewCell()
        }

    }

    func createCustomLayout() -> UICollectionViewLayout {

            let layout = UICollectionViewCompositionalLayout { (section: Int, environment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in

                let myItemInset: CGFloat = 2.0

                let leadingItem = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0)))
                leadingItem.contentInsets = NSDirectionalEdgeInsets(top: myItemInset, leading: myItemInset, bottom: myItemInset, trailing: myItemInset)

                let leadingGroupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.7), heightDimension: .fractionalHeight(1.0))
                let leadingGroup = NSCollectionLayoutGroup.vertical(layoutSize: leadingGroupSize, subitem: leadingItem, count: 1)

                let trailingGroupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.3), heightDimension: .fractionalHeight(1.0))
                let trailingGroup = NSCollectionLayoutGroup.vertical(layoutSize: trailingGroupSize, subitem: leadingItem, count: 5)

                let fullGroupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0))
                let fullGroup = NSCollectionLayoutGroup.horizontal(layoutSize: fullGroupSize, subitems: [leadingGroup, trailingGroup])

                let section = NSCollectionLayoutSection(group: fullGroup)

                section.orthogonalScrollingBehavior = .groupPagingCentered
                section.contentInsets = NSDirectionalEdgeInsets(top: 20, leading: 0, bottom: 20, trailing: 0)

                return section
            }
            return layout
        }

}
图像“男人…”是纵向的,而其余的是横向的,当我来回滚动时,我看到项目中重叠的图像

QuickCell的代码是空的-我不确定该放什么,某种初始化?但不管怎样,它应该是有效的,对吗

import UIKit

class QuickCell: UICollectionViewCell {
}

要从
UIImageView
中删除
image
,请执行以下操作

yourImageView.image = nil 

要从
UIImageView
中删除
image
,请执行以下操作

yourImageView.image = nil 

您在
cellForItemAt
中不断添加子视图,这会导致重叠。当单元格出列时,您需要为imageview创建一个出口,以编程方式在单元格内创建它,如

class QuickCell: UICollectionViewCell {


    let mySubView = UIImageView()

    override init(frame: CGRect) {
        super.init(frame: frame)
        let myInset: CGFloat = 4.0
        self.contentView.addSubview(mySubView)
        mySubView.translatesAutoresizingMaskIntoConstraints =  false
        mySubView.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: myInset).isActive = true
        mySubView.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: myInset).isActive = true
        mySubView.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: myInset * (-1)).isActive = true
        mySubView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor, constant: myInset * (-1)).isActive = true
        mySubView.clipsToBounds = true
       // mySubView.layer.cornerRadius = 8
        mySubView.contentMode = .scaleAspectFit

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


}

    if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellID", for: indexPath) as? QuickCell {
        cell.subviews.forEach { 
             if $0.tag == 333 {
               $0.removeFromSuperview()
             }
         }
        cell.backgroundColor = dataColors[indexPath.row]
        let mySubView = UIImageView()
        mySubView.tag = 333

您在
cellForItemAt
中不断添加子视图,这会导致重叠。当单元格出列时,您需要为imageview创建一个出口,以编程方式在单元格内创建它,如

class QuickCell: UICollectionViewCell {


    let mySubView = UIImageView()

    override init(frame: CGRect) {
        super.init(frame: frame)
        let myInset: CGFloat = 4.0
        self.contentView.addSubview(mySubView)
        mySubView.translatesAutoresizingMaskIntoConstraints =  false
        mySubView.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: myInset).isActive = true
        mySubView.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: myInset).isActive = true
        mySubView.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: myInset * (-1)).isActive = true
        mySubView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor, constant: myInset * (-1)).isActive = true
        mySubView.clipsToBounds = true
       // mySubView.layer.cornerRadius = 8
        mySubView.contentMode = .scaleAspectFit

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


}

    if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellID", for: indexPath) as? QuickCell {
        cell.subviews.forEach { 
             if $0.tag == 333 {
               $0.removeFromSuperview()
             }
         }
        cell.backgroundColor = dataColors[indexPath.row]
        let mySubView = UIImageView()
        mySubView.tag = 333

这里的问题是,每次重复使用单元格时,都会添加一个新的
UIImageView
。在前面的
cellForItemAtIndexPath:
方法迭代中添加的那些不会消失,因此其他的会添加到顶部

以下是问题要点:

let mySubView = UIImageView()
mySubView.image = UIImage(named: theImages[indexPath.row])
cell.addSubview(mySubView)

最好在单元格初始化时(或在带有插座的故事板中)添加一次图像视图,然后在
cellForItemAtIndexPath:
方法中设置图像。

这里的问题是,每次重复使用单元格时,都要添加一个新的
UIImageView
。在前面的
cellForItemAtIndexPath:
方法迭代中添加的那些不会消失,因此其他的会添加到顶部

以下是问题要点:

let mySubView = UIImageView()
mySubView.image = UIImage(named: theImages[indexPath.row])
cell.addSubview(mySubView)

最好在单元格初始化时添加一次图像视图(或在带有插座的故事板中),然后在
cellForItemAtIndexPath:
方法中设置图像。

每次恢复集合视图单元格时,都会将类型为UIImageView的子视图添加到自定义单元格(QuickCell)。它发生在cellForRowAt委托方法中

因此,在添加新图像视图之前,必须先从单元格中删除以前添加的图像视图

我建议您将单元格配置代码移动到QuickCell

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellID", for: indexPath)
    if let quickCell = quickCell as? QuickCell {
        quickCell.backgroundColor = self.dataColors[indexPath.row]
        quickCell.setImage(self.theImages[indexPath.row], insetBy: self.myInset)
        return quickCell
    }
    return cell
}
在这里进行自定义单元格配置

class QuickCell: UICollectionViewCell {
    func setImage(_ image: UIImage, insetBy inset: CGFloat) {
        // Remove previously added image views first if any
        for subview in self.subviews where subview.isKind(of: UIImageView.self) {
            subview.removeFromSuperview()
        }
        let imageView = UIImageView()
        imageView.image = image
        imageView.clipsToBounds = true
        imageView.contentMode = .scaleAspectFit
        self.addSubview(imageView)

        imageView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            imageView.topAnchor.constraint(equalTo: self.topAnchor, constant: inset),
            imageView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: inset),
            imageView.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: inset * (-1)),
            imageView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: inset * (-1))
        ])
        self.layoutIfNeeded()
    }
}

每次恢复集合视图单元格时,都会将类型为UIImageView的子视图添加到自定义单元格(QuickCell)中。它发生在cellForRowAt委托方法中

因此,在添加新图像视图之前,必须先从单元格中删除以前添加的图像视图

我建议您将单元格配置代码移动到QuickCell

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellID", for: indexPath)
    if let quickCell = quickCell as? QuickCell {
        quickCell.backgroundColor = self.dataColors[indexPath.row]
        quickCell.setImage(self.theImages[indexPath.row], insetBy: self.myInset)
        return quickCell
    }
    return cell
}
在这里进行自定义单元格配置

class QuickCell: UICollectionViewCell {
    func setImage(_ image: UIImage, insetBy inset: CGFloat) {
        // Remove previously added image views first if any
        for subview in self.subviews where subview.isKind(of: UIImageView.self) {
            subview.removeFromSuperview()
        }
        let imageView = UIImageView()
        imageView.image = image
        imageView.clipsToBounds = true
        imageView.contentMode = .scaleAspectFit
        self.addSubview(imageView)

        imageView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            imageView.topAnchor.constraint(equalTo: self.topAnchor, constant: inset),
            imageView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: inset),
            imageView.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: inset * (-1)),
            imageView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: inset * (-1))
        ])
        self.layoutIfNeeded()
    }
}

这是UICollectionView默认选中的,请尝试取消选中它。它应该适合你。


这是UICollectionView默认选中的,请尝试取消选中它。它应该适合您。

我现在尝试了几个版本,但它仍然有重叠的图像。我插入了一行:
mySubView.image=nil
就在这行的上方
mySubView.image=UIImage(名为:theImages[indexPath.row])
。。。它应该去别的地方吗?我现在尝试了几个版本,但它仍然有重叠的图像。我插入了一行:
mySubView.image=nil
就在这行的上方
mySubView.image=UIImage(名为:theImages[indexPath.row])
。。。应该去别的地方吗?谢谢。我做了一点改变,效果很好。但我不明白为什么我不能从故事板链接和UIImageView并简单地更改图像?当UIImageView就在那里时,为什么会出现“unwrapped nil”错误?它应该是弱的还是不弱的?你也可以通过故事板来实现这一点。当我未能将IBOutlet链接到情节提要时,遇到了一个“unwrapped nil”错误。谢谢。我做了一点改变,效果很好。但我不明白为什么我不能从故事板链接和UIImageView并简单地更改图像?当UIImageView就在那里时,为什么会出现“unwrapped nil”错误?它应该是弱的还是不弱的?你也可以通过故事板来实现这一点。当我未能将IBOutlet链接到情节提要时,遇到了一个“unwrapped nil”错误。