Swift 如何从UIImageView中清除图像
我在Swift中有以下用于合成布局的代码,但我的图像不会随着单元格的重用而消失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
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”错误。