滚动后未填充CollectionView

时间:2018-10-04 19:04:57

标签: ios swift uicollectionview uicollectionviewcell

我有一个CollectionView,它是从我的函数loadData中填充的,在其中使用DispatchGroup来确保正确下载了所有信息。然后将其放入两个数组:posts和userInfo,其中包含明显的信息:posts具有来自特定帖子的所有数据,包括来自作者的userID,userInfo具有基于userID的所有数据。

发生的事情是,它完美地显示了所有内容,即使我的自动布局也很完美。如果没有“注释”,则约束将发生变化,所有这些都将起作用。但是,当我向下滚动或有时滚动到最后一个单元格时(我想根据注释的高度,取决于注释的高度),该注释将不会显示。

Missing Notes

上面的图片应该显示我的意思:左边有7个帖子,右边有8个帖子。在两侧,您都可以看到滚动后或CollectionView末尾的第一条或多条帖子没有注释,但是单元格足够高,因此可以容纳。

据我了解,该问题发生在cellForItemAt方法中。在sizeForItemAt方法中,高度是根据音符的长度计算的,一切都很顺利(因为单元格的高度适应性很好)。

这是我的cellForItemAt方法的样子:

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

    if let userID = posts[indexPath.item].userID {
        if let userFirstName = userInfo[userID]?.userFirstName, let userLastName = userInfo[userID]?.userLastName {
            socialCell.usernameLabel.text = userFirstName + " " + userLastName
        }
    }

    if let wsName = posts[indexPath.item].postName {
        socialCell.postNameLabel.text = wsName
    }

    socialCell.noteTextView.text = posts[indexPath.item].postNote

    if(posts[indexPath.item].postNote == "") {
        socialCell.noteTextView.removeFromSuperview()
        socialCell.postDetailsView.bottomAnchor.constraint(equalTo: socialCell.noteTextView.bottomAnchor).isActive = false
        socialCell.postDetailsView.bottomAnchor.constraint(equalTo: socialCell.postNameLabel.bottomAnchor).isActive = true
    }

    // all other elements are set here, precisely the same way as the name of the post, so irrelevant

    socialCell.layer.shouldRasterize = true
    socialCell.layer.rasterizationScale = UIScreen.main.scale

    return socialCell
}

我认为它与indexPath.item有关–在某种程度上,当我滚动或到达可见区域的末尾(我想应该是在调用cellForItemAt时),indexPath下车,重置或其他原因。

任何解决此问题的想法将由衷地感谢。预先谢谢你!

编辑:我现在要打印一些信息,因为我想添加个人资料图片,但是注意到一些有用的东西:

print(userFirstName, " (", indexPath.item, "): ", userProfilePicURL)

我正在打印名字,索引路径和个人资料图片的URL,在加载时会给出此输出(它确实包含正确的URL,我只是将其隐藏了):

Penny  ( 0 ):  URL
Penny  ( 1 ):  URL
Penny  ( 3 ):  URL
Penny  ( 4 ):  URL
Penny  ( 0 ):  URL
Penny  ( 1 ):  URL
Andrea  ( 2 ):  URL
Penny  ( 3 ):  URL
Penny  ( 4 ):  URL
Andrea  ( 5 ):  URL

两个观察:输出被返回两次,所以我认为单元被重新加载了两次。并且第一次缺少indexPath 2和5。这是我获取数据并在loadData中重新加载CollectionView的方法:

    var Ref: DatabaseReference!
    Ref = Database.database().reference()

    Ref.child("posts").queryOrdered(byChild: "postReverseTimeStamp").observeSingleEvent(of: .value) { (snapshot) in

        let dataGroup = DispatchGroup()

        for child in snapshot.children {

            dataGroup.enter()

            let snap = child as! DataSnapshot
            let dict = snap.value as! [String: Any]

            self.posts.append(post(postID: snap.key, userID: dict["userID"] as! String, postName: dict["postName"] as! String, postNote: dict["postNote"]! as! String, postDuration: dict["postDuration"]! as! Int, postTimeStamp: dict["postTimeStamp"] as! TimeInterval, postLikes: dict["postLikes"]! as! Int, postComments: dict["postComments"]! as! Int))

            Ref.child("users").child(dict["userID"] as! String).observeSingleEvent(of: .value) { (snapshot) in

                let userValues = snapshot.value as! [String: Any]

                userInfo[dict["userID"] as! String] = userData(userFirstName: userValues["userFirstName"] as? String, userLastName: userValues["userLastName"] as? String, userProfilePicURL: userValues["userProfilePicURL"] as? String)

                dataGroup.leave()

                DispatchQueue.main.async {

                    self.collectionView?.reloadData()

                }

            }

        }

    }

