In my case, the top most view controller is already a subclass of UITabBarController. And its prefersStatusBarHidden is not called either. Anybody knows a another work-around for this?
EDIT: found the solution. I needed to explicitly implement childViewControllerForStatusBarHidden in the top most view controller as well:
- (UIViewController *) childViewControllerForStatusBarHidden
For anyone who's interested, I filed a bug and heard back from Apple that this is intended behavior on the iPhone X when the navigation controller's navigation bar is not hidden: "If you want to hide the status bar on iPhone X, you should also hide the navigation bar, otherwise you should leave both visible. This is the behavior that UINavigationController implements."