By jini


2011-05-29 16:33:20 8 Comments

I have two UITableViewControllers and need to pass the value from the child view controller to the parent using a delegate. I know what delegates are and just wanted to see a simple to follow example.

Thank You

4 comments

@iOS Team 2018-02-12 13:27:03

Following solution is very basic and simple approach to send data from VC2 to VC1 using delegate .

PS: This solution is made in Xcode 9.X and Swift 4

Declared a protocol and created a delegate var into ViewControllerB

    import UIKit

    //Declare the Protocol into your SecondVC
    protocol DataDelegate {
        func sendData(data : String)
    }

    class ViewControllerB : UIViewController {

    //Declare the delegate property in your SecondVC
        var delegate : DataDelegate?
        var data : String = "Send data to ViewControllerA."
        override func viewDidLoad() {
            super.viewDidLoad()
        }

        @IBAction func btnSendDataPushed(_ sender: UIButton) {
                // Call the delegate method from SecondVC
                self.delegate?.sendData(data:self.data)
                dismiss(animated: true, completion: nil)
            }
        }

ViewControllerA confirms the protocol and expected to receive data via delegate method sendData

    import UIKit
        // Conform the  DataDelegate protocol in ViewControllerA
        class ViewControllerA : UIViewController , DataDelegate {
        @IBOutlet weak var dataLabel: UILabel!

        override func viewDidLoad() {
            super.viewDidLoad()
        }

        @IBAction func presentToChild(_ sender: UIButton) {
            let childVC =  UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier:"ViewControllerB") as! ViewControllerB
            //Registered delegate
            childVC.delegate = self
            self.present(childVC, animated: true, completion: nil)
        }

        // Implement the delegate method in ViewControllerA
        func sendData(data : String) {
            if data != "" {
                self.dataLabel.text = data
            }
        }
    }

@BDGapps 2011-05-29 16:40:48

You need to use delegates and protocols. Here is a site with an example http://iosdevelopertips.com/objective-c/the-basics-of-protocols-and-delegates.html

@Jhaliya 2011-05-29 17:07:54

This below code just show the very basic use of delegate concept .. you name the variable and class as per your requirement.

First you need to declare a protocol:

Let's call it MyFirstControllerDelegate.h

@protocol MyFirstControllerDelegate
- (void) FunctionOne: (MyDataOne*) dataOne;
- (void) FunctionTwo: (MyDatatwo*) dataTwo;
@end

Import MyFirstControllerDelegate.h file and confirm your FirstController with protocol MyFirstControllerDelegate

#import "MyFirstControllerDelegate.h"

@interface FirstController : UIViewController<MyFirstControllerDelegate>
{

}

@end

In the implementation file, you need to implement both functions of protocol:

@implementation FirstController 


    - (void) FunctionOne: (MyDataOne*) dataOne
      {
          //Put your finction code here
      }
    - (void) FunctionTwo: (MyDatatwo*) dataTwo
      {
          //Put your finction code here
      }

     //Call below function from your code
    -(void) CreateSecondController
     {
             SecondController *mySecondController = [SecondController alloc] initWithSomeData:.];
           //..... push second controller into navigation stack 
            mySecondController.delegate = self ;
            [mySecondController release];
     }

@end

in your SecondController:

@interface SecondController:<UIViewController>
{
   id <MyFirstControllerDelegate> delegate;
}

@property (nonatomic,assign)  id <MyFirstControllerDelegate> delegate;

@end

In the implementation file of SecondController.

@implementation SecondController

@synthesize delegate;
//Call below two function on self.
-(void) SendOneDataToFirstController
{
   [delegate FunctionOne:myDataOne];
}
-(void) SendSecondDataToFirstController
{
   [delegate FunctionTwo:myDataSecond];
}

@end

Here is the wiki article on delegate.

@CW0007007 2014-06-19 07:02:31

While this covers how to setup a working Delegate protocol. I think it's ommiting a few key points. Firstly, when calling the methods on the delegate you should first be checking that the delegate responds to that selector. If it doesnt your app will crash. Secondly you need to set the "@protocol MyFirstControllerDelegate" to @protocol MyFirstControllerDelegate <NSObject>

@Simon Whitaker 2011-05-29 17:05:37

Simple example...

Let's say the child view controller has a UISlider and we want to pass the value of the slider back to the parent via a delegate.

In the child view controller's header file, declare the delegate type and its methods:

ChildViewController.h

#import <UIKit/UIKit.h>

// 1. Forward declaration of ChildViewControllerDelegate - this just declares
// that a ChildViewControllerDelegate type exists so that we can use it
// later.
@protocol ChildViewControllerDelegate;

