我有一个CollectionView,它是从我的函数loadData中填充的,在其中使用DispatchGroup来确保正确下载了所有信息。然后将其放入两个数组:posts和userInfo,其中包含明显的信息:posts具有来自特定帖子的所有数据,包括来自作者的userID,userInfo具有基于userID的所有数据。
发生的事情是,它完美地显示了所有内容,即使我的自动布局也很完美。如果没有“注释”,则约束将发生变化,所有这些都将起作用。但是,当我向下滚动或有时滚动到最后一个单元格时(我想根据注释的高度,取决于注释的高度),该注释将不会显示。
上面的图片应该显示我的意思:左边有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语句,以像对其他值那样解开该语句,但这也不起作用。
答案 0 :(得分:0)
试图找出更多有关调度组,主线程如何工作以及所有其他方面的背景信息。最后想出了如何通过将DispatchQueue代码替换为以下方法来解决此问题:
dataGroup.notify(queue: .main, execute: {
self.collectionView?.reloadData()
})
我在帖子和userInfo数组都填满后执行此操作,因此在这些括号之后。它现在可以正常工作,并且只能执行一次,从而在我的CollectionView中获得完美的数据,并且也只能打印一次。