我正在尝试将一些图像放到CollectionViewCell上。在故事板上,我在视图控制器中有一个集合视图。
我还像这样将dequeueReusableCell标识符设置为“cell”。并将其注册到视图控制器的viewDidLoad上。identifier
问题是当我添加超过3~4个图像时,单元格中的图像突然就像这样乱了。
simulator
在我的猜测中,这是因为我一遍又一遍地添加子视图,所以图像视图似乎一直在堆积。我不知道怎么修。
我尝试在Cell的内容视图上初始化一个视图,但是没有成功。我还读了一个关于添加自定义单元格类和.xib文件并使用prepareForReuse()初始化单元格的解决方案。但这很难理解,我没能实现它。
这是我的'视图控制器'代码(* 我调整了UIImage的大小以适应Cell。它保持显示为裁剪的图像。我应用了一些ContentMode设置,但它根本不起作用。所以我决定调整UIImage的大小。)
import Foundation
import Tabman
class SecondTabViewController: TabmanViewController {
@IBOutlet weak var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
collectionView.reloadData()
}
}
//MARK: - CollectionView
extension SecondTabViewController: UICollectionViewDataSource,
UICollectionViewDelegate,
UICollectionViewDelegateFlowLayout
{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
let ad = UIApplication.shared.delegate as? AppDelegate
if let count = ad?.collectedImages.count {
print("cell count = \(count)")
return count
} else {
return 1
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let ad = UIApplication.shared.delegate as? AppDelegate
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as? UICollectionViewCell {
if let imageInfo = ad?.collectedImages[indexPath.row] {
// resizing an Image
let imageSize = imageInfo.imageData.size
let cellSize = CGSize(width: cell.frame.width, height: cell.frame.height)
let newSize = resizing(imageSize: imageSize, frameSize: cellSize)
let rect = CGRect(origin: .zero, size: newSize)
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
imageInfo.imageData.draw(in: rect)
let resizingImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
var initView: UIView?
if let newCgsize = resizingImage?.size {
initView = UIView(frame: CGRect(origin: .zero, size: newSize))
} else { print("resizing error.")}
let appendingView = UIView(frame: CGRect.init())
let appendingImageView = UIImageView(image: resizingImage)
appendingView.addSubview(appendingImageView)
if let safeInitView = initView {
cell.contentView.addSubview(safeInitView)
}
cell.contentView.addSubview(appendingView)
cell.backgroundColor = UIColor.systemBackground
}
return cell
}
else {
return UICollectionViewCell()
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let sectionInsets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
let width = collectionView.frame.width
let height = collectionView.frame.height
let itemsPerRow: CGFloat = 2
let widthPadding = sectionInsets.left * (itemsPerRow + 1)
let itemsPerColumn: CGFloat = 3
let heightPadding = sectionInsets.top * (itemsPerColumn + 1)
let cellWidth = (width - widthPadding) / itemsPerRow
let cellHeight = (height - heightPadding) / itemsPerColumn
return CGSize(width: cellWidth, height: cellHeight)
}
}
extension SecondTabViewController {
func resizing (imageSize: CGSize, frameSize: CGSize) -> CGSize {
var newSize = CGSize()
let widthRatio = imageSize.width / frameSize.width
let heightRatio = imageSize.height / frameSize.height
var ratio: Double
if heightRatio > widthRatio {
ratio = heightRatio
} else {
ratio = widthRatio
}
newSize.height = imageSize.height / ratio
newSize.width = imageSize.width / ratio
return newSize
}
}
===============
更新(Xav Mac)
不幸的是,我得到了一个错误。这些是我尝试过的:
- 从新的Files-Cocoa Touch类创建CustomCollectionViewCell类和.xib文件
- 在CustomCellectionViewCell.xib中,我添加了ImageView并设置自动布局以适应自定义单元格。并在CustomCollectionViewCell.swift上添加了prepareForReuse()
- 以下是CustomCollectionViewCell.swift代码:
class CustomCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var cellImageView: UIImageView!
override func prepareForReuse() {
cellImageView = nil
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
}
- 在viewDidLoad()
collectionView.register(CustomCollectionViewCell.self, forCellWithReuseIdentifier: "cell”)
中注册自定义单元格 - 删除情节提要上的可重用视图单元。(我以为我不需要它,因为我已经注册了手机从.xib)
- 我这样编辑cellForItemAt func:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let ad = UIApplication.shared.delegate as? AppDelegate
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as? CustomCollectionViewCell {
if let imageInfo = ad?.collectedImages[indexPath.row] {
cell.cellImageView.image = imageInfo.imageData
cell.cellImageView.contentMode = UIImageView.ContentMode.scaleAspectFit
}
return cell
}
else {
return CustomCollectionViewCell()
}
}
我得到的错误是:/:75:致命错误:隐式解包Optional value时意外发现nil 2023-06-27 18:51:47.361942+0900**[**]/:75:致命错误:隐式展开Optional值时意外发现nil
1条答案
按热度按时间yfwxisqw1#
代码中的问题是,当collectionView重用单元格时,它将在单元格中添加新的子视图(堆叠图像效果)。
所以我在这里看到了两个解决方案,好的和坏的。
好方法:
所以之后你可以做:
PS:不要忘记在单元格的“prepareForReuse”中将imageView.image设置为nil,以避免图像毛刺。
坏方法:
在单元格中添加新的子视图之前,需要清理前一个子视图的单元格层次结构。所以你会有这样的东西
希望对你有帮助!