在Swift Firebase中滚动时分页 [英] Pagination while scrolling in Swift Firebase
问题描述
cells
,那么我想加载更多大约5 cells
。我试图做到这一点,但它不工作︰$ b $ pre $ func parseSnusBrands(
let ref = (),{},} {} {} {} {} { (snapshot)in
if snapshot.exists(){
if let all =(snapshot.value?.allKeys)!as?[String] {
self.snusBrandsArray = all
self.snusBrandsTableView.reloadData()
}
}
})
}
并检测有多少个单元格滚动:
override func tableView(tableView :UITableView,willDisplayCell cell:UITableViewCell,forRowAtIndexPath indexPath:NSIndexPath){$ b $ if if indexPath.row == 20 {
let ref = FIRDatabase.database()。reference()。child(Snuses)。孩子(品牌)
如果使用了快照。()。(
,如果let all =(snapshot.value?.allKeys)),则返回false。 !如? [String] {
self.snusBrandsArray = all
self.snusBrandsTableView.reloadData()
$ b}
}
})
}
这是我的 Firebase 结构:
有更好的解决方案还是应该继续这样的尝试?
这里可以看到整个代码。我知道它缺少OO,但我正在学习:)
您可能需要使用 offset
在您的应用中实现分页。
首先,在您的子路径中添加一个顺序
键,可能是当前插入的时间戳,以便您可以订单并在分页中使用它。
例如
品牌:{
catch:{
...
...
pOrder:555
},
etan :{
...
...
pOrder:444
},
general:{
...
...
pOrder:555
}。
.....
}
现在,要实现分页,您会检索21个记录,在这些记录中,前20个将是在表视图中使用的记录,而最后一个记录将是用于检索下一个集合的 offset
创建一个从 firebase
获取数据的函数:
// MARK:正在检索数据:Firebase
/ *
检索当前帖子集,按帖子的更新时间排序
* /
func retrievePost(offset:NSNumber,callFlag:Bool,completion:(result:AnyObject ?, error:NSError?) - >()){
//由于这个方法是从viewDidLoad中调用的,记录。
//稍后当用户向下滚动到底部时,再次调用
let postsRef = ref.child(kDBPostRef)
var startingValue:AnyObject?
//当由于未设置偏移量而从viewDidLoad调用此方法时,起始值将为零
if callFlag {
如果偏移量== 0 {
startingValue = nil
}
else {
startingValue = offset
}
} else {
//从offsetArray获得偏移量
startingValue = self .findOffsetFromArray()
//通过pOrder获取偏移量排序记录+1记录
self.refHandler = postsRef.queryOrderedByChild(pOrder)。queryStartingAtValue(startingValue)。 queryLimitedToFirst(kPostLimit + 1).observeEventType(FIRDataEventType.Value,withBlock:{(snapshot)in
// flag是用于设置最后一条记录/ 21st作为偏移
var flag = 0
let tempPost = NSMutableSet()
//遍历子元素并添加到tempPost
在snapshot.children {
//检查offet,最后一行(第21行)是偏移的;不要在主表列表中添加最后一个元素
flag + = 1
if flag == 21&& callFlag == true {
//这行是偏移
self.kOffset = item.value?[pOrder] as! NSNumber
self.offSetArray?.append(self.kOffset)
continue
}
//创建Post对象
let post = Post(snapshot:item as!FIRDataSnapshot )
//追加到tempPost
tempPost.addObject(后)
}
//返回闭包
完成(result:tempPost,error :nil)
))
}
调用 updateNewRecords
方法从 viewDidLoad
传递 0
来检索前20条记录。
func updateNewRecords(offset:NSNumber,callFlag:Bool){
self.retrievePost(offset,callFlag:callFlag) {(结果,错误) - >无效
//让tempArray = result as! (Post)
let oldSet = Set(self.posts)
var unionSet = oldSet.union(result as!Set< Post>)
unionSet = unionSet.union(unionSet)
self.posts = Array(unionSet)
self.postsCopy = self.posts
// print(self.posts.count)
self.posts.sortInPlace({$ 0.pOrder> $ 1 )
self.reloadTableData()
}
}
你可以维护一个数组 例如假设某些数据在表中的某处被修改,那么 您可以定义一个函数来返回特定更新列的 您也可以修改 I am loading data from Firebase Database. I am trying to load data while user scrolls. For example if he has scrolled about 20 and to detect how many cells are scrolled: This is my Firebase structure: Is there better solution or should I keep trying like this? Here you can see the whole code. I know that it lacks of OO but I am learning :) You may want to use First, add an For eg. Now, to achieve pagination you would retrieve 21 records and in those records, the first 20 will be the records to use in table view, while the last record will be the Create a function that fetches data from And call this Again when the user scrolls to bottom in the You can maintain an array For e.g. suppose some data is modified somewhere in your table, in that case You can define a function that will return the You can also modify 这篇关于在Swift Firebase中滚动时分页的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
<再次当用户滚动到表视图
底部时,调用这个方法,将 updateNewRecords
传递给offset,检索下一组20条记录。
$ b $ pre $ func scrollViewDidEndDragging(scrollView:UIScrollView,willDecelerate decelerate:Bool){
// UITableView只向一个方向移动,y轴
let currentOffset = scrollView.contentOffset.y
let maximumOffset = scrollView.contentSize.height - scrollView.frame.size.height
//改变10.0来调整距底部的距离
如果maximumOffset - currentOffset <= 10.0 {
self.updateNewRecords(self.kOffset,callFlag:true)
}
$ b offsetArray
用于在 firebase
中修改数据时更新表值。
observeEventType
将被调用,并且应该只从 firebase
。您可以使用偏移量
的数组来实现它。所以,当任何记录更新时, retrievePost
将被调用,从 offsetArray中相应的
。在正常情况下(从 offset
viewDidLoad
和 scrollViewDidEndDragging
中检索数据时),偏移量将为 kOffset
,在其他情况下(在监听数据变化时),偏移量将从 offsetArray
。
offset
值:
//找到偏移量offsetDict
func findOffsetFromArray() - > NSNumber {
let idx = self.kClickedRow / 20 // kClickedRow是表视图中已更新的行
return self.offSetArray![idx]
}
retrievePost
方法并传递额外的参数检索一定数量的记录。 cells
then I want to load a little more about 5 cells
. I am trying to achieve it like this but it is not working:func parseSnusBrands(){
let ref = FIRDatabase.database().reference().child("Snuses").child("Brands")
ref.queryOrderedByKey().queryLimitedToLast(20).observeEventType(.Value, withBlock: { (snapshot) in
if snapshot.exists() {
if let all = (snapshot.value?.allKeys)! as? [String]{
self.snusBrandsArray = all
self.snusBrandsTableView.reloadData()
}
}
})
}
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if indexPath.row == 20 {
let ref = FIRDatabase.database().reference().child("Snuses").child("Brands")
ref.queryOrderedByKey().queryLimitedToLast(20).observeEventType(.Value, withBlock: { (snapshot) in
if snapshot.exists() {
if let all = (snapshot.value?.allKeys)! as? [String]{
self.snusBrandsArray = all
self.snusBrandsTableView.reloadData()
}
}
})
}
}
offset
to achieve pagination in your app. order
key in your child path, may be current time stamp of insertion so that you can order it and use it in pagination."brands": {
"catch" : {
...
...
"pOrder" : 555
},
"etan" : {
...
...
"pOrder" : 444
},
"general" : {
...
...
"pOrder" : 555
}.
.....
}
offset
that will be used to retrieve next set of records.firebase
: // MARK: Retrieving Data: Firebase
/*
retrieve current set of posts sorted by updated time of posts
*/
func retrievePost(offset: NSNumber, callFlag: Bool, completion: (result: AnyObject?, error: NSError?)->()){
// As this method is called from viewDidLoad and fetches 20 records at first.
// Later when user scrolls down to bottom, its called again
let postsRef = ref.child(kDBPostRef)
var startingValue:AnyObject?
// starting value will be nil when this method is called from viewDidLoad as the offset is not set
if callFlag{
if offset == 0{
startingValue = nil
}
else{
startingValue = offset
}
} else{
// get offset from the offsetArray
startingValue = self.findOffsetFromArray()
}
// sort records by pOrder fetch offset+1 records
self.refHandler = postsRef.queryOrderedByChild("pOrder").queryStartingAtValue(startingValue).queryLimitedToFirst(kPostLimit + 1).observeEventType(FIRDataEventType.Value, withBlock: { (snapshot) in
// flag is for setting the last record/ 21st as offset
var flag = 0
let tempPost = NSMutableSet()
// iterate over children and add to tempPost
for item in snapshot.children {
// check for offet, the last row(21st) is offset ; Do not add last element in the main table list
flag += 1
if flag == 21 && callFlag == true{
// this row is offset
self.kOffset = item.value?["pOrder"] as! NSNumber
self.offSetArray?.append(self.kOffset)
continue
}
// create Post object
let post = Post(snapshot: item as! FIRDataSnapshot)
// append to tempPost
tempPost.addObject(post)
}
// return to the closure
completion(result:tempPost, error:nil)
})
}
updateNewRecords
method from viewDidLoad
, passing 0
to retrieve first 20 records. func updateNewRecords(offset:NSNumber, callFlag: Bool){
self.retrievePost(offset,callFlag:callFlag) { (result,error) -> Void in
// let tempArray = result as! [Post]
let oldSet = Set(self.posts)
var unionSet = oldSet.union(result as! Set<Post>)
unionSet = unionSet.union(unionSet)
self.posts = Array(unionSet)
self.postsCopy = self.posts
// print(self.posts.count)
self.posts.sortInPlace({ $0.pOrder> $1.pOrder})
self.reloadTableData()
}
}
table view
, call this method, updateNewRecords
passing the offset, to retrieve next set of 20 records.func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
// UITableView only moves in one direction, y axis
let currentOffset = scrollView.contentOffset.y
let maximumOffset = scrollView.contentSize.height - scrollView.frame.size.height
// Change 10.0 to adjust the distance from bottom
if maximumOffset - currentOffset <= 10.0 {
self.updateNewRecords(self.kOffset, callFlag:true)
}
}
offsetArray
for updating table values when your data is modified in firebase
. observeEventType
will be called and you should fetch only those range of records from firebase
. You can achieve it using maintaining an array of offsets
. So when any record is updated, the retrievePost
will be called with the corresponding offset
from offsetArray
. In normal case, ( while retrieving data from viewDidLoad
and scrollViewDidEndDragging
), the offset will be kOffset
and in rest of the cases(while listening to data change), the offset will be from offsetArray
.offset
value for a particular updated column:// find the offset from the offsetDict
func findOffsetFromArray() -> NSNumber{
let idx = self.kClickedRow/20 // kClickedRow is the updated row in the table view
return self.offSetArray![idx]
}
retrievePost
method and pass an extra parameter to retrieve a certain number of records.