2017-10-12 2 views
0

Je suis en mesure de faire défiler vers le bas de la collection, mais parfois il déclenche une exception de chemin non valide. J'ai essayé de vérifier numberOfSections et numberOfItemsInSection mais l'erreur apparaît parfois et mon application tombe en panne. J'ai également essayé d'utiliser la méthode setContentOffset pour faire défiler mais l'erreur apparaît parfois.Exception de chemin invalide

C'est le code que j'utilise pour faire défiler vers le bas du CollectionView:

guard let uid = FIRAuth.auth()?.currentUser?.uid, let toId = user?.id else { 
     return 
    } 


    let userMessagesRef = FIRDatabase.database().reference().child("user-messages").child(uid).child(toId) 
    userMessagesRef.observe(.childAdded, with: { (snapshot) in 

    guard let messageId = snapshot.key as? String else { 
      return 
     } 

       let messagesRef = FIRDatabase.database().reference().child("messages").child(messageId) 
     messagesRef.observeSingleEvent(of: .value, with: { (snapshot) in 


      guard let dictionary = snapshot.value as? [String: AnyObject] else { 
       return 
      } 


      self.messages.append(Message(dictionary: dictionary)) 

      DispatchQueue.main.async(execute: { 
       self.collectionView?.reloadData() 
       //scroll to the last index 

        if self.messages.count > 0 { 
        if let indexPath = IndexPath(item: self.messages.count - 1, section: 0) as? IndexPath? { 
        self.collectionView?.scrollToItem(at: indexPath!, at: .bottom, animated: false) 
       } 
       } 
      }) 

      }, withCancel: nil) 

     }, withCancel: nil) 
    } 

J'ai aussi essayé ceci:

 DispatchQueue.main.async(execute: { 
       self.collectionView?.reloadData() 
       //scroll to the last index 

        if let _ = self.collectionView?.dataSource?.collectionView(self.collectionView!, cellForItemAt: IndexPath(row: 0, section: 0)) { 
        if let indexPath = IndexPath(item: self.messages.count - 1, section: 0) as? IndexPath? { 
        self.collectionView?.scrollToItem(at: indexPath!, at: .bottom, animated: false) 
       } 
       } 
      }) 
+0

double possible de [Faire défiler vers le bas de CollectionView sans animation et sans chemin non valide exception] (https://stackoverflow.com/questions/46700716/scroll-to-bottom-of-collectionview-without-animation-and-without-invalid-path-ex) – jvrmed

+0

Désolé cette question n'a pas été répondue et donc j'avais pour poster à nouveau! Je supprime cette question. –

+0

si vous pouvez partager plus de détails sur l'erreur de message d'erreur (impressions, journaux, etc.), il sera plus facile de vous guider quelque part – jvrmed

Répondre

0

Vous pouvez vérifier si la IndexPath est correcte à l'aide var numberOfSections: Int { get } et func numberOfItems(inSection section: Int) -> Int

de sorte que vous pouvez faire quelque chose comme ceci:

DispatchQueue.main.async { 

     self.collectionView?.reloadData() 
     if self.collectionView?.numberOfSections > 0 { 
      //you can decide which section to choose if you have more than one section but I am here using 0 for now... 
      let numberOfItemsInSection = self.collectionView?.numberOfItems(inSection: 0) 

      if numberOfItemsInSection > 0 { 
       if let indexPath = IndexPath(item: numberOfItemsInSection - 1, section: 0) as? IndexPath { 
        self.collectionView?.scrollToItem(at: indexPath, at: .bottom, animated: false) 
       } 
      } 
     } 

} 
0

Ce qui est probablement passe est une condition de course, vous font self.collectionView?.reloadData() et immédiatement après avoir essayé de faire défiler le collectionView vers le bas. Il est possible que parfois l'objet n'est pas encore prêt et c'est pourquoi vous obtenez une exception.

En outre, il semble que vous avez des appels async imbriqués. Ce que vous devez faire:

  1. Déplacer self.collectionView?.reloadData() sur dispatch.
  2. Vérifiez si l'élément pour le indexPath que vous essayez de faire défiler existe réellement avant de faire scrollToItem.

Une autre approche pourrait être qu'au lieu de faire défiler à l'intérieur vous Firebase appel, vous avez coché chaque fois que le dernier Item est créé dans le UICollectionViewDataSource puis exécuté l'action de défilement.

+0

Pouvez-vous s'il vous plaît me donner un exemple de code créé dans UICollectionViewDataSource? –