it possible to Pass Data with popViewControllerAnimated?

I came across an interesting problem, i have main ViewController let’s call him MainVC with navigationController and i am doing performSegueWithIdentifier from him to Mine second ViewController let’s call him SecVC. so when i am trying to do the popViewControllerAnimated i want to pass some data from the SecVC to the MainVc.. i know i can do it with appDelegate Param or with singletons class but my question is : can i do it with more Elegant solution? like i use prepareForSegue and use local parmeters..

Thank you…

  • Broadcast data to multiple widgets in Flutter
  • Alamofire custom parameters
  • Unknown type name while known?
  • write into plist file using NSDictionary object
  • UISlider to control AVAudioPlayer
  • How to call iCarte SDK methods for scanning RFID
  • 5 Solutions Collect From Internet About “it possible to Pass Data with popViewControllerAnimated?”

    The best way to do it is by using a delegate.

    //SecVCDelegate.h

    #import <Foundation/Foundation.h>
    
    @protocol SecVSDelegate <NSObject>
    
    @optional
    - (void)secVCDidDismisWithData:(NSObject*)data;
    @end
    

    //SecVC.h

    #import <UIKit/UIKit.h>
    #import "SecVSDelegate.h"
    
    @interface SecVC : UIViewController
    
    /** Returns the delegate */
    @property (nonatomic, assign)   id<SecVSDelegate> delegate;
    
    @end
    

    //SecVC.M

    ...
    
    - (void) dealloc
    {
    ...
    delegate = nil
    ...
    }
    

    When ever you popViewControllerAnimated, right after it (or before it) you do this

    if(_delegate && [_delegate respondsToSelector:@selector(secVCDidDismisWithData:)])
    {
    [_delegate secVCDidDismisWithData:myDataObject];
    }
    

    And in the MainVC you must be certain that you implement the delegate function
    //MainVC.m

    - (void)secVCDidDismisWithData
    {
    //do whatever you want with the data
    }
    

    To avoid any warnings you must tell that the MainVC class implements the delegate like this:

    //MainVC.h

    #import "SecVCDelegate.h"
    ...
    @interface MainVC : UIViewController <SecVCDelegate>
    ...
    secVCInstance.delegate = self;
    [self.navigationController pushViewController:secVCInstance]; 
    ...
    

    While I agree that the best option is to use Delegate,
    but still if any one is looking for something different, he can use NSNotificationCenter as an alternative.

    In viewDidLoad of MainVC:

    - (void)viewDidLoad
    {
    
        [super viewDidLoad];
    
        [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(recvData:)
                                                 name:@"SecVCPopped"
                                               object:nil];
    }
    

    And add method recvData in MainVC.m

    - (void) recvData:(NSNotification *) notification
    {
    
        NSDictionary* userInfo = notification.userInfo;
        int messageTotal = [[userInfo objectForKey:@"total"] intValue];
        NSLog (@"Successfully received data from notification! %i", messageTotal);
    }
    

    Now in SecVC, before popping, add this line

    NSMutableDictionary* userInfo = [NSMutableDictionary dictionary];
    [userInfo setObject:[NSNumber numberWithInt:messageTotal] forKey:@"total"];
    
    NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
    [nc postNotificationName:@"SecVCPopped" object:self userInfo:userInfo];
    

    I would do it in one of the following ways, but I’m not sure if it’s elegant enough…

    1. In SecVC, add an @property MainVC *mainVC; Use [self.mainVC setSomeValue:...]; before calling [self.navigationController popViewControllerAnimated:...];

    2. Use [self.navigationController viewControllers]; to find out the MainVC *mainVC, and call [mainVC setSomeValue:...]; before the line of code that pop the ViewController.

    Is this what you want?

    There is another way to pass data between views including popViewControllerAnimated and it’s with a global var instance, so If you modify that Var in your detail view and after do the popViewControllerAnimated, you can call the new data in the viewWillAppear method.

    The first step is declare the Global var in main.h

    NSMutableArray * layerList;
    

    And now you have to call it in detail view.

    SecondView.m

    extern NSString *layerList;
    

    SecondView.h

    -(void)back{
        layerList = @"Value to send";
        [self.navigationController popViewControllerAnimated:YES];
    }
    

    Now you can use the information in the Master View after detect the pop action.

    FirstView.m

    extern NSString *layerList;
    

    FirstView.h

    -(void)viewWillAppear:(BOOL)animated{
       NSLog(@"This is what I received: %@",layerList);
    }
    

    I simply set up a protocol in the view being dismissed (example in Swift):

     protocol ExampleTableViewControllerDismissDelegate {
        func didDismiss(withData: Any)
    }
    
    var delegate: SearchableTableViewControllerDismissDelegate?
    

    You can then call this when you dismiss/pop your view like this

    self.navigationController?.popViewController(animated: true)
    delegate?.didDismiss(withData: Any)
    

    Then in the view being dismissed to (the parent in the hierarchy), we can conform to the delegate and essentially get a callback with the data after the view has been dismissed.

    //MARK: ExampleTableViewControllerDismissDelegate
    
    func didDismiss(withData: Any) {
        //do some funky stuff
    }
    

    And don’t forget to subscribe to the delegate in the parent view by using

    viewController.delegate = self