tableView not refreshing



我是编程新手,目前正在构建一个从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!
}

此处为

@objc private func refreshNewsFeedTableView(_ sender: Any)

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

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

然后你会得到任何新的数据,如果你需要实现刷新,那么在一个函数中插入所有数据库代码,用observeSingleEvent替换observe,并从viewDidLoad和刷新选择器方法调用它

ref.child("posts").observeSingleEvent( .value, with: { snapshot in

注意,使用建议的方法,您将一次获得所有子级,因此不要忘记清理observeSingleEvent回调中的数组以避免重复值,还可以考虑制作一个dataSource数组,而不是此处的3个

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
}

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

child_added事件通常用于检索项。不同于返回整个位置的内容,child_added每个都触发一次现有子项,然后每次将新子项添加到指定的路径。事件回调传递了一个快照,该快照包含新孩子的数据。出于订购目的,它也会传递一秒钟包含上一个子项的键的参数。

因此,如果您想接收任何特定节点的所有数据,您需要使用事件,而不是child_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()
}
})
}

最新更新