我目前面临困扰我数日的问题。我尝试了几种解决方案,但似乎无法解决该问题。让我说明发生了什么。
我有一个供稿,其中的帖子位于UITableView
中。用户选择一个单元格后,就会在新的UIViewController
中为他显示该帖子的详细视图。在其中,我设置了所有视图,并在loadPostDetails()
方法中调用了函数viewDidLoad()
。该视图一出现,就会显示一个自定义的加载指示器,该指示器设置为在加载详细信息后消失(隐藏),然后UITableView
的{{1}}(我们将其称为{{1} })。
在我的UIViewController
函数中,我做了一个HTTPRequest,它获取了我需要的JSON数据。这将返回三种信息:帖子详细说明自己,喜欢和评论。在重新加载PostController
并显示它之前,我需要处理这三个元素中的每一个。目前,我是这样的:
loadPostDetails()
注意:我向UITableView
添加了更多文本,例如用户的日期和个人资料图片,但是我删除了几行以使其更易读,并且因为多余的代码无关紧要对于这个问题。
现在,正如您可能已经看到的那样,我在1秒钟后调用了重载程序,因此在95%的情况下,它工作正常(但仍然不完美,因为它是“ hack”)。在另外5%的情况下,布局无法找出正确的约束条件,从而导致布局非常糟糕。
最近几天,我尝试与HTTP.retrievePostDetails(postID: postID, authRequired: true) { (error, postDetails) in
if(error != nil) {
self.navigationController?.popViewController(animated: true)
} else {
if let postDetails = postDetails, let postInfo = postDetails["postInfoRows"] as? [[String: Any]], let postLikesCount = postDetails["postLikesCount"] as? Int, let postLikesRows = postDetails["postLikesRows"] as? [[String: Any]], let postCommentsRows = postDetails["postCommentsRows"] as? [[String: Any]] {
DispatchQueue.main.async {
let tableFooterView = self.postTableView.tableFooterView as! tableFooterView
if let postTitle = postInfo[0]["postTitle"] as? String, let postText = postInfo[0]["postText"] as? String {
self.postTitleLabel.text = postTitle
self.postTextLabel.text = postText
}
for (index, postCommentRow) in postCommentsRows.enumerated() {
tableFooterView.postComments.append(Comment(userID: postCommentRow["userID"] as! Int, userProfilePicURL: postCommentRow["userProfilePicURL"] as! String, userDisplayName: postCommentRow["userDisplayName"] as! String, commentTimeStamp: postCommentRow["commentTimeStamp"] as! TimeInterval, commentText: postCommentRow["commentText"] as! String))
}
var likeDisplayNames = [String]()
for postLikeRow in postLikesRows {
likeDisplayNames.insert(postLikeRow["userDisplayName"] as! String, at: 0)
}
if(postLikesCount > 2) {
tableFooterView.likesLabel.text = "\(likeDisplayNames[0]), \(likeDisplayNames[1]) and \(postLikesCount - 2) others"
} else {
tableFooterView.likesLabel.text = "\(postLikesCount) likes"
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
self.screenDotsLoader.isHidden = true
self.screenDotsLoader.stopAnimating()
self.postTableView.isHidden = false
self.postTableView.reloadData()
})
}
}
}
一起玩,但是我不知道该怎么做。我实际上是想知道何时已执行所有任务,因此,当所有UILabels
已更新,所有DispatchGroups()
已更新等时,只有这样,我才想重新加载UILabels
我希望有人可以指出正确的方向,以便我可以进一步提高用户体验。谢谢!
答案 0 :(得分:1)
DispatchGroups
用于一起执行一堆异步任务,并且需要在所有任务完成时得到通知,但是当前您不执行此操作,因为当您收到响应时,它们都在内部同步线程(串行),这意味着重新加载表之前的所有工作都会在重新加载之前发生,因此,如果这对您的UX有意义,那么您可以自由使用dispatch