Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
Mike Zhu
1,840 PointsHow to Pass Values between Multiple View Controllers using Delegate / Protocol
Basically, I am now intend to use delegate to pass values between view controllers.
The flow of the view controllers is A -> B -> C
When the user does some action in the "C" view controller, how to pass the value back to the first view controller, which is "A"?
Below is the code of the First VC and Third VC:
#import "ViewController.h"
#import "ThirdViewController.h"
@interface ViewController ()<PassValueProtocal>
@property (weak, nonatomic) IBOutlet UILabel *myLabel;
@end
@implementation ViewController
{
ThirdViewController *thirdVC;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void) passValueBack:(NSString *)value
{
NSLog(@"HAHAH");
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)segueToSecondVC:(UIButton *)sender
{
thirdVC = [ThirdViewController sharedManager];
thirdVC.delegate = self;
}
@end
#import "ThirdViewController.h"
@interface ThirdViewController ()
@property (weak, nonatomic) IBOutlet UITextField *myTextField;
@end
@implementation ThirdViewController
+ (id) sharedManager
{
NSLog(@"myDelegate sharedManager");
static ThirdViewController *sharedManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ sharedManager = [[self alloc] init]; });
return sharedManager;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)passValueAction:(UIButton *)sender
{
NSLog(@"%@", self.delegate);
if ([self.delegate respondsToSelector:@selector(passValueBack:)])
{
[self.delegate passValueBack:self.myTextField.text];
}
}
2 Answers
Stepan Ulyanin
11,318 PointsHi, you need to create a manual seque in the storyboard and create an instance of your view controller via segue.destinationViewController
#import "FirstViewController.h"
//In the third controller user prepareForSegue:sender: method
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
FirstViewController *firstVC = (FirstViewController *)segue.destinationViewController;
firstVC.propertyName = dataYouWantToPass;
}
David Rynn
10,554 Points(Old question but...) You're using a Singleton and delegation which are two different ways of communicating between VCs (and I stay away from shared instances because they're bad for testing). I think all you need to do is pass the delegate from A, in the prepareForSegue method to B, and then pass it from B to C in B's prepare for segue method. It looks like you're trying to set the third delegate(C) from the first VC(A) by using the shared instance which is wonky. So do this in A and B
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NextViewController *nextVC = (NextViewController *)segue.destinationViewController;
nextVC.delegate = self; // self for First vc, self.delegate for second VC.
}
Keep passing the delegate that way and use the delegation pattern, where NextViewController will be replaced by which ever type is next, i.e., ThirdVC or SecondVC. Keep away from the singleton.
Mike Zhu
1,840 PointsMike Zhu
1,840 PointsThe delegate method is never triggerred and "self.delegate" is always "null". I am not sure why.