路径异常无效

时间:2017-10-12 18:01:47

标签: swift firebase scroll firebase-realtime-database

我能够滚动到collectionView的底部,但有时它会抛出一个无效路径异常。我已经尝试检查numberOfSections和numberOfItemsInSection但是错误仍然有时会显示,我的应用程序崩溃了。我也尝试使用setContentOffset方法进行滚动,但错误仍然有时会出现。

这是我用来滚动到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)
    }

我也试过这个:

      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)
                }
                }
            })

2 个答案:

答案 0 :(得分:0)

可能发生的是竞争条件,您正在尝试self.collectionView?.reloadData()并尝试将collectionView滚动到底部。有时候物品还没有准备就绪,这就是为什么你会得到一个例外。

此外,您似乎有一些嵌套的async调用。你应该做什么:

  1. self.collectionView?.reloadData()移出dispatch
  2. 在执行indexPath之前,检查您尝试滚动到的scrollToItem的项目是否确实存在。
  3. 另一种方法可能是,不是在Firebase调用内部滚动,而是在Item内创建最后UICollectionViewDataSource时检查,然后执行滚动操作。

答案 1 :(得分:0)

您可以使用IndexPathvar numberOfSections: Int { get }

检查func numberOfItems(inSection section: Int) -> Int是否正确

所以你可以这样做:

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)
                 } 
             }
         }

}