Search code examples
iosuinavigationcontrolleruisplitviewcontrolleripad

Using Split View Controller and Navigation Controller As Window Root View Controller Alternately


i have a navigation controller which is my application's root view controller. it is my main screen. I have a split view controller whose master view lists location and detail view shows the location on the map. I wanted to push the split view controller to the navigation controller, but it throw a error saying split view controller cant be pushed to navigation controller and it must be application's root view controller. So i tried a hard way.

MyAppDelegate *myappdelegate= [[UIApplication sharedApplication] delegate];
UISplitViewController * vc= [[UISplitViewController alloc] init];
vs.viewControllers = [NSArray arraywithObjects......
....
myappdelegate.window.rootViewController= vc;

This works. It shows split view controllers without animation as expected. And i do the same steps when i was closing split view controller. i am creating a navigation controller with main screen nib and setting this my app delegate's window.rootviewController again. And it succesfully loads main screen again.

But i suspect that this is the proper way of achieving this. Is there more eligible way of doing this?

And i couldnt release split view controller's child controllers. i made a breakpoint on my release method of child controllers. it wasnt be catched. I assumed that when i set my app's root view controller as navigation controller, the old root view controller (split view controller) must be released along with its childs. Then i tried below code when closing split view controller.

UISplitViewController *oldviewcontroller= (UISplitViewController*) myappdelegate.window.rootViewController;
for (UIViewController *child in oldviewcontroller.viewControllers)
{
     [child release];
}

//Setting the navigation controller as window.rootviewController again in here.

This code throw an error saying "[UIImageView __viewDidDisappear:]: unrecognized selector sent to instance 0x7d...."

i think because of releasing the view already, there is no imageview on viewdidDisappear event.

In brief, my question is that am i using right method to achieve this? If so, how can i successfully release all child view controllers?


Solution

  • I finally found a way. I probably found the error. What i have done is cutting the branch on which i am sitting. I was releasing the view controller which i am currently in:) When viewdidDisappear called, there is no such view controller. Because i throw away it to space already.Below is my working steps. I hope it will be useful to someone. But i cant stand thinking of apple may reject my app. I wish finding a suitable way.

    This is my working ultimate way of using split view controller and navigation controller as window root view controller alternately.

    Firstly i defined NavigationController and SplitViewController property in AppDelegate interface.

    AppDelegate.h
    @property (assign,nonatomic) UINavigationController * NC;
    @property (assign,nonatomic) UISplitViewController *SVC;
    

    Secondly i assign newly created NC on AppDelegate didFinishLaunch event.

    AppDelegate.m
    //Creating my main screen controller
    //Creating my navigation controller with my view controller instance. Then
    self.NC= my_navigation_controller;
    self.window.rootViewController= self.NC;
    

    Thirdly creating a splitview controller and setting as app's root view controller

     MyMainScreen.m
     -(void) OpenSplit()
     {
          //Creating my master view controller of SVC
          //Creating my detail view controller of SVC
          //Creating my SVC;
          AppDelegate * app_delegate= [[UIApplication sharedApplication] delegate];
          app_delegate.SVC= newly created my SVC;
          app_delegate.window.rootViewController= app_delegate.SVC;          
     }
    

    Fourthly releasing unused NC in viewDidLoad event of detail view of SVC.

    MyDetailView.m
    - (void) viewDidLoad()
    {
        ...
        AppDelegate * app_delegate= [[UIApplication sharedApplication] delegate];
        app_delegate.NC= nil;  //i dont need it now. i am releasing. Releasing Navigation Controller release as well child controllers. I learned with testing.
    }   
    

    Fifthly managing close split view function.I used UIBarButton on NavigationBar in DetailView.

    MyDetailView.m
    -(void) closeSplitView
    {
         //Creating navigation controller with my main screen view controller
         AppDelegate * app_delegate= [[UIApplication sharedApplication] delegate];
         app_delegate.NC= newly_created_NC;
         app_delegate.window.rootViewController= appdelegate.NC;
    } 
    

    Sixthly handling unused split view controller in Main Screen viewDidLoad event.

     MyMainScreen.m
     -(void) viewDidLoad
     {
        AppDelegate * app_delegate= [[UIApplication sharedApplication] delegate];
        app_delegate.SVC= nil; //I am releasing it because i am working with NC now.
     }