0
votes

I'm having some difficulty managing a segue. My view controller hierarchy is as follows:

  • BHGSplitViewController (subclass of UISplitViewController)
    • UINavigationController
      • MasterViewController (subclass of UITableViewController)
    • UINavigationController
      • DetailViewController (subclass of UIViewController)

These have the following properties:

BHGSplitViewController:

@interface BHGSplitViewController : UISplitViewController

@property (nonatomic, strong) MasterViewController* masterVC;

@end

MasterViewController:

@interface MasterViewController : UITableViewController

@property (strong, nonatomic) MenuDataSource *menuDataSource;
@property (strong, nonatomic) DetailViewController *detailViewController;

@end

DetailViewController:

@interface DetailViewController : UIViewController

@property (strong, nonatomic) NSURL* URL;
@property (strong, nonatomic) IBOutlet UIWebView *webView;

@end

These are related in my main storyboard through relationship segues.

After the initial app launch, I modally display a login view controller. After login, I segue back to my BHGSplitViewController, but I need to set some data. In the loginViewController's prepareForSegue method I attempt the following:

BHGSplitViewController *splitVC = [segue destinationViewController];
splitVC.masterVC.menuDataSource.var = someValue;

But, when debugging, splitVC.masterVC = nil, so obviously attempting to set a value on it is not going to work. How do I set-up and retain those relationships?

I inherited a version of this app that was built with storyboards. I'm guessing that I need to start intializing these properties. What's the best way to do that with storyboards? Do I need to override initWithCoder:? Should I be setting these properties in viewDidLoad?

Edit: Explanation of segue

So, I'm loading up my BHGSplitViewController in my AppDelegate and setting it up to handle collapses, etc. After that, I need to immediately display a modal view for login. I need this to animate in like a push (but Apple won't allow that), so I'm trying to hack my way around that by using a custom segue (which is hacky and I hate it):

Present Segue:

- (void)perform {

    UIViewController *srcViewController = (UIViewController *) self.sourceViewController;
    UIViewController *destViewController = (UIViewController *) self.destinationViewController;

    UIView *prevView = srcViewController.view;
    UIView *destView = destViewController.view;

    UIWindow *window = [[[UIApplication sharedApplication] delegate] window];

    [window insertSubview:destView aboveSubview:prevView];

    [destView enterLeft:0.1 then:^{
        [srcViewController presentViewController:destViewController animated:NO completion:nil];
    }];

}

Dismiss Segue:

- (void)perform {

    UIViewController *srcViewController = (UIViewController *) self.sourceViewController;
    UIViewController *destViewController = self.destinationViewController;

    UIView *prevView = srcViewController.view;

    UIView *destView = destViewController.view;


    UIWindow *window = [[[UIApplication sharedApplication] delegate] window];

    [window insertSubview:destView aboveSubview:prevView];

    [destView enterRight:0.1 then:^{
        [srcViewController presentViewController:destViewController animated:NO completion:nil];
    }];

}
1

1 Answers

0
votes

You can set the properties in viewDidLoad. initWithCoder is definitely too early since the split view controller is instantiated first, and then the other controllers it houses. So, you can do this in viewDidLoad of BHGSplitViewController,

-(void)viewDidLoad {
    [super viewDidLoad];
    UINavigationController *nav = (UINavigationController *)self.viewControllers.firstObject;
    self.masterVC = (MasterViewController *)nav.topViewController;
}