编辑2:如果我将reloadData代码(包括DispatchQueue.main.async)移至for child语句之外,则在显示所有注释时效果很好,但随后不显示用户名和个人资料图片。从字面上看,不知道这是怎么回事。

编辑3:仍在积极尝试解决此问题。尚未这样做,但是我确实在cellForItemAt中的每个声明之后添加了一条打印语句,在这里我设置了标签和文本视图的内容。我希望它可以帮助我找出在哪里可以找到问题,但是没有,因为它返回以下内容:

now working on cell:  0
username:  Penny   Wise
workout name:  Test
note:  
now working on cell:  1
username:  Penny   Wise
workout name:  Test
note:  
now working on cell:  2
workout name:  Another Activity
note:  Testing the basic functionality of the feed system
now working on cell:  3
username:  Penny   Wise
workout name:  Activity
note:  Nothing special. Just trying out a very long note here, to see if it wraps nicely inside the cell.
now working on cell:  4
username:  Penny   Wise
workout name:  Testing this out!
note:  Adding an optional note. Nothing interesting can be found here, but still.
now working on cell:  5
workout name:  Some Random Activity
note:  With a random note attached to it!
now working on cell:  0
username:  Penny   Wise
workout name:  Test
note:  
now working on cell:  1
username:  Penny   Wise
workout name:  Test
note:  
now working on cell:  2
username:  Andrea   Capella
workout name:  Another Activity
note:  Testing the basic functionality of the feed system
now working on cell:  3
username:  Penny   Wise
workout name:  Activity
note:  Nothing special. Just trying out a very long note here, to see if it wraps nicely inside the cell.
now working on cell:  4
username:  Penny   Wise
workout name:  Testing this out!
note:  Adding an optional note. Nothing interesting can be found here, but still.
now working on cell:  5
username:  Andrea   Capella
workout name:  Some Random Activity
note:  With a random note attached to it!
now working on cell:  0
username:  Penny   Wise
workout name:  Test
note:  
now working on cell:  1
username:  Penny   Wise
workout name:  Test
note:  
now working on cell:  2
username:  Andrea   Capella
workout name:  Another Activity
note:  Testing the basic functionality of the feed system
now working on cell:  3
username:  Penny   Wise
workout name:  Activity
note:  Nothing special. Just trying out a very long note here, to see if it wraps nicely inside the cell.
now working on cell:  4
username:  Penny   Wise
workout name:  Testing this out!
note:  Adding an optional note. Nothing interesting can be found here, but still.
now working on cell:  5
username:  Andrea   Capella
workout name:  Some Random Activity
note:  With a random note attached to it!

它会打印所有内容三遍。这也是我无法解决的问题,但不是我最大的问题。如您所见,注释显示在print语句中,因此我无法弄清楚为什么未在这些特定的单元格中设置它们(在上述情况下使用indexPath 4和5)。因此,我错过了“添加可选注释。这里找不到有趣的东西,但是仍然可以。”和“附带随机注释!”在我的应用中,如屏幕截图所示。在我看来,设置此注释的方式确实有问题,因此此行:

socialCell.noteTextView.text = posts[indexPath.item].postNote

但是我不知道这可能是什么。现在,我试图添加一个if let语句,以像对其他值那样解开该语句,但这也不起作用。

1 个答案:

答案 0 :(得分:0)

试图找出更多有关调度组,主线程如何工作以及所有其他方面的背景信息。最后想出了如何通过将DispatchQueue代码替换为以下方法来解决此问题:

dataGroup.notify(queue: .main, execute: {
    self.collectionView?.reloadData()
})

我在帖子和userInfo数组都填满后执行此操作,因此在这些括号之后。它现在可以正常工作,并且只能执行一次,从而在我的CollectionView中获得完美的数据,并且也只能打印一次。