I am slightly confused about your question.
Let's assume you have VC1 that opens VC2.
If you want to pass information from root controller(vc1) to new one(vc2)
With segues best you can do is create public property in VC2 and set it before method executes. You can attach just before method executes in prepareForSegue method. So implementation will be something like this:
//
// VC1.m
// StackOverflow
#import "VC1.h"
#import "VC2.h"
@implementation VC1
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if( [segue.identifier isEqualToString:@"yourSegueId"] )
{
if( [segue.destinationViewController isKindOfClass:[VC2 class]] )
{
[(VC2*)segue.destinationViewController setMyPassedString:@"YOUR STRING FROM VC1"];
}
}
}
@end
//
// VC2.h
// StackOverflow
#import <UIKit/UIKit.h>
@interface VC2 : UIViewController
@property(nonatomic, strong) NSString* myPassedString;
@end
I personally don't like this approach as you are creating public properties on VC2, which may not be needed at all. However this is a limitation on how storyboard works, and only way to avoid this is to use good old fashioned xib's and designated initializers where you can put your params.
If you want to pass information from new controller(vc2) back to root(vc1)
Here you could basically use two approaches: by passing weak reference to vc2, store it, and then use it when needed to update something on vc1. This is called delegate pattern, however it could be used in much much more powerful and encapsulated way called BLOCKS.
Here is simple implementation with blocks:
//
// VC2.h
// StackOverflow
#import <UIKit/UIKit.h>
@interface VC2 : UIViewController
@property(nonatomic, copy) void(^vc1UpdateBlock)(NSString* string);
@end
//
// VC2.m
// StackOverflow
#import "VC2.h"
@implementation VC2
-(void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
_vc1UpdateBlock(@"PUT YOUR PASSED STRING HERE");
}
@end
//
// VC1.m
// StackOverflow
#import "VC1.h"
#import "VC2.h"
@implementation VC1
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if( [segue.identifier isEqualToString:@"yourSegueId"] )
{
if( [segue.destinationViewController isKindOfClass:[VC2 class]] )
{
[(VC2*)segue.destinationViewController setVc1UpdateBlock:^(NSString * stringFromVC2) {
NSLog(@"I'm printing in VC1 string %@, passed from VC2", stringFromVC2);
}];
}
}
}
@end
Again if you use xib files directly you can use designated initializers and hide block property, however with storyboards you must create your block publicly available.