6

I have a UITableViewController in my app, which is added to the view hierarchy directly. After the view appears, I want to scroll to a specific cell. My solution would be to call the code for scrolling in -[viewDidAppear].

According to Apple's docs I have to call the method manually:

If the view belonging to a view controller is added to a view hierarchy directly, the view controller will not receive this message. If you insert or add a view to the view hierarchy, and it has a view controller, you should send the associated view controller this message directly.

The question is: When is the right time to call it manually?

Calling it from the parent view controller's -[viewDidAppear] leads to a crash when I try to do the scrolling because apparently, the table view actually didn't yet appear and therefore thinks it has no sections to scroll to.

mrueg
  • 8,065
  • 4
  • 41
  • 66

4 Answers4

17

If you are using view controller containment don't call viewWillAppear: directly. Instead use – beginAppearanceTransition:animated: and – endAppearanceTransition.

If you are implementing a custom container controller, use this method to tell the child that its views are about to appear or disappear. Do not invoke viewWillAppear:, viewWillDisappear:, viewDidAppear:, or viewDidDisappear: directly.

Calling addSubView will automatically trigger viewWillAppear: and viewDidAppear: if the view's viewController is a child view controller, therefore calling viewWillAppear: directly will trigger view will appearance method twice. Using beginAppearanceTransition:animated:and– endAppearanceTransition` will suppress the automatic behaviour so you only get it called once.

Robert
  • 35,442
  • 34
  • 158
  • 205
1

In -[viewDidAppear] on the tableview, called indeed from the parent view controller's -[viewDidAppear], you can call [tableView reloadData], this way you ensure that the tableView is loaded and ready.

luvieere
  • 35,580
  • 18
  • 120
  • 178
0

Calling it from the parent controller's -viewDidAppear is usually your best bet.

If this results in problems if the child view controller isn't fully initialized yet, you may have another problem. Make sure your child view controller is completely "ready for action" after -viewWillAppear is called (which you can also call manually from the parent's -viewWillAppear)

Philippe Leybaert
  • 155,903
  • 29
  • 200
  • 218
  • You should absolutely never call these life cycle events directly – TheCodingArt May 29 '20 at 19:08
  • If your view controller is not in the root view controller heirachy then those life cycle events will never be called, so you absolutely need to call them manually if you want to use them. They're just a function, not the boogy man. – Bergasms Jun 17 '20 at 03:19
0

This is how I manually call viewWillAppear, viewDidAppear, viewWillDisappear, viewDidDisappear: here

and one of the view controllers I load this way, has the following viewWillAppear: (note that this is viewWillAppear since at the point that viewDidAppear is called, your view is viewable by the user)

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [wordListTable reloadData];
    [wordListTable scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionMiddle animated:NO];
}
Community
  • 1
  • 1
mahboudz
  • 38,588
  • 16
  • 95
  • 123