'NSInternalInconsistencyException',原因:“试图为无视图创建视图动画”

时间:2019-11-27 18:19:45

标签: ios swift

我的快速iOS应用程序出现问题:“由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'试图为无视图创建视图动画'”

有人可以在这里找到主要问题吗?谢谢!

背景:我正在使用Firebase,并试图将数据(从Firebase数据库)加载到UICollection视图。该问题正在解决从数据库检索数据的问题。

[问题在代码中的特定区域附近突出显示]

    import Foundation
    import UIKit
    import Firebase
    import ProgressHUD

    class CollectionViewController : UICollectionViewController {

        private var hiddenCells: [ExpandableCell] = []
        private var expandedCell: ExpandableCell?
        private var isStatusBarHidden = false

        var posts = [Post]()
        var fetchingMore = false
        var endReached = false
        let leadingScreensForBatching:CGFloat = 3.0

        var refreshControl:UIRefreshControl!


        var lastUploadedPostID:String?

        var postsRef:DatabaseReference {
            return Database.database().reference().child("posts")
        }

        var oldPostsQuery:DatabaseQuery {
            var queryRef:DatabaseQuery
            let lastPost = posts.last
            if lastPost != nil {
                let lastTimestamp = lastPost!.createdAt.timeIntervalSince1970 * 1000
                queryRef = postsRef.queryOrdered(byChild: "timestamp").queryEnding(atValue: lastTimestamp)
            } else {
                queryRef = postsRef.queryOrdered(byChild: "timestamp")
            }
            return queryRef
        }

        var newPostsQuery:DatabaseQuery {
            var queryRef:DatabaseQuery
            let firstPost = posts.first
            if firstPost != nil {
                let firstTimestamp = firstPost!.createdAt.timeIntervalSince1970 * 1000
                queryRef = postsRef.queryOrdered(byChild: "timestamp").queryStarting(atValue: firstTimestamp)
            } else {
                queryRef = postsRef.queryOrdered(byChild: "timestamp")
            }
            return queryRef
        }

        override var shouldAutorotate: Bool {
            return false
        }

        override var prefersStatusBarHidden: Bool {
            return isStatusBarHidden
        }


          override func viewDidLoad() {
              super.viewDidLoad()

              self.hideKeyboardWhenTappedAround()



            collectionView.delegate = self
            collectionView.dataSource = self
            collectionView.reloadData()

              refreshControl = UIRefreshControl()
              if #available(iOS 12.0, *) {
                  collectionView.refreshControl = refreshControl
              } else {
                  // Fallback on earlier versions
                  collectionView.addSubview(refreshControl)
              }




              beginBatchFetch()

          }

