在过去的几天中,我一直在尝试为我的应用创建类似Instagram的供稿。更具体地说:每当用户从底部更新Feed时,加载新帖子(5)。
我目前正在使用Firebase来存储和显示我的数据。
到目前为止,我的代码如下所示:
var ref:FIRDatabaseReference! var dict = [String:Any]() var posts = [[String:Any]]() override func viewDidLoad() { super.viewDidLoad() tableView.delegate = self tableView.dataSource = self ref = FIRDatabase.database().reference() // Do any additional setup after loading the view, typically from a nib. } override func viewDidAppear(animated: Bool) { loadValues() } func loadValues() { dict.removeAll() posts.removeAll() ref.child("posts").queryOrderedByChild("timeCreated").queryLimitedToLast(5).observeEventType(.ChildAdded) { (snapshot:FIRDataSnapshot) in if let timeCreated = snapshot.value!["timeCreated"] as? Int { self.dict["timeCreated"] = timeCreated } if let postText = snapshot.value!["postText"] as? String { self.dict["postText"] = postText } self.posts.append(self.dict) self.tableView.reloadData() } } func scrollViewDidScroll(scrollView: UIScrollView) { if (scrollView.contentOffset.y + scrollView.frame.size.height) >= scrollView.contentSize.height { //tableView.tableFooterView!.hidden = true let pagingSpinner = UIActivityIndicatorView(activityIndicatorStyle: .Gray) pagingSpinner.startAnimating() pagingSpinner.hidesWhenStopped = true pagingSpinner.sizeToFit() tableView.tableFooterView = pagingSpinner //loadMore(5) } else { let pagingSpinner = UIActivityIndicatorView(activityIndicatorStyle: .Gray) pagingSpinner.stopAnimating() pagingSpinner.hidesWhenStopped = true pagingSpinner.sizeToFit() pagingSpinner.hidden = true tableView.tableFooterView = pagingSpinner tableView.tableFooterView?.hidden = true } } func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return posts.count } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) if let postText = posts[indexPath.row]["postText"] as? String { cell.textLabel!.text = postText } return cell } func loadMore(increment:Int) { //What should go in here? }
因此,我要在这里进行的操作是- 检测到用户何时滚动到底部(在我的scrollViewDidScroll函数中。然后,我将显示活动指示器,并调用函数loadMore(5),其中5是数量我想显示的新帖子。
所以在这里我有两个问题。timeCreated变量只是一个时间戳,其中有10条记录(1-10,其中10是最新记录,而1是最旧记录)。有了我现在得到的这段代码,tableView会以升序显示数据,从5开始到10结束。
我试图通过简单地做一个.reverse()来反转字典(post)的数组,然后再将字典添加到loadValues函数中。因为我只希望它在顶部显示10,在底部显示5。
我遇到的第二个问题是,我似乎似乎找不到真正有效的方法来更新tableView(添加另外5条记录)。我试图简单地拥有一个默认值为5的全局变量,然后在loadMore上简单地将其加5,然后对dict和post都执行removeAll()-没有运气(tableView滚动到顶部,我不想)。我还尝试同时使用queryLimitedTolast和queryLimitedToFirst,但最终都重复了一些数据。
因此,换句话说,我还需要检查用户实际上是否可以加载5个新的唯一帖子(如果剩下3个唯一的帖子,则可以加载3个)。
有人对我将如何处理这个问题有任何想法吗?
非常感谢您的帮助,因为过去两天来我一直在为此苦苦挣扎。
如果使用的是tableView更新 数据源, 而不是在特定索引处添加行。使用struct是一种常见的方式。
tableView
struct
struct dataS { var postData : String! var index_Initial : Int! init(post : String!, ind : Int!) { self.postData = post self.index_Initial = ind } }
声明一个类型数组 dataSourceS
dataSourceS
var dataFeed= [dataS]()
为了知道您已经检索了多少个帖子,您需要将每个帖子的索引保留在post节点本身中。可以通过计算post节点中子节点的数量并将其增加一个来完成,或者创建一个完整的单独节点的节点
post
noOfPosts: 100, //Lets say there are 100 posts in your DB
Posts : { Post1:{
text : asdasdasd, index : 12 },
Post2:{
text : asdasddasdasd, index : 13 },.....
}
您的最终代码将如下所示:
import UIKit import Firebase class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { var dataFeed = [dataS]() let pagingSpinner = UIActivityIndicatorView(activityIndicatorStyle: .Gray) var totalNoOfPost : Int! @IBOutlet weak var customTableView: UITableView! override func viewDidLoad() { super.viewDidLoad() customTableView.delegate = self customTableView.dataSource = self } override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) FIRDatabase.database().reference().child("Posts").observeSingleEventOfType(.Value, withBlock: {(snap) in if let postDict = snap.value as? [String:AnyObject]{ self.totalNoOfPost = postDict.count self.loadMore() } }) } func numberOfSectionsInTableView(tableView: UITableView) -> Int { return 1 } func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return dataFeed.count } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = customTableView.dequeueReusableCellWithIdentifier("customCell") as! customTableViewCell if dataFeed.count > 0{ cell.poatLabel.text = dataFeed[indexPath.row].postData } return cell } func loadMore(){ let initialFeedCount : Int = dataFeed.count if totalNoOfPost - initialFeedCount - 4 > 0{ FIRDatabase.database().reference().child("Posts").queryOrderedByChild("index").queryStartingAtValue(totalNoOfPost - initialFeedCount - 4).queryEndingAtValue(totalNoOfPost - initialFeedCount).observeEventType(.Value, withBlock: {(recievedSnap) in if recievedSnap.exists(){ for each in recievedSnap.value as! [String:AnyObject]{ let temp = dataS.init(post: each.1["text"] as! String, ind : each.1["index"] as! Int) self.dataFeed.insert(temp, atIndex: 5 * Int(self.dataFeed.count/5)) self.dataFeed.sortInPlace({$0.index_Initial > $1.index_Initial}) if self.dataFeed.count == initialFeedCount+5{ self.dataFeed.sortInPlace({$0.index_Initial > $1.index_Initial}) self.customTableView.reloadData() } } } }, withCancelBlock: {(err) in print(err.localizedDescription) }) }else if totalNoOfPost - initialFeedCount - 4 <= 0{ FIRDatabase.database().reference().child("Posts").queryOrderedByChild("index").queryStartingAtValue(0).queryEndingAtValue(totalNoOfPost - initialFeedCount).observeEventType(.Value, withBlock: {(recievedSnap) in if recievedSnap.exists(){ for each in recievedSnap.value as! [String:AnyObject]{ let temp = dataS.init(post: each.1["text"] as! String, ind : each.1["index"] as! Int) self.dataFeed.insert(temp, atIndex: 5 * Int(self.dataFeed.count/5)) self.dataFeed.sortInPlace({$0.index_Initial > $1.index_Initial}) if self.dataFeed.count == initialFeedCount+4{ self.dataFeed.sortInPlace({$0.index_Initial > $1.index_Initial}) self.customTableView.reloadData() self.pagingSpinner.stopAnimating() } } }else{ self.pagingSpinner.stopAnimating() } }, withCancelBlock: {(err) in print(err.localizedDescription) }) } } func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { if (indexPath.row + 1) == dataFeed.count { print("Displayed the last row!") pagingSpinner.startAnimating() pagingSpinner.hidesWhenStopped = true pagingSpinner.sizeToFit() customTableView.tableFooterView = pagingSpinner loadMore() } } } struct dataS { var postData : String! var index_Initial : Int! init(post : String!, ind : Int!) { self.postData = post self.index_Initial = ind } }