Search code examples
iosobjective-cuipopovercontroller

What if you cant invoke [super init] first


I'm trying to subclass UIPopoverController and give IT the proper responsibility of determining what kind of UIViewController (contentViewController) to create and present rather than horribly cluttering the popover's calling code with that responsibility. But I'm running into several issues.

According to Apple documentation, there is never a valid reason to do anything before first calling.

if (self = [super init])

So I tried that, thinking I could then simply set the contentViewController property later in the method when my code examined the data I pass in and makes the decision about which UIViewController to create and prsent, but calling [super init] blows up with an error telling me I have to call the other initializer.

[super initWithContentViewController:...]

So my problem is illustrated below. I can't use the first lines of my custom initializer to make the decision and THEN call super when the call to super is supposed to be the very first call and according to apple, there's never a good reason to not have it be the first call.

initWithData:(MyDataObject*)data
   // examine data object and determine what kind
   // of UIViewController to create and present
   //
   // [super initWithContentViewController:myDecidedContentViewController

What to do? Thanks.


Solution

  • From Apple documentation on UIPopoverController:

    When initializing an instance of this class, you must specify the view controller that provides the content for the popover.

    UIPopoverController doesn't have any content of it's own, it needs another UIViewController that renders the stuff you actually want to present. Any subclass of UIViewController would suffice, as long as it doesn't conflict with the popover controller.

    For example you can use a custom designed controller from a Storyboard or a XIB, or a programatically instantiated UIViewController. You're not limited to these two, though. Subclassing UIPopoverController won't help, as the subclass still needs a content controller.

    Now, subclassing UIPopoverController and implementing the logic for creating the content controller within that class, is a violation of the Single Responsibility Principle as you'll mix the responsibilities for the popover class. Currently the UIPopoverController has one and good responsibility - to display view controllers in a popover, you're only burdening it if you also make it responsible of creating content controllers.

    My recommendation would be to create a MyPopoverFactory class that have methods that will create both the popover and its content controller. For example:

    - (UIPopoverController*)popoverForSomething