Ios tableView不刷新

Ios tableView不刷新,ios,swift,firebase,tableview,Ios,Swift,Firebase,Tableview,我刚开始编程,目前正在构建一个从Firebase收集数据的应用程序 我想当视图被拉下时,实现这个令人耳目一新的动画会很好。现在我遇到了一个问题,没有任何东西可以刷新(一开始工作正常)。此外,每次应用程序启动时,tableView最初是空的,当您按下按钮时,它会重新加载,但错误 我真的很挣扎。有人能看到我的代码有什么错误吗 class ViewController: BaseViewController, UITableViewDelegate, UITableViewDataSource {

我刚开始编程,目前正在构建一个从Firebase收集数据的应用程序

我想当视图被拉下时,实现这个令人耳目一新的动画会很好。现在我遇到了一个问题,没有任何东西可以刷新(一开始工作正常)。此外,每次应用程序启动时,tableView最初是空的,当您按下按钮时,它会重新加载,但错误

我真的很挣扎。有人能看到我的代码有什么错误吗

class ViewController: BaseViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet var newsfeedTableView: UITableView!
    @IBOutlet weak var activityIndicatorView: UIActivityIndicatorView!

    private let refreshControl = UIRefreshControl()

    var ref: DatabaseReference!

    var posts = [String]()
    var timeRef = [String]()
    var userRef = [String]()

    override func viewDidLoad() {
        super.viewDidLoad()
        addSlideMenuButton()
        setupTableView()

        ref = Database.database().reference()

        ref.child("posts").observe( .childAdded, with: { snapshot in

            let newPost = snapshot.value as? NSDictionary
            let post_title:String = newPost!["post_title"] as? String ?? "error"

            let newPostTime = snapshot.value as? NSDictionary
            let post_time:String = newPostTime!["post_time"] as? String ?? "error collecting timestamp"

            let newPostUser = snapshot.value as? NSDictionary
            let post_user:String = newPostUser!["post_user"] as? String ?? "Team"

            self.posts.insert(post_title, at: 0)
            self.timeRef.insert(post_time, at: 0)
            self.userRef.insert(post_user, at: 0)

            self.newsfeedTableView.reloadData()
        })
    }

    private func setupTableView() {
        if #available(iOS 10.0, *) {
            newsfeedTableView.refreshControl = refreshControl
        } else {
            newsfeedTableView.addSubview(refreshControl)
        }
        refreshControl.addTarget(self, action: #selector(refreshNewsFeedTableView(_:)), for: .valueChanged)
    }

    @objc private func refreshNewsFeedTableView(_ sender: Any) {

        //self.refreshControl.beginRefreshing()
        self.newsfeedTableView.reloadData()
        self.refreshControl.endRefreshing()
        self.activityIndicatorView.stopAnimating()
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return posts.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! NewsfeedCell

        cell.customTextLabel?.text = posts[indexPath.row]
        cell.customTimeLabel?.text = timeRef[indexPath.row]
        cell.customNameLabel?.text = userRef[indexPath.row]

        return cell
    }
    }

    class NewsfeedCell: UITableViewCell {
    @IBOutlet weak var customTextLabel: UILabel!
    @IBOutlet weak var customNameLabel: UILabel!
    @IBOutlet weak var customTimeLabel: UILabel!

    }
这里

您不需要执行任何API请求来获取数据,然后重新加载表并结束刷新,因为您在这里使用了observe

ref.child("posts").observe( .childAdded, with: { snapshot in
然后,您将获得任何新数据,如果需要实现刷新,则将所有数据库代码插入函数中,并将
observeSingleEvent
替换为
observeSingleEvent
,然后从
viewDidLoad
和刷新选择器方法调用它

ref.child("posts").observeSingleEvent( .value, with: { snapshot in
请注意,在建议的方法中,您将一次获得所有的孩子,所以不要忘记清理代码<代码> >观察事件> /代码>中的数组,以避免重复值,也可以考虑在这里制作一个数据源数组而不是3个< /p>
 self.posts.insert(post_title, at: 0)
 self.timeRef.insert(post_time, at: 0)
 self.userRef.insert(post_user, at: 0)
可能需要创建一个模型

struct Item {
  let post:String
  let time:String
  let user:String
}

我在代码中看到的唯一问题是,您正在使用.childAdded来观察来自firebase的事件,但根据firebase文档:

“添加的子项”事件通常在检索子项列表时使用 数据库中的项目。与返回整个 添加的子位置的内容每次触发一次 现有子级,然后每次将新子级添加到 指定的路径。向事件回调传递一个包含 新孩子的数据。出于订购目的,还将传递第二个 包含上一个子项的键的参数

因此,如果要接收任何特定节点的所有数据,需要使用value事件,而不是child\u added,如下所述:

事件用于读取内容的静态快照 在给定的数据库路径上,因为它们在读取时存在 事件它与初始数据一起触发一次,每次触发一次 数据发生了变化。向事件回调传递一个快照,其中包含 该位置的所有数据,包括子数据。在代码示例中 上面,value返回了应用程序中的所有博客帖子。每次 添加新的博客文章后,回调函数将返回所有 职位


在DispatchQueue.main中重新加载UItableView,请尝试以下代码

override func viewDidLoad() {
        super.viewDidLoad()
        addSlideMenuButton()
        setupTableView()

        ref = Database.database().reference()

        ref.child("posts").observe( .childAdded, with: { snapshot in

            let newPost = snapshot.value as? NSDictionary
            let post_title:String = newPost!["post_title"] as? String ?? "error"

            let newPostTime = snapshot.value as? NSDictionary
            let post_time:String = newPostTime!["post_time"] as? String ?? "error collecting timestamp"

            let newPostUser = snapshot.value as? NSDictionary
            let post_user:String = newPostUser!["post_user"] as? String ?? "Team"

            self.posts.insert(post_title, at: 0)
            self.timeRef.insert(post_time, at: 0)


            self.userRef.insert(post_user, at: 0)
            DispatchQueue.main.async() {
                self.newsfeedTableView.reloadData()
            }

        })
    }

数据库操作是异步的吗?重新加载tableview时是否需要使用
dispatchQueue.main.async{}
在正确的线程上执行此操作?@firebase的TommyBs回调默认位于主线程中没有任何更改:(
override func viewDidLoad() {
        super.viewDidLoad()
        addSlideMenuButton()
        setupTableView()

        ref = Database.database().reference()

        ref.child("posts").observe( .childAdded, with: { snapshot in

            let newPost = snapshot.value as? NSDictionary
            let post_title:String = newPost!["post_title"] as? String ?? "error"

            let newPostTime = snapshot.value as? NSDictionary
            let post_time:String = newPostTime!["post_time"] as? String ?? "error collecting timestamp"

            let newPostUser = snapshot.value as? NSDictionary
            let post_user:String = newPostUser!["post_user"] as? String ?? "Team"

            self.posts.insert(post_title, at: 0)
            self.timeRef.insert(post_time, at: 0)


            self.userRef.insert(post_user, at: 0)
            DispatchQueue.main.async() {
                self.newsfeedTableView.reloadData()
            }

        })
    }