I am using parse.com framework with Swift and in PFQueryTableViewController when I set the pagination it won't work. If the DB has less rows than the number set in objectPerPage it works fine, but if there are more rows and when I run the app it keeps showing the loading screen and nothing is downloaded, when I do "swipe as refresh" it crash as Error
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 5 beyond bounds [0 .. 4]
ImagesTableViewController.swift
import UIKit
import Parse
import ParseUI
import Bolts
class ImagesTableViewController: PFQueryTableViewController {
@IBAction func unwindToSegue (segue : UIStoryboardSegue) {}
// Initialise the PFQueryTable tableview
override init(style: UITableViewStyle, className: String!) {
super.init(style: style, className: className)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
// Configure the PFQueryTableView
self.parseClassName = "Image"
self.pullToRefreshEnabled = true
self.paginationEnabled = true
self.objectsPerPage = 5
}
// Define the query that will provide the data for the table view
override func queryForTable() -> PFQuery {
var query = PFQuery(className: "Image")
query.whereKey("deleted", notEqualTo: 1)
query.orderByDescending("createdAt")
return query
}
//override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("ImageCell") as! ImageTVCell!
if cell == nil {
cell = ImageTVCell(style: UITableViewCellStyle.Default, reuseIdentifier: "ImageCell")
}
// Extract values from the PFObject to display in the table cell HEADLINE
if let caption = object?["caption"] as? String {
cell?.headlineLabel?.text = caption
}
// Display image
var initialThumbnail = UIImage(named: "question")
cell.postImageView.image = initialThumbnail
if let thumbnail = object?["image"] as? PFFile {
cell.postImageView.file = thumbnail
cell.postImageView.loadInBackground()
}
return cell
}
// if I remove this code pagination work but the cell height is wrong
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return calculateHeightForRowAtIndexPath(indexPath)
}
func calculateHeightForRowAtIndexPath(indexPath: NSIndexPath) -> CGFloat {
if let ratio = objectAtIndexPath(indexPath)?["aspect"] as? Float {
println("Ratio: \(ratio)")
return tableView.bounds.size.width / CGFloat(ratio)
} else {
return 50.0
}
}
@IBAction func addNewPhotoButton(sender: UIBarButtonItem) {
self.tabBarController?.tabBar.hidden = true
self.performSegueWithIdentifier("showUploadNewImage", sender: self)
}
}
This problem occurs because of
PFQueryTableViewController
's implementation of the methodtableView:numberOfRowsInSection
from theUITableViewDataSource
. I've copy/pasted it from the GitHub repo containingPFQueryTableViewController.m
It simply returns the count of objects to display (which makes sense), but if pagination is enabled, then it requires for an extra cell to be shown. This means you have to manually created another cell with the text "Load more data" or something like that, which would trigger a refresh.
A way to overcome this is simply by overriding
tableView:numberOfRowsInSection
yourself with the following:UPDATE 1
The prebuilt
Parse
pagination button was gone in previous answerUse the following code snippet for calculating the height of the cells to display the prebuilt
Parse
pagination button