0

I have 2 view controllers, A and B. When I click a button, these take me to C - a table view with it's own view controller. C has a list of items where when you click one it takes you back to the previous controller. I am using this code to go back in didSelectRowAtIndexPath:

[self.navigationController popViewControllerAnimated:NO];

My Problem is: How do I send data back programmatically to either A or B once I've popped C?

I've looked around but the function prepareForSegue doesn't get called on a pop - I've used NSLog and nothing is printed when going back.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
SOair
  • 173
  • 1
  • 3
  • 14

2 Answers2

1

you have to create custom delegate

in CViewController.h

@protocol SecondViewControllerDelegate <NSObject>

@required
- (void)dataFromController:(NSString *)data;

@end

@interface CViewController : UIViewController

@property (nonatomic, weak) id<SecondViewControllerDelegate> delegate;

@end

in CViewController.m

- (IBAction)btnBackAction:(id)sender {

    if([_delegate respondsToSelector:@selector(dataFromController:)])
    {
        [_delegate dataFromController:@"Data Received"];
    }

    [self.navigationController popViewControllerAnimated:YES];
}

in A or BViewController (where you want to come back from C)

// not forget to import CViewController.h
@interface A OR BViewController : UIViewController<SecondViewControllerDelegate>

now in A or BViewController.m

// when you go to CViewController from A Oor B then you have to pass delegate like  
CView.delegate = self;

- (void)dataFromController:(NSString *)data
{
    // this method invokes when you come back from CViewController

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(50, 50, 250, 50)];
    label.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth|
    UIViewAutoresizingFlexibleBottomMargin;
    label.textAlignment = NSTextAlignmentCenter;
    label.text = [NSString stringWithFormat:@"Your data: %@", data]; 
    [self.view addSubview:label];    
}  
Ashish Ramani
  • 1,214
  • 1
  • 17
  • 30
  • Thank you, it worked! I'd +1 it but I need 15 reputation >_< Only thing I'd change is putting CViewController as CTableViewController and replacing "CView.delegate = self" with with the method it's in "- (IBAction)selectItem:(id)sender { CTableViewController *nextController = [self.storyboard instantiateViewControllerWithIdentifier:@"cTableViewController"]; nextController.delegate = self; [self.navigationController pushViewController:nextController animated:YES]; }" Note that when assigning a delegate, I'm not the class name itself. – SOair Aug 19 '14 at 06:32
  • Also note that "cTableViewController" is the storyboard id of the CViewController. I set this in the storyboard itself, not in code. – SOair Aug 19 '14 at 06:34
0

One easy way is to store the data in AppDelegate then access it form there, but its no the best way to do it.

Let there is a property of AppDelegate called selectedItem;

@property (strong, nonatomic) NSString *selectedItem;

Form your VC C,

AppDelegate *app = (AppDelegate *) [[UIApplication sharedApplication] delegate];
app.selectedItem = @"Your data here";

From VC A/B, you can access the data by:

AppDelegate *app = (AppDelegate *) [[UIApplication sharedApplication] delegate];
NSLog(@"%@", app.selectedItem);

The best way would be using Delegates, see this answer.

Hope this helps.. :)

Community
  • 1
  • 1
Rashad
  • 11,057
  • 4
  • 45
  • 73