我正在尝试构建一个有趣的论坛应用程序,并且希望创建一个所有论坛的表格视图。我想将运行该项目的成本降至最低,那是我偶然发现Infinite滚动/分页数据
(这会降低成本吗?因为我不会同时返回所有数据?)。
此表视图必须能够处理来自Firebase的许多子项,并且使用分页/无限滚动是处理此问题的最佳方法吗?
我已经看过“ Replicode”关于此的教程,我尝试实现它,但是它不起作用,此外,我似乎找不到找到使之起作用的方法。
我现在有两个错误(我认为):
错误1:
在表格视图中,它显示了正确的主题数,但是显示了同一单元格中的重复行。
错误2: :尝试滚动表格视图时发生崩溃,并且在控制台中显示*** Terminating app due to uncaught exception 'InvalidQueryParameter', reason: 'You can only pass nil, NSString or NSNumber to queryEndingAtValue:'
这是此问题的所有相关代码:
var topics = [nameTopics]()
var filteredTopics = [nameTopics]()
//infinite scrolling methods
var fetchingMore = false
var endReached = false
let leadingScreensForBatching:CGFloat = 3.0
override func viewDidLoad() {
super.viewDidLoad()
self.searchController = UISearchController(searchResultsController: nil)
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
tableView.tableHeaderView = searchController.searchBar
self.tableView.delegate = self
self.tableView.dataSource = self
let postCell = UINib(nibName: "TopicsTableViewCell", bundle: nil)
self.tableView.register(postCell, forCellReuseIdentifier:
"topicCell")
beginBatchFetch()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return topics.count
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.performSegue(withIdentifier: "goToTopic", sender: self.topics[indexPath.row])
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "topicCell", for: indexPath) as! TopicsTableViewCell
cell.topicName.text = self.topics[indexPath.row].name
cell.followersLabel.text = String (self.topics[indexPath.row].followersCount)
return cell
/*
let cell = tableView.dequeueReusableCell(withIdentifier: "loadingCell", for: indexPath) as! LoadingCell
cell.spinner.startAnimating()
return cell
*/
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offsetY = scrollView.contentOffset.y
let contentHeight = scrollView.contentSize.height
if offsetY > contentHeight - scrollView.frame.size.height * leadingScreensForBatching {
if !fetchingMore && !endReached {
beginBatchFetch()
}
}
}
/*
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
*/
func fetchTopics(completion:@escaping (_ topics:[nameTopics])->()) {
let postsRef = Database.database().reference().child("topics")
var queryRef:DatabaseQuery
let lastPost = topics.last
if lastPost != nil {
queryRef = postsRef.queryOrdered(byChild: "followersCount").queryEnding(atValue: lastPost).queryLimited(toLast: 20)
} else {
queryRef = postsRef.queryOrdered(byChild: "followersCount").queryLimited(toLast: 20)
}
queryRef.observeSingleEvent(of: .value, with: { snapshot in
//var tempPosts = [Post]()
for child in snapshot.children {
if let childSnapshot = child as? DataSnapshot,
let dict = childSnapshot.value as? [String:Any],
let topicHotness = dict["topicHotness"] as? Int,
//let text = dict["text"] as? String,
let followers = dict["followersCount"] as? Int {
if childSnapshot.key != lastPost?.name {
//let userProfile = UserProfile(uid: uid, username: username, photoURL: url)
let insertMe = nameTopics(name: snapshot.key, score: topicHotness, followersCount: followers)
self.topics.insert(insertMe, at: 0)
}
}
}
return completion(self.topics)
})
}
func beginBatchFetch() {
fetchingMore = true
//self.tableView.reloadSections(IndexSet(integer: 1), with: .fade)
fetchTopics { newPosts in
self.topics.append(contentsOf: newPosts)
self.fetchingMore = false
self.endReached = newPosts.count == 0
UIView.performWithoutAnimation {
self.tableView.reloadData()
}
}
}