-2

I've been at this for almost two days. I cannot get it to display anything. I am going to go step by step because I have no idea what the problem is.

I start with an empty Main.storyboard.

I drag a Table View Controller to the Main.storyboard.

I embed the Table View Controller in a Navigation Controller.

I create a Cocoa Touch Class UITableViewController file. I name it TableViewController.

I type TableViewController in the Class text field under Custom Class in the identity inspector pane of the dragged Table View Controller.

I create a Cocoa Touch Class UITableViewCell file. I name it TableViewCell.

class TableViewController: UITableViewController {

    let users = NSMutableArray()

    override func viewDidLoad() {

        // Register class
        self.tableView.registerClass(TableViewCell.self, forCellReuseIdnetifier: "TVC")

        // Since the Table View Controller I dragged onto Main.storyboard has outlets `dataSource` and `delegate` set to TableViewController, I do not need to set dataSource and delegate in code, correct? Either way, I've tried both ways.

        // Load data
        self.loadData()
    }

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return users.count
    }

    // Load data
    func loadData() {
        self.users.removeAllObjects()
        let query = PFQuery(className: "User")
        query.findObjectsInBackgroundWithBlock {(objects: [PFObject]?, error: NSError?) -> Void in
            if error == nil {
                for person in objects! {
                    self.users.addObject(person)
                    // The print statement here is printing
                }
                self.tableView.reloadData()
            }
        }
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let personCell = tableView.dequeueReusableCellWithIdentifier("TVC", forIndexPath: indexPath) as! EventTableViewCell
        let person = self.users.objectAtIndex(indexPath.row)
        personCell.userName.text = (event.objectForKey("email") as! String)
        return personCell
    }

.

class TableViewCell: UITableViewCell {

    let userName = UILabel()

    // I'm assuming the reuseIdentifier below should be the same as the one in TableViewController
    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: "TVC")

        userName.text = PFUser.currentUser()!.email
        userName.translatesAutoresizingMaskIntoConstraints = false
        self.contentView.addSubview(userName)
        self.contentView.addConstraint(NSLayoutConstraint(item: UserName,
            attribute: .CenterX,
            relatedBy: .Equal,
            toItem: self.contentView,
            attribute: .CenterX,
            multiplier: 1,
            constant: 0))
        self.contentView.addConstraint(NSLayoutConstraint(item: userName,
            attribute: .CenterY,
            relatedBy: .Equal,
            toItem: self.contentView,
            attribute: .CenterY,
            multiplier: 1,
            constant: 0))
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
    }

So I expect to see a number of cells with one label in each cell. And each label being centred on both X and Y based on each cell.

Sorry for the wall of code, but I am really stumped.

fossdeep
  • 113
  • 1
  • 11

2 Answers2

1

Is the loadData function getting called from somewhere that isn't in your sample? If not, I'd assume you want to do something like this:

override func viewDidLoad() {
    super.viewDidLoad() // <-- don't forget this part

    self.tableView.registerClass(TableViewCell.self, forCellReuseIdnetifier: "TVC")

    // Yup, your `dataSource` and `delegate` outlets are correct
    // Now load up the data
    loadData()
}

If that works for you, then I'd remove this from the loadData function

self.tableView.reloadData()
Daniel
  • 624
  • 7
  • 6
  • Sorry I forgot to add it in the example. I actually had it above `self.tableView.registerClass()`, and I was hoping that was the reason. But it still doesn't work after moving it below. I just realized I have a print statement in the for loop of `loadData()`, and I'm not sure when it stopped printing to console. But it stopped. I hope you know your Parse, and can tell me why there is no `person` object in my array of `objects`. I have two user rows in the default `User` Parse class. – fossdeep Jan 09 '16 at 18:38
  • All right, I edited the question, and I added a comment into the for loop, so it is now printing. So now I know there is an object in users. So I think the problem is in `override func tableView()`. – fossdeep Jan 09 '16 at 18:50
  • 1
    Oh! I see another thing. In your UITableViewCell, in the initializer, before setting up the AutoLayout constraints, did you add the label to the view hierarchy? Something like this: `self.contentView.addSubview(userName)` – Daniel Jan 09 '16 at 21:22
  • You're right I forgot to add that in my actual code. However, it doesn't solve the problem. I might just end up doing this non-programmatically if no one else sees anything. At least I have a general understanding of how this class works now. – fossdeep Jan 11 '16 at 17:58
1

I figured it out. The constraints were not actually being executed. I made the mistake of thinking the override init() in TableViewCell acted like a viewDidLoad(). All that code should actually be moved to a new override function.

override func layoutSubviews() { // Set attributes, add to contentView, set constraints, etc. }

fossdeep
  • 113
  • 1
  • 11