CollectionView 单元格混淆
CollectionView cells Confused
我正在忙于一个带有音板的语音应用程序,当您点击 CollectionView Cell 时,iPhone 将朗读文本。我的应用程序有一个小错误,我不知道是什么原因。
我构建了一个以图像作为背景视图的 CollectionView。它可以工作,但是当我转到另一个视图时,例如转到 Paint 视图,我会返回,然后单元格会混淆。
谁能告诉我哪里出了问题以及我是如何解决的?
谢谢!
这是我的代码:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
managedObjectContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
loadData()
let itemSize = UIScreen.main.bounds.width/2 - 5
let itemHeight = itemSize / 2
let layout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets.init(top: 3, left: 3, bottom: 3, right: 3)
layout.itemSize = CGSize(width: itemSize, height: itemHeight)
layout.minimumInteritemSpacing = 3
layout.minimumLineSpacing = 3
soundboard.collectionViewLayout = layout
navigationItem.rightBarButtonItem = editButtonItem
if(traitCollection.forceTouchCapability == .available){
registerForPreviewing(with: self as UIViewControllerPreviewingDelegate, sourceView: collectionView)
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
loadData()
}
func loadData() {
let soundRequest:NSFetchRequest<Soundboard> = Soundboard.fetchRequest()
do {
soundBoardData = try managedObjectContext.fetch(soundRequest)
self.soundboard.reloadData()
} catch {
print("Error")
}
}
// MARK: - Collection View
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return soundBoardData.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> soundboardCellVC {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! soundboardCellVC
let soundItem = soundBoardData[indexPath.row]
if let getCellPhoto = soundItem.photo as Data? {
cell.title.text = "";
let cellPhoto = UIImage(data: getCellPhoto)
let cellPhotoFrame = UIImageView(image:cellPhoto)
cellPhotoFrame.frame = CGRect(x: 0, y: 0, width: cell.frame.width, height: cell.frame.height)
cellPhotoFrame.contentMode = UIView.ContentMode.scaleAspectFill
cell.backgroundView = UIView()
cell.backgroundView!.addSubview(cellPhotoFrame)
}
else
{
cell.title.text = soundItem.title;
cell.backgroundColor = UIColor(red: CGFloat(soundItem.colorRed), green: CGFloat(soundItem.colorGreen), blue: CGFloat(soundItem.colorBlue), alpha: 1)
let fontAwesomeIcon = FAType(rawValue: Helper.FANames.index(of: soundItem.icon!)!)
cell.icon.setFAIconWithName(icon: fontAwesomeIcon!, textColor: UIColor.white)
}
cell.layer.cornerRadius = 10
cell.layer.masksToBounds = true
cell.delegate = self as SoundboardCellDelegate
return cell
}
单元格被重新使用,这意味着您要将新的图像视图添加到具有现有图像视图的单元格中。
您应该在 soundboardCellVC
class 中创建一个 UIImageView
,然后将图像简单地放入其中,或者根据需要将图像设置为 nil
。
其他几个风格要点:
按照惯例,classes 应该以大写字母开头,并且它是一个单元格子class,而不是视图控制器子class,所以它应该像 SoundboardCell
不是 soundboardCellVC
最后,您的 cellForItemAt
签名应与协议声明匹配并声明为返回 UICollectionViewCell
,而不是您的特定单元格 subclass:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
使用单元格时的一个好习惯是清除单元格重复使用时不想保留的所有属性。
https://developer.apple.com/documentation/uikit/uicollectionreusableview/1620141-prepareforreuse
例如,在您的单元格中 class 您可以:
override func prepareForReuse() {
super.prepareForReuse()
self.title.text = nil
}
这可以使您的 cellForItem
方法更清晰,并且您可以肯定地知道在您重用它之前 将执行上述操作。
我正在忙于一个带有音板的语音应用程序,当您点击 CollectionView Cell 时,iPhone 将朗读文本。我的应用程序有一个小错误,我不知道是什么原因。
我构建了一个以图像作为背景视图的 CollectionView。它可以工作,但是当我转到另一个视图时,例如转到 Paint 视图,我会返回,然后单元格会混淆。
谁能告诉我哪里出了问题以及我是如何解决的?
谢谢!
这是我的代码:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
managedObjectContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
loadData()
let itemSize = UIScreen.main.bounds.width/2 - 5
let itemHeight = itemSize / 2
let layout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets.init(top: 3, left: 3, bottom: 3, right: 3)
layout.itemSize = CGSize(width: itemSize, height: itemHeight)
layout.minimumInteritemSpacing = 3
layout.minimumLineSpacing = 3
soundboard.collectionViewLayout = layout
navigationItem.rightBarButtonItem = editButtonItem
if(traitCollection.forceTouchCapability == .available){
registerForPreviewing(with: self as UIViewControllerPreviewingDelegate, sourceView: collectionView)
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
loadData()
}
func loadData() {
let soundRequest:NSFetchRequest<Soundboard> = Soundboard.fetchRequest()
do {
soundBoardData = try managedObjectContext.fetch(soundRequest)
self.soundboard.reloadData()
} catch {
print("Error")
}
}
// MARK: - Collection View
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return soundBoardData.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> soundboardCellVC {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! soundboardCellVC
let soundItem = soundBoardData[indexPath.row]
if let getCellPhoto = soundItem.photo as Data? {
cell.title.text = "";
let cellPhoto = UIImage(data: getCellPhoto)
let cellPhotoFrame = UIImageView(image:cellPhoto)
cellPhotoFrame.frame = CGRect(x: 0, y: 0, width: cell.frame.width, height: cell.frame.height)
cellPhotoFrame.contentMode = UIView.ContentMode.scaleAspectFill
cell.backgroundView = UIView()
cell.backgroundView!.addSubview(cellPhotoFrame)
}
else
{
cell.title.text = soundItem.title;
cell.backgroundColor = UIColor(red: CGFloat(soundItem.colorRed), green: CGFloat(soundItem.colorGreen), blue: CGFloat(soundItem.colorBlue), alpha: 1)
let fontAwesomeIcon = FAType(rawValue: Helper.FANames.index(of: soundItem.icon!)!)
cell.icon.setFAIconWithName(icon: fontAwesomeIcon!, textColor: UIColor.white)
}
cell.layer.cornerRadius = 10
cell.layer.masksToBounds = true
cell.delegate = self as SoundboardCellDelegate
return cell
}
单元格被重新使用,这意味着您要将新的图像视图添加到具有现有图像视图的单元格中。
您应该在 soundboardCellVC
class 中创建一个 UIImageView
,然后将图像简单地放入其中,或者根据需要将图像设置为 nil
。
其他几个风格要点:
按照惯例,classes 应该以大写字母开头,并且它是一个单元格子class,而不是视图控制器子class,所以它应该像 SoundboardCell
不是 soundboardCellVC
最后,您的 cellForItemAt
签名应与协议声明匹配并声明为返回 UICollectionViewCell
,而不是您的特定单元格 subclass:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
使用单元格时的一个好习惯是清除单元格重复使用时不想保留的所有属性。
https://developer.apple.com/documentation/uikit/uicollectionreusableview/1620141-prepareforreuse
例如,在您的单元格中 class 您可以:
override func prepareForReuse() {
super.prepareForReuse()
self.title.text = nil
}
这可以使您的 cellForItem
方法更清晰,并且您可以肯定地知道在您重用它之前 将执行上述操作。