7

I am currently trying to present a view controller using a UIPresentationController. My issue is, when my custom transitioning delegate calls

func presentationControllerForPresentedViewController(presented: UIViewController, presentingViewController presenting: UIViewController!, sourceViewController source: UIViewController) -> UIPresentationController? 

My presenting controller is nil causing it throw an exception. I am presenting it from a view controller that is embedded in a navigation controller which is embedded in a tab bar controller. I have tried presenting it from these controllers as well to the same issue. It also works properly when there is not custom modal presentation but my goal is to customize it. I call it when a button is selected and the code is provided below. mapTransitionDelegate is my custom transitioning delegate that I retain in a class property. Also, EnlargedMapViewController() is initialized to have a custom modal presentation so that my transitioning delegate is called.

var enlargedMapController = EnlargedMapViewController();
enlargedMapController.transitioningDelegate = mapTransitionDelegate;
presentViewController(enlargedMapController, animated: true, completion: nil);

I would love to learn why this issue is occurring for future knowledge. As of now, my subclass UIPresentationController is not even being initialized because of this exception.

  • 1
    is the `EnlargedMapViewController` created in Interface Builder? If yes, it's a common trap. Use an `IBOutlet` rather than create an instance programmatically. – vadian Aug 01 '15 at 19:02
  • EnlargedMapViewController() is created all in code. However, my application relies on storyboards mostly except for this view controller – user2532485 Aug 01 '15 at 19:08

1 Answers1

0

The designated initializer for UIViewController (and, in turn, its subclasses) is init(nibName:bundle:). However, the documentation specifically says:

This is the designated initializer for this class. When using a storyboard to define your view controller and its associated views, you never initialize your view controller class directly. Instead, view controllers are instantiated by the storyboard either automatically when a segue is triggered or programmatically when your app calls the instantiateViewControllerWithIdentifier: method of a storyboard object. When instantiating a view controller from a storyboard, iOS initializes the new view controller by calling its initWithCoder: method instead of this method and sets the nibName property to a nib file stored inside the storyboard.

Calling EnlargedMapViewController() isn't the right way to go because it bypasses all the needed mechanisms for Cocoa to find the pieces. You should instantiate it from a nib using its designated initializer or at least by matching its nib file name to its class name (ie, EnlargedMapViewController.xib) so your call to EnlargedMapViewController(nibName: nil, bundle: nil) (passing nil) will cause Cocoa to hunt for a matching nib by name.

But really, if you're using storyboards everywhere else, why not here too? Just set an identifier for its scene and use instantiateViewControllerWithIdentifier: and enjoy the time and aggravation you've saved yourself.

Joshua Nozzi
  • 60,946
  • 14
  • 140
  • 135