3

Here is my problem:

I have a basic application with a UIViewController embedded in a NavigationController. It is also the RootViewController of the application. From there I have a push segue to a normal UIViewControllerand a second push segue to a UITableViewController with its own UIViewController for the detailed view.

In the root view there is an instance of the class whose purpose is to send message with a define protocol. In the table view the user will select the type of message he wants to send and in the detail view the content of that particular type of message.

Now the user has specified everything and I want him to push a "send" button. That button must do two things: pop back to the root view and send the user defined message by the protocol class instance. I can do the pop back just fine with:

[self.navigationController popToRootViewControllerAnimated:true];

but I have no idea how to send the message (a class instance) back to the root view. The application is still fresh so I can completely change the structure if this one is not correct.

The best for me would be to access the protocol class instance from everywhere (I will need it in the other UIViewController) but I am not sure how to do that so that's why I thought of sending the message back to the root view.

If you know how to do one of the two above please give me a hand!

Cheers.

EDIT: Technically the NavigationController is the initial ViewController so I am not really sure who is the RootViewController anymore.

5 Answers5

4

First: You could do: (only works when your view has been added to a the window)

[self.view.window.rootviewcontroller doSomething];

Second option is to define a property on your appDelegate:

@property (nonatomic, strong) UIViewController *root;

And call it through:

AppDelegate *appDelegate= (YourAppDelegateClass *) [[UIApplication sharedApplication] delegate];

[appDelegate.root doSomething];
Thomas Keuleers
  • 6,075
  • 2
  • 32
  • 35
  • I agree, with a little twist… I keep my app delegate class clean and focused on its `UIApplicationDelegate` duties. So instead of adding that "root" property there, I create a singleton `XXNavigator` object (subclass of NSObject) for such nav-related info. This object is where I do stuff such as keep track of a user's usage history (akin to a web browser History), and respond to target-actions from nav controller's optional tool bar buttons. You could subclass UINavigationController for such a property but Apple recommends against that before iOS 6 -- and doing so just muddies the waters. – Basil Bourque Sep 10 '13 at 07:48
1

you can Create an application object and assign the message to it. and use it on your root view controller. if i understood your question correctly this might help.

wasim
  • 698
  • 8
  • 20
1

You could try:

UIApplication *myApp = [UIApplication sharedApplication];
UIWindow *frontWindow = [myApp.windows lastObject];
UIViewController *myRootViewController = frontWindow.rootViewController;
Reinhard Männer
  • 14,022
  • 5
  • 54
  • 116
1

You Can also send Notification whenever you move to root view controller

by adding observer to it.

Pankaj Wadhwa
  • 3,073
  • 3
  • 28
  • 37
1

one way is to use protocol and other way is to pass your root view controller instance to your tableviewcontroller(via view controller) using your custom init method like:

UIViewController.m

- (id)initWithRoot:(id)rootInstance
      withNibNameOrNil:(NSString *)nibNameOrNil
                bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self)
    {
        self.root = (RootView *)rootInstance;
    }

}

RootViewController.m

viewcontrollerInstance = [[viewcontroller alloc] initWithRoot:self                      withNibNameOrNil:@"viewcontroller"
bundle:[NSBundle mainBundle]];

[self.navigationController pushViewController:viewcontrollerInstance animated:YES];

UITableViewController.m

- (id)initWithRoot:(id)rootInstance
      withNibNameOrNil:(NSString *)nibNameOrNil
                bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self)
    {
        self.root = (RootView *)rootInstance;
    }

}

ViewController.m

tableViewInstance = [[tablecontroller alloc] initWithRoot:self                      withNibNameOrNil:@"tablecontroller"
bundle:[NSBundle mainBundle]];

[self.navigationController pushViewController:tableViewInstance animated:YES];

UITableViewController.m

now on table view controller use your root instance(come from view controller) to call the function of root view controller like:

[self.root displayMessage:message];

sorry for the typo. hope this will help.

KDeogharkar
  • 10,939
  • 7
  • 51
  • 95