Reputation: 1102
I have a VC named Dashboard (D) which can open a VC named Login (L) and a VC named Register (R). Login can open VC Register too.
I try to use storyboard as often as possible, so I have created with it three Segues, D to L, D to R, L to R
So, in case of D -> L -> R and in case of D -> R, when I close R, I have to close L if it necessary and inform D which he can begin to load the user infos (launch function in nutshell).
So, I would like get the sender of Segue in destination vc, knowing that I put it in sender entrie of performSegueWithIdentifier like that :
[self performSegueWithIdentifier:@"SegueToFbRegister" sender:self];
Upvotes: 12
Views: 25394
Reputation: 3459
You can get it easily by using the type of the parent controller such as
let temp = self.navigationController?.viewControllers
if (temp != nil){
if let _parent = temp![temp!.count-2] as? UIControllerClass {
//do what you want here with the _parent
}
}
You have to subtract 2 because last one is the current view that you want to get its parent.
Upvotes: 0
Reputation: 1341
Another way would be to use an unwind segue.
Place the following code in you Dashboard (D) view controller.
@IBAction func loadUserInfoAfterRegistration(segue: UIStoryboardSegue) {
}
In Interface Builder, do the following steps for the Register (R) view controller:
loadUserInfoAfterRegistrationWithSegue:
from the list displayed.Using this approach, the Register (R) view controller will always navigate to the Dashboard (D) view controller, regardless of what is between them. The view controllers between them will not have to be touched. The loading of the user data in the Dashboard (D) view controller can also be customized in the method declared above.
Upvotes: 0
Reputation: 1811
This sounds like a great place to use Delegates. In your RegisterViewController.h define a protocol like this
@protocol RegisterViewDelegate <NSObject>
- (void)tellRegisterDelegateSomething:(NSObject*)something;
@end
Then on your class keep a pointer to your delegate
@interface RegisterViewController : UIViewController
@property (weak, nonatomic) id <RegisterViewDelegate> delegate;
@end
Now tell the presenting view controllers that they implement the new protocol you just created. This is done in the .h files of the other viewcontrollers that present this view.
In LoginViewController.h
@interface LoginViewController : UIViewController <RegisterViewDelegate>
@end
In DashboardViewController.h
@interface DashboardViewController : UIViewController <RegisterViewDelegate>
@end
In the .m files of the above classes, implement the protocol's method
- (void)tellRegisterDelegateSomething:(NSObject*)something
{
}
Now you need to assign the delegate when you perform your segue from either presenting view controller like this.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"SegueToFbRegister"])
{
RegisterViewController* destination = [segue destinationViewController];
destination.delegate = self;
}
}
Now you can call the presenting view controller (delegate) and have it do something with any information you need to send back like this (this would be called in your RegisterViewController.m).
if ([self.delegate respondsToSelector:@selector(tellRegisterDelegateSomething:)])
{
// Tell the delegate something.
[self.delegate tellRegisterDelegateSomething:something];
}
The instance where you need to pass back through two controller you follow the same basic pattern.
@protocol LoginViewDelegate <NSObject>
- (void)tellLoginDelegateSomething:(NSObject*)something;
@end
Then on your class keep a pointer to your delegate
@interface LoginViewController : UIViewController
@property (weak, nonatomic) id <LoginViewDelegate> delegate;
@end
Now tell the Dashboard view controller that it implements the protocol. This is done in the .h files of the Dashboard viewcontrollers that present this view.
In DashboardViewController.h
@interface DashboardViewController : UIViewController <RegisterViewDelegate, LoginViewDelegate>
@end
In the .m files of the DashboardViewController implement the protocol's method
Follow the above pattern of setting the delegate on the viewcontroller when you perform the segue. Now when the delegate method is called in the LoginViewController, you call the delegate in the DashboardViewController as well.
in LoginViewController.m
- (void)tellRegisterDelegateSomething:(NSObject*)something
{
if ([self.delegate respondsToSelector:@selector(tellLoginDelegateSomething:)])
{
// Tell the delegate something.
[self.delegate tellLoginDelegateSomething:something];
}
}
Now you are all connected so you can pass data back through both controllers (or just one) and do something with it. You will know which scenario you are in because different delegate methods will be called in the DashboardViewController based on which viewcontroller was visible.
Hope this helps.
Upvotes: 7
Reputation: 994
Create a delegate for R and make D and L to implement the delegate methods.Use prepareForSegue:sender
to assign the delegate of R.When you finish task in R use your delegate to perform the rquired action.
Upvotes: 0
Reputation: 2551
I'd do this by having R send a notification when the registration/login is done, and having D listen to it then pop everything and load your data.
If however you insist on getting a reference to the sender, you can add this property on your destination VC and set it in the source VC's prepareForSegue:sender:
Upvotes: 7