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