UISplitViewController Delegate Help (project sample included)

Discussion in 'iOS Programming' started by Unixed, Mar 10, 2011.

  1. Unixed macrumors newbie

    Joined:
    Mar 10, 2011
    #1
    I uploaded a sample project that clearly shows my dilemma which can be found below.

    I created a Split View-based Application. I then added a second UINavigationController to the DetailViewController inside the MainWindow.xib.

    I then pop a new UIViewController Subclasses when a toolbar item is clicked. I use the following code to conduct the pop:

    Code:
    DocumentDetailVC *DetailViewController = [[DocumentDetailVC alloc] initWithNibName:@"DocumentDetailVC" bundle:[NSBundle mainBundle]];
        [detailViewController.detailNavController pushViewController:DetailViewController animated:YES];
    
        DocumentsVC *RRequestViewController = [[DocumentsVC alloc] initWithNibName:@"DocumentsVC" bundle:[NSBundle mainBundle]];
        [self.navigationController pushViewController:RRequestViewController animated:YES];
    This works. The issue I am having is how do I pass information or function calls from the Main side of the Split View to the Detail side of the Split view?

    If I present the UIViewController via the following method:

    Code:
    DocumentDetailVC *RRequestViewController = [[DocumentDetailVC alloc] initWithNibName:@"DocumentDetailVC" bundle:[NSBundle mainBundle]];
        RRequestViewController.delegate=self;
        RRequestViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
        [RRequestViewController setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
        [self presentModalViewController:RRequestViewController animated:YES];
        [RRequestViewController release];
        RRequestViewController = nil;
    I am able to complete a reach back through a protocol as intended.

    DocumentDetailVC, when loaded via the pushViewController, the hierarchy is as follows:

    Code:
    NSLog([NSString stringWithFormat:@"%@",self]); 
        //self = <DocumentDetailVC: 0x4e0d960>
        NSLog([NSString stringWithFormat:@"%@",self.parentViewController]);
        //self.parentViewController = <UINavigationController: 0x4e0ce30>
        NSLog([NSString stringWithFormat:@"%@",self.parentViewController.parentViewController]);
        //self.parentViewController.parentViewController = <UISplitViewController: 0x4e0d0f0>
    Thank you for your assistance. This problem is consuming my life!
     

    Attached Files:

  2. RonC macrumors regular

    Joined:
    Oct 18, 2007
    Location:
    Chicago-area
    #2
    I'm having related design issues, so maybe we can work this out together. Here's what I got when I ran the code you posted:

    There are 2 sub-views, left and right. When you present the left view as a modal view, the information entered into the corresponding field of the right view gets populated. The problem is it doesn't get populated in the left view that's presented on the left-side of the split-view.

    Similarly, when information is entered into the left view, it doesn't find it's way into the right view.​

    The issue that jumps out to me immediately is there's nothing in the right hand view that reacts to events in the left hand view; similarly, there's nothing in the left hand view that reacts to events in the right hand view. It works when the left hand view is presented as a modal view because they're really under the same view controller.

    Perhaps using a protocol for interaction BETWEEN the left and right view controllers for the purpose of telling the other one that something changed here. A shared model can be used to hold the data that is being presented, and the various view controllers can pull that data out as appropriate from that model. I don't know where this goes and how it would actually work, but I'm otherwise stumped.

    Now that I'm intrigued, I'll tinker with this example a little and see what that looks like. My immediate reaction is that while it will work for this example, I don't know if it will work in general (or it's already hiding somewhere in the sea of APIs in iOS and I just don't know what it is).
     
  3. Unixed thread starter macrumors newbie

    Joined:
    Mar 10, 2011
    #3
    First I want to say, thank you for taking interest in this.

    Second, for simplicity sake, I only linked up one protocol for the subview left to populate the right subview's UITextField. I thought about setting one up in reverse, but decided it would be easier to present it with less versus more.

    In a nutshell, calling a function within any subview on demand is what the ultimate goal will be.

    I submitted a TSI through the developer program and am still waiting for a response.

    I will keep you updated on any and all findings that I may come across. My head hurts at this moment trying everything that I can possibly think of to make what seems to be simple problem get resolved.

    Thank you again!
     
  4. RonC macrumors regular

    Joined:
    Oct 18, 2007
    Location:
    Chicago-area
    #4
    Ok, I got this going a little bit

    So I did what I said I would - I created a handful of protocols and a data model object. Here's what I added:
    • Class "TwoUIViewDataModel" - holds the data model (in this case, just the two strings.
    • Protocol "TwoUIViewDataModelProtocol" to access and update the data model. It has simple get/set style methods.
    • Protocol "TwoUIViewControllerDelegate" for the interaction among the View Controllers. It still has a stink to me, but... Oh, Left and Right implement this protocol.
    • Protocol "LeftModalViewControllerDelegate" (in Left.h) - this is implemented by Right to get notified when the modal version of Left closes. The implemention in Right notifies both Left and Right via the TwoUIViewControllerDelegate "somethingHappened" member that, well, something happened.
    I then updated the code to use the delegate methods and the data model to shlep data around, etc.

    Here's that code, and when the iPad simulator is turned landscape you can see it in action (press MyBtn and have at it) - both views get updated as changes occur in each via the button presses. Text updates via keyboard aren't processed - that requires handling events from the UITextField objects, and that code doesn't appear to be there.
     

    Attached Files:

  5. Unixed thread starter macrumors newbie

    Joined:
    Mar 10, 2011
    #5
    Perfect! Thank you!

    I am now dissecting the concepts added to this project. Then I will read up on the subject.

    I think what you just demonstrated will be a critical part of any blooming dev.

    Thank you once again! :D
     
  6. Unixed thread starter macrumors newbie

    Joined:
    Mar 10, 2011
    #6
    I just want to thank you one more time.

    I also would like to share what I gleaned from your magnificent example.

    Inside the RootViewController, all I had to do is change the following code:
    Code:
    - (IBAction)myBtnPushed{
    
        NSLog(@"myBtnPushed");
    
        Right *DetailViewController = [[Right alloc] initWithNibName:@"Right" bundle:[NSBundle mainBundle]];
    
        [detailViewController.navigationController pushViewController:DetailViewController animated:YES];
    
        Left *RootViewController = [[Left alloc] initWithNibName:@"Left" bundle:[NSBundle mainBundle]];
    
        [self.navigationController pushViewController:RootViewController animated:YES];
    
    }
    To this following code:

    Code:
    - (IBAction)myBtnPushed{
    
        NSLog(@"myBtnPushed");
    
        Right *rightVC = [[Right alloc] initWithNibName:@"Right" bundle:[NSBundle mainBundle]];
    
        [detailViewController.navigationController pushViewController:rightVC animated:YES];
    
        Left *leftVC = [[Left alloc] initWithNibName:@"Left" bundle:[NSBundle mainBundle]];
        [self.navigationController pushViewController:leftVC animated:YES];
    
        leftVC.delegate = rightVC;
    
        [rightVC release];
        [leftVC release];
    }
    And now within my leftVC I can call any function within my rightVC by calling the function through the delegate. In the following code I am calling the function "reachingBack":

    Code:
    [self.delegate reachingBack:self];
    Thank you again, I would have never figure that out without your help!

    I still have a lot to learn. . .
     
  7. Unixed thread starter macrumors newbie

    Joined:
    Mar 10, 2011
    #7
    I decided to add a working example of a UISplitController with two UINavigationControllers being able to reference from pushed Master VC to a pushed Detail VC.

    I am sure others can benifit from my heartache, ;)
     

    Attached Files:

  8. PhoneyDeveloper macrumors 68040

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #8
    You might prefer to use NSNotifications to communicate between objects that don't naturally have a close connection.
     
  9. farshadtx macrumors newbie

    Joined:
    Jul 26, 2011
    #9
    problem

    first ty for your good and helpful topic ;)
    i have a problem with change views in detailviewcontroller
    it's my sample project ,can you help me :-s

    http://hotfile.com/dl/125040634/63b31a4/wow.zip.html

    i just need to change the detail view with an action like click on a button :( but i cant!
    i use a sqlite-tree database and i drilldown completely correct in navigation pane (left side view) ,at the final row of tree when i need to show information about child in the right side view ,a cant change the view or show a new view
    plz help me with an sample project ;)

    sry for my bad english ;)
     

Share This Page