// 2. Declaration of the view controller class, as usual
@interface ChildViewController : UIViewController

// Delegate properties should always be weak references
// See http://stackoverflow.com/a/4796131/263871%20for%20the%20rationale
// (Tip: If you're not using ARC, use `assign` instead of `weak`)
@property (nonatomic, weak) id<ChildViewControllerDelegate> delegate;

// A simple IBAction method that I'll associate with a close button in
// the UI. We'll call the delegate's childViewController:didChooseValue: 
// method inside this handler.
- (IBAction)handleCloseButton:(id)sender;

@end

// 3. Definition of the delegate's interface
@protocol ChildViewControllerDelegate <NSObject>

- (void)childViewController:(ChildViewController*)viewController 
             didChooseValue:(CGFloat)value;

@end

In the child view controller's implementation, call the delegate methods as required.

ChildViewController.m

#import "ChildViewController.h"

@implementation ChildViewController

- (void)handleCloseButton:(id)sender {
    // Xcode will complain if we access a weak property more than 
    // once here, since it could in theory be nilled between accesses
    // leading to unpredictable results. So we'll start by taking
    // a local, strong reference to the delegate.
    id<ChildViewControllerDelegate> strongDelegate = self.delegate;

    // Our delegate method is optional, so we should 
    // check that the delegate implements it
    if ([strongDelegate respondsToSelector:@selector(childViewController:didChooseValue:)]) {
        [strongDelegate childViewController:self didChooseValue:self.slider.value];
    }
}

@end

In the parent view controller's header file, declare that it implements the ChildViewControllerDelegate protocol.

RootViewController.h

#import <UIKit/UIKit.h>
#import "ChildViewController.h"

@interface RootViewController : UITableViewController <ChildViewControllerDelegate>

@end

In the parent view controller's implementation, implement the delegate methods appropriately.

RootViewController.m

#import "RootViewController.h"

@implementation RootViewController

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    ChildViewController *detailViewController = [[ChildViewController alloc] init];
    // Assign self as the delegate for the child view controller
    detailViewController.delegate = self;
    [self.navigationController pushViewController:detailViewController animated:YES];
}

// Implement the delegate methods for ChildViewControllerDelegate
- (void)childViewController:(ChildViewController *)viewController didChooseValue:(CGFloat)value {

    // Do something with value...

    // ...then dismiss the child view controller
    [self.navigationController popViewControllerAnimated:YES];
}

@end

Hope this helps!

@Madbreaks 2013-01-16 01:36:20

How though does the parent register as the delegate of the child?

@Simon Whitaker 2013-01-16 11:04:24

By calling detailViewController.delegate = self; (it's in -tableView:didSelectRowAtIndexPath: in the above code snippet.

@Dejell 2013-03-19 10:01:50

Thanks. If the ChildViewController is delegate to UITableView, where should the UITableView methods be? In the child or the parent?

@Danny 2013-06-05 05:50:22

Great example/explanation! Unfortunately, I'm getting a "Cannot find protocol declaration for 'MyProtocol'" error when I try to compile. It's as you described, though: the spawned viewcontroller has the procotol definition in its .h file and invokes the protocol method in its .m file. The hosting viewcontroller has <MyProtocol> in its .h @interface declaration -- which is where the error happens. Your answer seems to be the same, though... any ideas?

@JaseC 2015-06-22 20:14:21

Thank you. I've looked at least a dozen resources and this is the first I've been able to follow. I think the numbered code comments work great to help explain the sequence of it.

@bLacK hoLE 2015-06-26 10:59:35

not working for me, delegate method not calling in rootviewcontroller .

Related Questions

Sponsored Content

88 Answered Questions

[SOLVED] How can I make a UITextField move up when the keyboard is present?

10 Answered Questions

[SOLVED] Pass Method as Parameter using C#

39 Answered Questions

[SOLVED] Passing Data between View Controllers

19 Answered Questions

[SOLVED] How do I create delegates in Objective-C?

49 Answered Questions

[SOLVED] Applications are expected to have a root view controller at the end of application launch

  • 2011-09-22 20:21:51
  • ArtSabintsev
  • 281962 View
  • 371 Score
  • 49 Answer
  • Tags:   ios objective-c

4 Answered Questions

6 Answered Questions

3 Answered Questions

[SOLVED] Xcode using delegate to pass data between controllers

  • 2015-05-20 12:10:07
  • Tony_89
  • 452 View
  • -2 Score
  • 3 Answer
  • Tags:   ios objective-c

4 Answered Questions

1 Answered Questions

[SOLVED] Communication between two childViewControllers

Sponsored Content