2017-02-04 4 views
0

У меня проблема с ячейками в UICollectionView, где изображения смешиваются при прокрутке вверх или вниз. Он будет смешиваться, а затем оставаться смешанным, или он вернется к правильному порядку.UICollection View Cell смешивается, когда я прокручиваю

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

Показать код метода 'initWithBook'. –

+0

@NiravD, пожалуйста, проверьте код, добавленный мной – Khallad

ответ

1

Это не для меня очевидно, что может быть неправильно, но я вижу некоторые проблемы, которые могут возникнуть проблемы, и было бы лучше, чтобы исправить их:

В любом случае, когда вы используете dequeueReusableCellWithIdentifier, вам нужно указать уникальный и описательный идентификатор. «Ячейка» не является хорошим идентификатором.

Во-вторых, когда вы создаете новую ячейку, вам нужно предоставить идентификатор повторного использования, чтобы впоследствии ее можно было удалить.

В-третьих, вы не соблюдали соглашение об именах для классов, которое должно использовать TitleCase. Труднее понять ваш код из-за класса, который вы назвали collectionViewCellBooks. Его следует называть BookViewCell или что-то в этом роде.

В-четвертых, ваш пример не включал a prepareForReuse function в ваш класс Cell, поэтому я собираюсь предположить, что у вас его нет. Вам нужно очистить состояние от предыдущего использования ячейки, поскольку объекты ячейки повторно используются. По умолчанию реализация этой функции ничего не делает, поэтому вам нужно заполнить ее.

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.

+0

Я получаю сообщение об ошибке в этой строке cell = collectionViewCellAlbums (reuseIdentifier: Constants.BookCellReuseIdentifier) ​​"reuceIdentifier не соответствует какой-либо доступной перегрузке" – Khallad

+0

Мой первоначальный ответ был основан на UITableViewCell, и он превращается они разные. Я обновил свой ответ и связался с новым учебным пособием. –

Смежные вопросы