【发布时间】:2018-02-06 19:40:12
【问题描述】:
我在这里遇到了非常奇怪的问题。
基本上,用户来到一个附有 TableView 的 View。后端调用了一些数据,并在完成块中将该数据提供给 TableView 显示。
在 4 个可重用的 cellForRow 1 中,自定义单元格根据某种逻辑出列,然后调用该单元格的配置方法。
这就是它变得棘手的地方:一些单元格可能需要进一步的异步调用(为它们的自定义显示获取更多数据),因此需要一个 tableView.reloadRows 调用......那么,这两个可以最好地解释发生了什么截图:
在第一个单元格中,“有没有想过你会为克朗代克酒吧做什么?”复制在“演员的自我管理”单元的顶部,作为包含 Twitter 信息 DID 的单元,需要额外的异步调用来获取该数据。
有什么想法吗?我在 begin/endUpdates 块内运行 tableView.reloadRows 调用,但没有骰子。
cellForRow:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let postAtIndexPath = posts[indexPath.row]
let cell: PostCell!
if postAtIndexPath.rawURL == "twitter.com" {
cell = tableView.dequeueReusableCell(withIdentifier: "TwitterCell", for: indexPath) as! TwitterCell
} else if !postAtIndexPath.rawURL.isEmpty {
cell = tableView.dequeueReusableCell(withIdentifier: "LinkPreviewCell", for: indexPath) as! LinkPreviewCell
} else if postAtIndexPath.quotedID > -1 {
cell = tableView.dequeueReusableCell(withIdentifier: "QuoteCell", for: indexPath) as! QuoteCell
} else {
cell = tableView.dequeueReusableCell(withIdentifier: "PostCell", for: indexPath) as! PostCell
}
cell.isUserInteractionEnabled = true
cell.privacyDelegate = self
cell.shareDelegate = self
cell.likeDelegate = self
cell.linkPreviewDelegate = self
cell.reloadDelegate = self
postToIndexPath[postAtIndexPath.id] = indexPath
if parentView == "MyLikes" || parentView == "Trending" {
cell.privatePostButton.isHidden = true
cell.privatePostLabel.isHidden = true
}
cell.configureFor(post: postAtIndexPath,
liked: likesCache.postIsLiked(postId: postAtIndexPath.id),
postIdToAttributions: postIdToAttributions,
urlStringToOGData: urlStringToOGData,
imageURLStringToData: imageURLStringToData)
cell.contentView.layoutIfNeeded()
return cell
}
异步 Twitter 通话:
private func processForTwitter(og: OpenGraph, urlLessString: NSMutableAttributedString, completion:(() -> ())?) {
let ogURL = og[.url]!
let array = ogURL.components(separatedBy: "/")
let client = TWTRAPIClient()
let tweetID = array[array.count - 1]
if let tweet = twitterCache.tweet(forID: Int(tweetID)!) {
for subView in containerView.subviews {
subView.removeFromSuperview()
}
let tweetView = TWTRTweetView(tweet: tweet as? TWTRTweet, style: .compact)
containerView.addSubview(tweetView)
tweetView.translatesAutoresizingMaskIntoConstraints = false
tweetView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true
tweetView.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
containerView.leftAnchor.constraint(equalTo: tweetView.leftAnchor).isActive = true
containerView.rightAnchor.constraint(equalTo: tweetView.rightAnchor).isActive = true
containerView.isHidden = false
postText.isHidden = false
} else {
client.loadTweet(withID: tweetID, completion: { [weak self] (t, error) in
if let weakSelf = self {
if let tweet = t {
weakSelf.twitterCache.addTweetToCache(tweet: tweet, forID: Int(tweetID)!)
}
}
if let complete = completion {
complete()
}
})`enter code here`
}
if urlLessString.string.isEmpty {
if let ogTitle = og[.title] {
postText.text = String(htmlEncodedString: ogTitle)
}
} else {
postText.attributedText = urlLessString
}
}
tableviewcontroller 中的完成块:
func reload(postID: Int) {
tableView.beginUpdates()
self.tableView.reloadRows(at: [self.postToIndexPath[postID]!], with: .automatic)
tableView.endUpdates()
}
注意:这不会 100% 发生,它可能取决于网络。
【问题讨论】:
-
你可以试试 tableView.reloadData 代替 tableView.reloadRows
-
一个快速的建议 - 查看您的代码我没有看到任何后台调用,您可以尝试一下。将网络调用置于后台并在主线程上重新加载表格单元格。
标签: ios iphone swift uitableview custom-cell