// **** ISSUE AROUND HERE VVV **** //

        func beginBatchFetch() {
            fetchingMore = true
            self.collectionView.reloadSections(IndexSet(integer: 0))

            fetchPosts { newPosts in
                self.posts.append(contentsOf: newPosts)
                self.fetchingMore = false
                self.endReached = newPosts.count == 0
                UIView.performWithoutAnimation {
                    self.collectionView.reloadData()

                    self.listenForNewPosts()
                }
            }
        }

        var postListenerHandle:UInt?

        func listenForNewPosts() {

            guard !fetchingMore else { return }

            // Avoiding duplicate listeners
            stopListeningForNewPosts()

            postListenerHandle = newPostsQuery.observe(.childAdded, with: { snapshot in

                if snapshot.key != self.posts.first?.id,
                    let data = snapshot.value as? [String:Any],
                    let post = Post.parse(snapshot.key, data) {

                    self.stopListeningForNewPosts()

                    if snapshot.key == self.lastUploadedPostID {
                        self.handleRefresh()
                        self.lastUploadedPostID = nil
                    } else {

                    }
                }
            })
        }

        @objc func handleRefresh() {
            print("Refresh!")

            newPostsQuery.queryLimited(toFirst: 10).observeSingleEvent(of: .value, with: { snapshot in
                var tempPosts = [Post]()

                let firstPost = self.posts.first
                for child in snapshot.children {
                    if let childSnapshot = child as? DataSnapshot,
                        let data = childSnapshot.value as? [String:Any],
                        let post = Post.parse(childSnapshot.key, data),
                        childSnapshot.key != firstPost?.id {

                        tempPosts.insert(post, at: 0)
                    }
                }

                self.posts.insert(contentsOf: tempPosts, at: 0)

                let newIndexPaths = (0..<tempPosts.count).map { i in
                    return IndexPath(row: i, section: 0)
                }


                self.refreshControl?.endRefreshing()


                    self.collectionView.scrollToItem(at: IndexPath(row: 0, section: 0), at: [], animated: true)
                    self.collectionView.insertItems(at: newIndexPaths)

                self.listenForNewPosts()

            })
        }

        func stopListeningForNewPosts() {
            if let handle = postListenerHandle {
                newPostsQuery.removeObserver(withHandle: handle)
                postListenerHandle = nil
            }
        }




        func fetchPosts(completion:@escaping (_ posts:[Post])->()) {
            oldPostsQuery.queryLimited(toLast: 20).observeSingleEvent(of: .value, with: { snapshot in
                var tempPosts = [Post]()

                let lastPost = self.posts.last
                for child in snapshot.children {
                    if let childSnapshot = child as? DataSnapshot,
                        let data = childSnapshot.value as? [String:Any],
                        let post = Post.parse(childSnapshot.key, data),
                        childSnapshot.key != lastPost?.id {

                        tempPosts.insert(post, at: 0)
                    }
                }

                return completion(tempPosts)
            })
        }


        // **** ISSUE ABOVE HERE ^^^ **** //


        override func numberOfSections(in collectionView: UICollectionView) -> Int {
            return 1
        }

        func collectionView(_ collectionView: UICollectionView, numberOfRowsInSection section: Int) -> Int {
            switch section {
            case 0:
                return posts.count
            case 1:
                return fetchingMore ? 1 : 0
            default:
                return 0
            }
        }



        // MARK: - UICollectionViewDelegates

        override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return posts.count
        }

        override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ExpandableCell", for: indexPath) as! ExpandableCell

            cell.set(post: posts[indexPath.row])

            return cell
        }





        override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
            if collectionView.contentOffset.y < 0 ||
                collectionView.contentOffset.y > collectionView.contentSize.height - collectionView.frame.height {
                return
            }


            let dampingRatio: CGFloat = 0.8
            let initialVelocity: CGVector = CGVector.zero
            let springParameters: UISpringTimingParameters = UISpringTimingParameters(dampingRatio: dampingRatio, initialVelocity: initialVelocity)
            let animator = UIViewPropertyAnimator(duration: 0.5, timingParameters: springParameters)


            self.view.isUserInteractionEnabled = false

            if let selectedCell = expandedCell {
                isStatusBarHidden = false

                animator.addAnimations {
                    selectedCell.collapse()

                    for cell in self.hiddenCells {
                        cell.show()
                    }
                }

                animator.addCompletion { _ in
                    collectionView.isScrollEnabled = true

                    self.expandedCell = nil
                    self.hiddenCells.removeAll()
                }
            } else {
                isStatusBarHidden = true

                collectionView.isScrollEnabled = false

                let selectedCell = collectionView.cellForItem(at: indexPath)! as! ExpandableCell
                let frameOfSelectedCell = selectedCell.frame

                expandedCell = selectedCell
                hiddenCells = collectionView.visibleCells.map { $0 as! ExpandableCell }.filter { $0 != selectedCell }

                animator.addAnimations {
                    selectedCell.expand(in: collectionView)

                    for cell in self.hiddenCells {
                        cell.hide(in: collectionView, frameOfSelectedCell: frameOfSelectedCell)
                    }
                }
            }


            animator.addAnimations {
                self.setNeedsStatusBarAppearanceUpdate()
            }

            animator.addCompletion { _ in
                self.view.isUserInteractionEnabled = true
            }

            animator.startAnimation()
        }
    }

0 个答案:

没有答案