为啥我的函数没有重新加载 UITableView 的数据?
Posted
技术标签:
【中文标题】为啥我的函数没有重新加载 UITableView 的数据?【英文标题】:Why isn't my function reloading the UITableView's data?为什么我的函数没有重新加载 UITableView 的数据? 【发布时间】:2020-10-10 09:24:13 【问题描述】:我正在创建一个表格视图,用于监控来自几个帐户的前 20 条推文并按时间顺序显示它们。它调用 Twitter API,然后遍历推文并将它们添加到 tableview。我的问题是,当我尝试刷新 tableview 中的数据时,什么也没有发生。我尝试再次调用 getTwitterInfo() ,但即使有新的推文要显示,它也不会做任何事情。我已经尝试了所有可以在网上找到的方法,但似乎没有任何解决方法。任何帮助将不胜感激——这是我的视图控制器的代码。
class TwitterViewController: UIViewController
var tableView = UITableView()
var tweets = [Tweet]()
let cellID = "cellID"
var accounts: [String:String] = [
//this is just a dictionary of the accounts I'm monitoring and their corresponding profile picture
]
override func viewDidLoad()
super.viewDidLoad()
navigationController?.setNavigationBarHidden(true, animated: false)
configureTableView()
getTwitterInfo()
func configureTableView()
view.addSubview(tableView)
tableView.delegate = self
tableView.dataSource = self
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 150
tableView.register(TweetCell.self, forCellReuseIdentifier: cellID)
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
tableView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
tableView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
func getTwitterInfo()
print("getting new info...")
tweets = [Tweet]()
var counter = 1
for (name, pfpLink) in accounts
let imageURL = URL(string:pfpLink)!
var image = UIImage()
let imageDataTask = URLSession.shared.dataTask(with: imageURL) (data,response,error) in
image = UIImage(data:data!)!
imageDataTask.resume()
let url = URL(string: "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=\(name)&count=20&tweet_mode=extended")!
var request = URLRequest(url: url)
request.allHTTPHeaderFields = ["Authorization": Constants.bearer]
let dataTask = URLSession.shared.dataTask(with: request) (data,response,error) in
do
let data = try JSONSerialization.jsonObject(with: data!, options: []) as? [[String:Any]]
let _ = data!.map
let htmlEncodedString = $0["full_text"] as! String
let message: String
if let newDict = $0["retweeted_status"] as? Dictionary<String,Any>
let newEncodedString = newDict["full_text"] as! String
message = Constants.decodeTwitterString(newEncodedString)
else
message = Constants.decodeTwitterString(htmlEncodedString)
let userInfo = $0["user"] as! Dictionary<String,Any>
let screenName = userInfo["screen_name"] as! String
let username = userInfo["name"] as! String
let twitterID = userInfo["id_str"] as! String
let dateString = $0["created_at"] as! String
let tweet = Tweet(name: username, username: screenName, message: message, twitterID: twitterID, image:image, dateString: dateString)
self.tweets.append(tweet)
if (counter == self.accounts.keys.count)
let formatter = DateFormatter()
formatter.dateFormat = "EE LLL dd HH:mm:ss Z yyyy"
self.tweets = self.tweets.sorted
formatter.date(from: $0.dateString)! > formatter.date(from: $1.dateString)!
DispatchQueue.main.async
self.tableView.reloadData()
counter += 1
catch let err
print(err)
dataTask.resume()
extension TwitterViewController: UITableViewDelegate, UITableViewDataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return tweets.count
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: cellID, for: indexPath) as! TweetCell
let tweet = tweets[indexPath.row]
cell.set(tweet:tweet)
cell.selectionStyle = .none
return cell
【问题讨论】:
【参考方案1】:我假设你已经验证了 try 没有抛出异常,并且强制 unwrap 没有崩溃。我认为你应该做的是移动
DispatchQueue.main.async
self.tableView.reloadData()
到它所在的 if 块的外部和之后。我怀疑 tableView.reloadData() 没有被调用,因为它所在的 if 块中的条件检查失败。试试看,让我知道它是否对您有帮助。如果没有,您最好从 GitHub 向我发送指向您项目的链接。
如果您不想向后兼容运行 ios 13 更低版本的设备,请使用 Google UITableViewDiffableDataSource。用新方法来做这件事要容易得多,特别是当项目变得有点复杂时,需要管理许多 tableview 状态更改,从而为您省去很多麻烦。如果您想查看它,这是一个很好的起点:[https://developer.apple.com/videos/play/wwdc2019/220/][1]
【讨论】:
我只是在该块内放了一个打印语句,它确实最终打印了 - 似乎一切都在运行,但由于某种原因它无法正常工作。 我刚刚发现似乎是问题所在。我从另一个视图控制器调用 getTwitterInfo(),我想当我调用它时我必须把它放在它自己的 Dispatch.main.async 块中。我真的不明白为什么,但是嘿,它有效。无论如何感谢您的帮助! 跟进:我还必须以编程方式创建 TwitterVIewController 的实例,而不是通过情节提要实例化它。超级奇怪——我不确定这会如何改变任何事情,但它只能这样工作。以上是关于为啥我的函数没有重新加载 UITableView 的数据?的主要内容,如果未能解决你的问题,请参考以下文章