Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

overriding loadView in a UITableViewController subclass

I am trying to setup a UITableViewController so that its tableView belongs to my custom subclass. My loadView method currently looks like this:

- (void) loadView {
   MyTableViewSubclass* tv = [[[MyTableViewSubclass alloc]initWithFrame: CGRectZero style: UITableViewStylePlain]autorelease];
   self.view = tv;
   self.tableView = tv;
}

I am getting crashes later on that go away if I comment out the above method. So something is missing. But what?

Apple's documentation says I should not be calling super in loadView. Which makes sense, because I want the view to have my class, not theirs.

Things I've tried that don't help:

  • Rewrite the loadView method so that it is creating a plain UITableView. This tells me that the source of the problem does not lie in the implementation of my subclass.
  • Call [super viewDidLoad] from my loadView method. From Apple's docs, it is unclear to me whether that method is called from loadView or afterwards. In any case, adding it to the end of my loadView method does not help.

One thing I've tried that does fix the problem, but defeats the purpose:

  • Comment out my loadView method.

EDIT: the crash is shown below. It happens after the user does some input. It also happens the same way if I am creating a plain UITableView instead of my subclass. There is a lot going on in the app, and something in my loadView override [or more likely, something missing from my override] is causing the state to be different, which in turn leads to the crash. But I don't see a good way to track what is different.

2011-09-08 12:44:59.591 MyAppName[97649:207] *** Terminating app due to uncaught exception 'NSRangeException', reason: '-[MyTableViewSubclass scrollToRowAtIndexPath:atScrollPosition:animated:]: row (0) beyond bounds (0) for section (0).'
like image 350
William Jockusch Avatar asked Sep 08 '11 16:09

William Jockusch


2 Answers

Turns out I need to set the dataSource and delegate of my tableView as a part of loading. So when I do this, everything works fine:

- (void) loadView {
   MyTableViewSubclass* tv = [[[MyTableViewSubclass alloc]initWithFrame: CGRectZero style: UITableViewStylePlain]autorelease];
   tv.dataSource = self;
   tv.delegate = self;
   self.view = tv;
   self.tableView = tv;
}
like image 148
William Jockusch Avatar answered Nov 15 '22 07:11

William Jockusch


William's answer help me over the last hurdle too.

To add a swift example, the pattern I commonly use is:

class SomeTableViewController: UITableViewController {

    private var childView: SomeTableView! { return tableView as! SomeTableView }

    override func loadView() {
        tableView = SomeTableView(frame: UIScreen.mainScreen().bounds, style: .Plain)
        tableView.delegate = self
        tableView.dataSource = self
        view = tableView
    }

}

You are then free to refer to the customised view as childView in other places in the ViewController.

like image 20
AgentK Avatar answered Nov 15 '22 09:11

AgentK