我目前面临一个困扰我好几天的问题。我尝试了几种解决方案,但似乎无法解决问题。让我来说明发生了什么。
我在 UITableView
中有一个包含帖子的提要。一旦用户选择其中一个单元格,就会在新的 UIViewController
中向他显示这篇文章的详细 View 。在那里,我设置了所有 View 并在 viewDidLoad()
方法中调用函数 loadPostDetails()
。 View 一出现,就会显示一个自定义加载指示器,该指示器设置为在加载详细信息时消失(隐藏),然后是此 UIViewController
的 UITableView
(让我们调用它 PostController
) 显示。
在我的 loadPostDetails()
函数中,我创建了一个 HTTPRequest 来获取我需要的 JSON 数据。这将返回三种信息:帖子详细信息本身、点赞和评论。在重新加载 UITableView
并显示它之前,我需要处理这三个元素中的每一个。目前,我是这样做的:
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
添加了更多文本,例如用户的日期和个人资料图片,但我删除了几行以使其更易读,因为额外的代码与此问题无关。
现在,正如您可能已经看到的那样,我在 1 秒后调用重新加载,因此在 95% 的情况下它工作得很好(但仍然不完美,因为它是一个“hack”)。在另外 5% 中,布局无法找出正确的约束,导致布局非常糟糕。
我最近几天尝试使用 DispatchGroups()
,但我不知道该怎么做。事实上,我想知道所有任务何时执行,所以当所有 UILabels
已更新,所有 UIImageViews
已更新等。只有到那时,我想重新加载UITableView
。
我希望有人能给我指出正确的方向,这样我就可以进一步提升我的用户体验。谢谢!
最佳答案
DispatchGroups
当你一起做一堆异步任务时使用,并且需要在所有完成时得到通知,但目前你不这样做,因为当你收到响应时,所有都是在同步(串行)的主线程中,这意味着重新加载表之前的所有内容都将在重新加载之前发生,因此如果这对您的 UX 有意义,您可以自由使用 dispatch
关于ios - 如何知道 HTTPRequest 之后所有任务何时完成(Swift),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55329290/