我遇到UICollectionView中的单元格问题,当向上或向下滚动时图像混合在一起。它会混淆然后保持混合状态,否则它会恢复正常的顺序。
class booksVC: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {
var imageIdsonDB : [String] = []
var imageIds : [String] = []
@IBOutlet weak var collectionView: UICollectionView!
var posts = [Post]()
let db : DBHelper = DBHelper()
var arrayBooks = [BookModel]()
var selectedIndexPath : IndexPath = IndexPath()
var post: Post!
override func viewDidLayoutSubviews() {
adjustViewLayout(size: UIScreen.main.bounds.size)
}
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
for item in self.db.fetchAll() {
imageIdsonDB.append(item.id)
}
self.arrayBooks.removeAll()
self.arrayBooks.append(contentsOf: self.db.fetchAll())
self.collectionView.reloadData()
DataService.ds.REF_POSTS8.observe(.value, with: { (snapshot) in
if let snapshot = snapshot.children.allObjects as? [FIRDataSnapshot] {
for snap in snapshot {
print ("SNAP: \(snap)")
if let postDict = snap.value as? Dictionary<String, AnyObject>{
let key = snap.key
let post = Post(postKey: key , postData: postDict)
self.posts.append(post)
self.db.insertBook(id: postDict["id"] as! String, imgName: postDict["id"] as! String, imgPath: "", bookName: postDict["book_name"] as! String, bookPath: "", imageURL: postDict["image_path"] as! String, bookURL: postDict["book_path"] as! String, caption: "")
}
}
}
self.arrayBooks.removeAll()
self.arrayBooks.append(contentsOf: self.db.fetchAll())
self.collectionView.reloadData()
})
// update db for changed database data
for image in self.db.fetchAll() {
if !self.imageIds.contains(image.id) {
self.db.deleteBook(id: image.id)
}
}
self.collectionView.reloadData()
}
func getFilePath(name : String) -> String {
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let filePath = documentsPath+"/"+name
return filePath
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return arrayBooks.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let book = arrayBooks[indexPath.item]
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)as? collectionViewCellBooks {
SwiftLoader.hide()
cell.initWithBook(book: book)
return cell
} else {
return collectionViewCellBooks()
}
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.selectedIndexPath = indexPath
self.performSegue(withIdentifier: "showImage", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier == "showImage"
{
let vc = segue.destination as! showPdfVC
vc.book = self.arrayBooks[self.selectedIndexPath.row]
}
}
}
initwithBook
功能的代码是
func initWithBook(book : BookModel) {
self.caption.text = book.bookName
if book.thumbImagePaht == "" {
let ref = FIRStorage.storage().reference(forURL: book.imageURL)
let downloadTask = ref.data(withMaxSize: 4 * 1024 * 1024, completion: { (data,error) in
if error != nil {
}else {
if let imgData = data {
if let img = UIImage(data: imgData) {
self.imageView.image = img
let imageName = book.id+".jpg"
let filepath = self.getFilePath(name: imageName)
if (try? data?.write(to: URL(fileURLWithPath: filepath),options: [.atomic])) != nil {
self.db.upDateImagePath(id: book.id, imagePath: filepath)
}
self.stopLoading();
}
}
}
})
downloadTask.observe(.progress) { (snapshot) -> Void in
// Download reported progress
let percentComplete = 100 * Double(snapshot.progress!.completedUnitCount)
/ Double(snapshot.progress!.totalUnitCount)
print(percentComplete)
// Update the progress indicator
}
downloadTask.observe(.success) { (snapshot) -> Void in
// Download completed successfully
print("Download Success")
}
} else {
let image = UIImage(contentsOfFile: book.thumbImagePaht)
self.imageView.image = image
stopLoading();
}
)
答案 0 :(得分:2)
对我来说并不是什么可能是错的,但我看到一些可能导致问题的问题,最好修复它们:
在使用dequeueReusableCellWithIdentifier
的任何情况下,您都需要指定唯一且具有描述性的标识符。 “cell”不是一个好的标识符。
其次,当您创建新单元格时,需要为其指定一个重用标识符,以便以后可以将其出列。
第三,您没有遵循类的命名约定,即使用TitleCase。由于您命名为collectionViewCellBooks
的类,因此理解您的代码更加困难。它应该被命名为BookViewCell
或类似的东西。
第四,你的例子在你的Cell类中没有包含a prepareForReuse
function,所以我假设你没有。您需要清除以前使用单元格的状态,因为正在重用单元对象。此函数的默认实现不执行任何操作,因此您需要填充它。
class BooksViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
override func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let book = arrayBooks[indexPath.item]
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Constants.BookCellReuseIdentifier,
for: indexPath) as! BookViewCell
cell.initWithBook(book: book)
return cell
}
private struct Constants {
static let BookCellReuseIdentifier = "BookCell"
}
}
class BookViewCell: UICollectionViewCell {
override func prepareForReuse() {
// Remove any state in this cell that may be left over from its previous use.
self.book = nil
self.imageView.image = nil
self.caption = nil
}
// Your initWithBook function goes here
}
This is a good tutorial关于使用UICollectionView。