Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

get sender of segue in destination view controller

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];
like image 444
Thomas Leduc Avatar asked Feb 19 '13 18:02

Thomas Leduc


People also ask

What is Sender in Perform segue?

The string that identifies the triggered segue. In Interface Builder, you specify the segue's identifier string in the attributes inspector. This method throws an Exception handling if there is no segue with the specified identifier. sender. The object that you want to use to initiate the segue.

How do I create a segue between view controllers?

To create a segue between view controllers in the same storyboard file, Control-click an appropriate element in the first view controller and drag to the target view controller. The starting point of a segue must be a view or object with a defined action, such as a control, bar button item, or gesture recognizer.

What is the significance of the method prepare for sender:)?

prepare(for:sender:) Notifies the view controller that a segue is about to be performed.


2 Answers

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:

like image 191
Taum Avatar answered Oct 20 '22 01:10

Taum


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.

like image 29
johnrechd Avatar answered Oct 19 '22 23:10

johnrechd