Mark Amery Mark Amery - 4 months ago 14
iOS Question

Clean way to force view to load subviews early

Recently I wrote some code where I tried to refer to an outlet on a

UIViewController
I'd just instantiated with
[storyboard instantiateViewControllerWithIdentifier]
and modify the subview that the outlet pointed to before presenting the
ViewController
. It didn't work because the
ViewController
's view hadn't loaded its subviews yet, including the one that my outlet referred to, so the property just gave me a null pointer.

After (with some struggle) tracking down the cause of my issue in the debugger, I Googled around and learned, through answers like this one, that I can cause the view to load its subviews without being displayed by calling the
myViewController.view
getter. After that, I can access my outlet without any problems.

It's a clear hack, though, and Xcode - quite rightly - doesn't like it, and angrily protests with this warning:


Property access result unused - getters should not be used for side effects


Is there a non-hacky alternative way to do this that doesn't involved abusing the
.view
getter? Alternatively, are there canonical/idiomatic patterns for this scenario involving something like dynamically adding a handler to be called as soon as the subviews are loaded?

Or is the standard solution just to replace
myViewController.view
with
[myViewController view]
to shut up Xcode's warning, and then live with the hack?

Answer

If I understand you correctly, I think there's another fairly standard solution: move the outlet modification/configuration code into a ViewDidLoad method (of the recently instantiated VC).

The topic is also discussed in this question.

It would require some restructuring, but it might give you a "cleaner" design in terms of MVC if your incoming VC handled its own configuration, and it would avoid the "You should never call this method directly" stricture on loadView.

Good luck.