Swift CollectionViewCell中的图像重叠问题

1tu0hz3e  于 2023-06-28  发布在  Swift
关注(0)|答案(1)|浏览(201)

我正在尝试将一些图像放到CollectionViewCell上。在故事板上,我在视图控制器中有一个集合视图。
我还像这样将dequeueReusableCell标识符设置为“cell”。并将其注册到视图控制器的viewDidLoad上。identifier
问题是当我添加超过3~4个图像时,单元格中的图像突然就像这样乱了。
simulator
在我的猜测中,这是因为我一遍又一遍地添加子视图,所以图像视图似乎一直在堆积。我不知道怎么修。
我尝试在Cell的内容视图上初始化一个视图,但是没有成功。我还读了一个关于添加自定义单元格类和.xib文件并使用prepareForReuse()初始化单元格的解决方案。但这很难理解,我没能实现它。
这是我的'视图控制器'代码(* 我调整了UIImage的大小以适应Cell。它保持显示为裁剪的图像。我应用了一些ContentMode设置,但它根本不起作用。所以我决定调整UIImage的大小。)

  1. import Foundation
  2. import Tabman
  3. class SecondTabViewController: TabmanViewController {
  4. @IBOutlet weak var collectionView: UICollectionView!
  5. override func viewDidLoad() {
  6. super.viewDidLoad()
  7. collectionView.dataSource = self
  8. collectionView.delegate = self
  9. collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
  10. }
  11. override func viewDidAppear(_ animated: Bool) {
  12. super.viewDidAppear(animated)
  13. collectionView.reloadData()
  14. }
  15. }
  16. //MARK: - CollectionView
  17. extension SecondTabViewController: UICollectionViewDataSource,
  18. UICollectionViewDelegate,
  19. UICollectionViewDelegateFlowLayout
  20. {
  21. func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
  22. let ad = UIApplication.shared.delegate as? AppDelegate
  23. if let count = ad?.collectedImages.count {
  24. print("cell count = \(count)")
  25. return count
  26. } else {
  27. return 1
  28. }
  29. }
  30. func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  31. let ad = UIApplication.shared.delegate as? AppDelegate
  32. if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as? UICollectionViewCell {
  33. if let imageInfo = ad?.collectedImages[indexPath.row] {
  34. // resizing an Image
  35. let imageSize = imageInfo.imageData.size
  36. let cellSize = CGSize(width: cell.frame.width, height: cell.frame.height)
  37. let newSize = resizing(imageSize: imageSize, frameSize: cellSize)
  38. let rect = CGRect(origin: .zero, size: newSize)
  39. UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
  40. imageInfo.imageData.draw(in: rect)
  41. let resizingImage = UIGraphicsGetImageFromCurrentImageContext()
  42. UIGraphicsEndImageContext()
  43. var initView: UIView?
  44. if let newCgsize = resizingImage?.size {
  45. initView = UIView(frame: CGRect(origin: .zero, size: newSize))
  46. } else { print("resizing error.")}
  47. let appendingView = UIView(frame: CGRect.init())
  48. let appendingImageView = UIImageView(image: resizingImage)
  49. appendingView.addSubview(appendingImageView)
  50. if let safeInitView = initView {
  51. cell.contentView.addSubview(safeInitView)
  52. }
  53. cell.contentView.addSubview(appendingView)
  54. cell.backgroundColor = UIColor.systemBackground
  55. }
  56. return cell
  57. }
  58. else {
  59. return UICollectionViewCell()
  60. }
  61. }
  62. func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
  63. let sectionInsets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
  64. let width = collectionView.frame.width
  65. let height = collectionView.frame.height
  66. let itemsPerRow: CGFloat = 2
  67. let widthPadding = sectionInsets.left * (itemsPerRow + 1)
  68. let itemsPerColumn: CGFloat = 3
  69. let heightPadding = sectionInsets.top * (itemsPerColumn + 1)
  70. let cellWidth = (width - widthPadding) / itemsPerRow
  71. let cellHeight = (height - heightPadding) / itemsPerColumn
  72. return CGSize(width: cellWidth, height: cellHeight)
  73. }
  74. }
  75. extension SecondTabViewController {
  76. func resizing (imageSize: CGSize, frameSize: CGSize) -> CGSize {
  77. var newSize = CGSize()
  78. let widthRatio = imageSize.width / frameSize.width
  79. let heightRatio = imageSize.height / frameSize.height
  80. var ratio: Double
  81. if heightRatio > widthRatio {
  82. ratio = heightRatio
  83. } else {
  84. ratio = widthRatio
  85. }
  86. newSize.height = imageSize.height / ratio
  87. newSize.width = imageSize.width / ratio
  88. return newSize
  89. }
  90. }

===============

更新(Xav Mac)

不幸的是,我得到了一个错误。这些是我尝试过的:

  • 从新的Files-Cocoa Touch类创建CustomCollectionViewCell类和.xib文件
  • 在CustomCellectionViewCell.xib中,我添加了ImageView并设置自动布局以适应自定义单元格。并在CustomCollectionViewCell.swift上添加了prepareForReuse()
  • 以下是CustomCollectionViewCell.swift代码:
  1. class CustomCollectionViewCell: UICollectionViewCell {
  2. @IBOutlet weak var cellImageView: UIImageView!
  3. override func prepareForReuse() {
  4. cellImageView = nil
  5. }
  6. override func awakeFromNib() {
  7. super.awakeFromNib()
  8. // Initialization code
  9. }
  10. }
  • 在viewDidLoad()collectionView.register(CustomCollectionViewCell.self, forCellWithReuseIdentifier: "cell”)中注册自定义单元格

  • 删除情节提要上的可重用视图单元。(我以为我不需要它,因为我已经注册了手机从.xib)
  • 我这样编辑cellForItemAt func:
  1. func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  2. let ad = UIApplication.shared.delegate as? AppDelegate
  3. if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as? CustomCollectionViewCell {
  4. if let imageInfo = ad?.collectedImages[indexPath.row] {
  5. cell.cellImageView.image = imageInfo.imageData
  6. cell.cellImageView.contentMode = UIImageView.ContentMode.scaleAspectFit
  7. }
  8. return cell
  9. }
  10. else {
  11. return CustomCollectionViewCell()
  12. }
  13. }

我得到的错误是:/:75:致命错误:隐式解包Optional value时意外发现nil 2023-06-27 18:51:47.361942+0900**[**]/:75:致命错误:隐式展开Optional值时意外发现nil

yfwxisqw

yfwxisqw1#

代码中的问题是,当collectionView重用单元格时,它将在单元格中添加新的子视图(堆叠图像效果)。
所以我在这里看到了两个解决方案,好的和坏的。

好方法:

  • 创建自定义UICollectionViewCell(例如:CustomCollectionViewCell)
  • 根据视图添加具有顶部/左侧/右侧/底部约束的UIImageView(将纵横比设置为AspectFit以适合UIImageView中的图像

所以之后你可以做:

  1. if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as? CustomCollectionViewCell {
  2. cell.imageView.image = //your image
  3. }

PS:不要忘记在单元格的“prepareForReuse”中将imageView.image设置为nil,以避免图像毛刺。

坏方法:

在单元格中添加新的子视图之前,需要清理前一个子视图的单元格层次结构。所以你会有这样的东西

  1. cell.contentView.subviews.forEach({ $0.removeFromSuperview() })

希望对你有帮助!

展开查看全部

相关问题