提问者:小点点

为什么我的函数没有重新加载UITableView的数据?


我正在创建一个tableview,它可以监控来自几个账户的前20条tweet,并按时间顺序显示它们。 它调用Twitter API,然后遍历tweets并将它们添加到TableView中。 我的问题是,当我试图刷新tableview中的数据时,什么也不会发生。 我尝试再次调用getTwitterInfo(),但它不做任何事情,即使有新的tweet要显示。 我试过所有我能在网上找到的东西,但似乎没有什么能解决它。 如有任何帮助,我们将不胜感激--这里是我的视图控制器的代码。

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个答案

匿名用户

我假设您已经验证了没有从尝试中抛出异常,也没有从强制解包中崩溃。 我认为你应该做的是搬家

DispatchQueue.main.async{
    self.tableView.reloadData()
}

到它所在的if块的外部和后面。 我怀疑TableView.reloadData()没有被调用是因为它所在的if块中的条件检查失败。 试试看,如果对你有帮助就告诉我。 如果没有,你可以给我一个链接到你的项目最好是从GitHub。

如果你不想与运行iOS13更低版本的设备向下兼容,谷歌UITableViewDiffableDataSource。 用新的方法做要容易得多,节省了大量的麻烦,特别是当项目变得更加复杂,需要管理许多tableview状态更改时。 如果您想要查看它,这里有一个很好的起点:[https://developer.apple.com/videos/play/wwdc2019/220/][1]