Search code examples
iosuitableviewparse-platformpfquerytableviewcontrolle

ParseUI PFQueryTableViewController in SWIFT


I'm trying to use two PFQueryTableViewControllers in succession, so that the row selected in the first controller generates a second tableview with a detailed query. I assume this is a common thing to do.

The second view controller throws this message:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UITableViewController loadView] loaded the "EQR-J7-VNh-view-gYk-IB-w7b" nib but didn't get a UITableView.'

I've got a "show" segue defined between the cell in the first table and the new view controller, but when it happens the above message appears and the second controller never gets called. If I change the second controller class to a regular UIViewController, everything works fine.

I'm getting the impression that I need to recast PFQueryTableViewController to be a UIViewController in a .nib, but I have no idea how to do that or why Parse defined it as something else. Can anyone enlighten me. I'm coming from a Swift perspective and thought would get away with a storyboard based UI.

Here's the code:

Target (Second) View Controller:

import Parse
import UIKit
import ParseUI


class ClubDetailsViewController: PFQueryTableViewController {

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 = "USACourses"
    self.textKey = "course_name"
    self.pullToRefreshEnabled = true
    self.paginationEnabled = false
    self.objectsPerPage = 10
}



@IBOutlet weak var detailClubName: UILabel!
@IBOutlet weak var detailAddress: UILabel!
@IBOutlet ...

First View Controller:

import UIKit
import Parse
import ParseUI


class ClubTableViewController: PFQueryTableViewController {

    // 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 = "USAClubs"
        self.textKey = "club_name"
        self.pullToRefreshEnabled = true
        self.paginationEnabled = true
        self.objectsPerPage = 20
    }

    override func queryForTable() -> PFQuery {
        var query = PFQuery(className: "USAClubs")
        query.orderByAscending("club_name")
        return query
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell {

        var cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! PFTableViewCell!
        if cell == nil {
            cell = PFTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
        }

        // Extract values from the PFObject to display in the table cell
        if let nameClub = object?["club_name"] as? String {
            cell?.textLabel?.text = nameClub
        }
        if let clubtype = object?["club_membership"] as? String {
            cell?.detailTextLabel?.text = clubtype
        }

        return cell
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        var detailScene = segue.destinationViewController as! ClubDetailsViewController

        // Pass the selected object to the destination view controller.
        if let indexPath = self.tableView.indexPathForSelectedRow() {
            let row = Int(indexPath.row)
            detailScene.currentClubObject = (objects?[row] as! PFObject)
        }
    }

    override func viewDidAppear(animated: Bool) {

        // Refresh the table to ensure any data changes are displayed
        tableView.reloadData()
    } // end view did appear
}

Solution

  • Make sure the ViewController you are setting to ClubDetailsViewController is a UITableViewController and not a UIViewController.

    PFQueryTableViewController is a subclass of UITableViewController that in turn is a subclass of UIViewController. For your ViewController to conform to the UITableViewController it needs to follow certain rules like having a UITableView and not having other subviews. When you drag a UITableViewController onto your storyboard it makes sure it follows the needed rules.