×

iOS Protocols & Delegates


Protocols & Delegates

As we studied in Objective-C ,

What are Protocols and Delegates

Now we will see how to implement the conecpt of Protocols & Delegates in iOS Programming . You may refer the Detailed Concept before starting this tutorial here, Protocols & Delegates . In this tutorial your concepts of NSMutableDictionary , Protocols & Delegates will gets clear.

So Let's begin with Student's Form App. We create one Student Form which shows the name and age of a student. And we will provide an edit functionality so that user can change his name or age as per his need.

We created a simple category of UIView + Autolayout so that your app should becomes responsive in every iPhone Screen. Make sure you had added this category "UIView + Autolayout" in your project.

Doubt in Adding Category ?

You can refer our UIView + Autolayout Tutorial here

Final Output :-

1) Original Student Form


2) Screen When we click on edit button


3) Edit Details of Student here


4) See the reflected changes in original Form


Create a new Project or Use an existing one .

Open Xcode Goto File > New >Project >Single View Application > Enter Project Name (eg :- FirstProjectViewController) > Done.

1) Copy this code in AppDelegate.m File's didFinishLaunching Method

//AppDelegate.m
//  Created by Manish Methani.
//  Copyright © 2017 Codzify. All rights reserved.
//

#import "AppDelegate.h"
#import "ViewController.h"      
@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    
    ViewController *abcController = [[ViewController alloc]init];
    
    UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:abcController];
     self.window.rootViewController = navController;
    [self.window makeKeyAndVisible];
    return YES;
}

@end

What we did in this method is we want ViewController file to be loaded first when App starts and then we added that ViewController to NavigationController . You may refer Details of UINavigationController here.

2) ViewController.m File looks like

//Created by Manish Methani.
//  Copyright © 2017 Codzify. All rights reserved.
//
#import "ViewController.h"
#import "UIView+Autolayout.h"
#import "EditStudentDetailsViewController.h"

#define PADDING   12
@interface ViewController () 
{
    UILabel *labelNameDetails;
    UILabel *labelAgeDetails;
}
@end

@implementation ViewController


- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor whiteColor];
   
  /* initialise Navigation Bar View */
     [self initialiseNavigationBarView];
   
  /* initialise Student Form View */
    [self initializeStudentFormView];
}


-(void)initialiseNavigationBarView

{
  /* All about Navigation Controller Title , Back Button */
    NSArray *ver = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."];
    
    /* give Background color to navigation bar */
    if ([[ver objectAtIndex:0] intValue] >= 7) {
        // iOS 7.0 or later
        self.navigationController.navigationBar.barTintColor = [UIColor colorWithRed:0/255.0 green:169/255.0  blue:98/255.0 alpha:1.0];;
        self.navigationController.navigationBar.translucent = NO;
    }else {
        // iOS 6.1 or earlier
        self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:0/255.0 green:169/255.0  blue:98/255.0 alpha:1.0];;
        self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:0/255.0 green:169/255.0  blue:98/255.0 alpha:1.0];;
    }
    
  /* give title to navigation bar */
    self.navigationItem.title = @"Student Details";
    
    
  /* give Right Button to Navigation Bar */
    UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithTitle:@"Edit Details" style:UIBarButtonItemStylePlain target:self action:@selector(editButtonClicked)];
    
  /* Chnage TextColor of Left Or Right BarButton on Navigation Item */
    [item setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]} forState:UIControlStateNormal];
    
    self.navigationItem.rightBarButtonItems = @[item];
    
  /* give titleColor to Navigation Title */
    [self.navigationController.navigationBar setTitleTextAttributes:
     @{NSForegroundColorAttributeName:[UIColor whiteColor]}];

}

- (void)initializeStudentFormView
{
    UILabel *labelName = [[UILabel alloc]init];
    [self.view addSubview:labelName];
    [labelName autolayout];
    [labelName leftAlign:PADDING];
    [labelName topAlign:40];
    [labelName width:90];
    [labelName height:24];
    labelName .text = @"Name :";
    labelName.textColor = [UIColor colorWithRed:0/255.0 green:169/255.0  blue:98/255.0 alpha:1.0];
    labelName.font = [UIFont fontWithName:@"Helvetica-Bold" size:20.0];
    
    
    labelNameDetails = [[UILabel alloc]init];
    [self.view addSubview:labelNameDetails];
    [labelNameDetails autolayout];
    [labelNameDetails leftAlign:PADDING relativeToView:labelName];
    [labelNameDetails topAlign:40];
    [labelNameDetails rightAlign:PADDING];
    [labelNameDetails height:24];
    labelNameDetails.text = @"Manish Methani";
    labelNameDetails.textAlignment = NSTextAlignmentLeft;
    
    UILabel *labelAge = [[UILabel alloc]init];
    [self.view addSubview:labelAge];
    [labelAge autolayout];
    [labelAge leftAlign:PADDING];
    [labelAge topAlign:PADDING relativeToView:labelName];
    [labelAge width:90];
    [labelAge height:24];
    labelAge.text = @"Age";
    labelAge.textColor = [UIColor colorWithRed:0/255.0 green:169/255.0  blue:98/255.0 alpha:1.0];
    labelAge.font = [UIFont fontWithName:@"Helvetica-Bold" size:20.0];
    
 
    labelAgeDetails = [[UILabel alloc]init];
    [self.view addSubview:labelAgeDetails];
    [labelAgeDetails autolayout];
    [labelAgeDetails leftAlign:PADDING relativeToView:labelAge];
    [labelAgeDetails topAlign:PADDING relativeToView:labelName];
    [labelAgeDetails rightAlign:PADDING];
    [labelAgeDetails height:24];
    labelAgeDetails.text = @"21";
    labelAgeDetails.textAlignment = NSTextAlignmentLeft;


    
    UILabel *labelGrabdetails = [[UILabel alloc]init];
    [self.view addSubview:labelGrabdetails];
    [labelGrabdetails autolayout];
    [labelGrabdetails leftAlign:PADDING];
    [labelGrabdetails centerYAlign];
    [labelGrabdetails rightAlign:PADDING];
    labelGrabdetails.numberOfLines = 0;
    labelGrabdetails.lineBreakMode = NSLineBreakByWordWrapping;
    labelGrabdetails.text = @"Here all the concepts of NSMutableDictionary , Protocols & Delagtes will be cleared with the Mostly used Example in Real Word. 'An Edit Form ' ";
    labelGrabdetails.textColor = [UIColor colorWithRed:0/255.0 green:169/255.0  blue:98/255.0 alpha:1.0];
    labelGrabdetails.font = [UIFont fontWithName:@"Helvetica-Bold" size:16.0];;
    
    
}


#pragma mark - Edit Button Clicked
-(void)editButtonClicked
{
    NSMutableDictionary *passStudentDetailsUsingDictionary = [[NSMutableDictionary alloc]init];
    [passStudentDetailsUsingDictionary setObject:labelNameDetails.text forKey:@"name"];
    [passStudentDetailsUsingDictionary setObject:labelAgeDetails.text forKey:@"age"];
    
    EditStudentDetailsViewController *editDetailsControllerReference = [[EditStudentDetailsViewController alloc ]init];
    
    /* Register a delegate in EditStudentDetailsController Here */
    editDetailsControllerReference.delegateRef = self;
    
    /* Pass Student Data to EditStudentDetailsController like this */
    editDetailsControllerReference.studentDetailsDictToBeEdited = passStudentDetailsUsingDictionary;
    
    [self.navigationController pushViewController:editDetailsControllerReference animated:YES];
}


#pragma mark - EditStudentDetails Delagate
-(void)editDetailsMethod:(NSDictionary *)studentDetailsDictionary
{
    labelNameDetails.text = [studentDetailsDictionary valueForKey:@"name"];
    labelAgeDetails.text = [studentDetailsDictionary valueForKey:@"age"];
}

What we did this in this Code is we initialised the UI Part which includes labelName , labelAge , Edit Button on Navigation bar . We had covered all the details in UINavigationController and Autolayouts tutorials. i hope you can design any Ui of your App now.

#pragma mark - Edit Button Clicked
-(void)editButtonClicked
{
    NSMutableDictionary *passStudentDetailsUsingDictionary = [[NSMutableDictionary alloc]init];
    [passStudentDetailsUsingDictionary setObject:labelNameDetails.text forKey:@"name"];
    [passStudentDetailsUsingDictionary setObject:labelAgeDetails.text forKey:@"age"];
    
    EditStudentDetailsViewController *editDetailsControllerReference = [[EditStudentDetailsViewController alloc ]init];
    
  /* Register a delegate in EditStudentDetailsController Here */
    editDetailsControllerReference.delegateRef = self;
    
  /* Pass Student Data to EditStudentDetailsController like this */
    editDetailsControllerReference.studentDetailsDictToBeEdited = passStudentDetailsUsingDictionary;
    
    [self.navigationController pushViewController:editDetailsControllerReference animated:YES];
}

Inside editButton's Action method we created a passStudentDetailsUsingDictionary dictionary . Because we have to pass the original Data to another Controller. Then with the help of pushViewController we moved to EditStudentDetailsController

editDetailsControllerReference.delegateRef = self;

Now how do you get the edited changes in second Cotroller to orignal form. So with the help of delegates we can do this. Simple concept of Delegates is do some changes in edited form and pass those edited changes back to orignal Form with the help of Deictionaries or Arrays or Any Class.

3) EditStudentDetailsViewController.h File looks like

//
//  EditStudentDetailsViewController.h
//  FirstProjectViewController
//
//  Created by Manish Methani 
//  Copyright © 2017 Codzify. All rights reserved.
//

#import 

@protocol EditStudentDetailsDelegate 

-(void)editDetailsMethod : (NSDictionary *)studentDetailsDictionary;

@end

@interface EditStudentDetailsViewController : UIViewController
@property(weak,nonatomic)iddelegateRef;

@property (strong,nonatomic)NSMutableDictionary *studentDetailsDictToBeEdited;
@end

3) EditStudentDetailsViewController.m File looks like

//
//  EditStudentDetailsViewController.m
//  FirstProjectViewController
//
//  Created by Manish Methani .
//  Copyright © 2017 Codzify. All rights reserved.
//

#import "EditStudentDetailsViewController.h"
#import "UIView+Autolayout.h"

#define PADDING 12
@interface EditStudentDetailsViewController ()
{
    NSMutableDictionary *studentDict ;
    UITextField *textFieldAge;
    UITextField *textFieldName;
}
@end

@implementation EditStudentDetailsViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    studentDict = [[NSMutableDictionary alloc]init];
    
    /* initialise Navigation Bar View */
    [self initialiseNavigationBarView];
    
    /* initialise Student Form View */
    [self initializeStudentFormView];
}


-(void)initialiseNavigationBarView

{
    /* All about Navigation Controller Title , Back Button */
    NSArray *ver = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."];
    
    /* give Background color to navigation bar */
    if ([[ver objectAtIndex:0] intValue] >= 7) {
        // iOS 7.0 or later
        self.navigationController.navigationBar.barTintColor = [UIColor colorWithRed:0/255.0 green:169/255.0  blue:98/255.0 alpha:1.0];;
        self.navigationController.navigationBar.translucent = NO;
    }else {
        // iOS 6.1 or earlier
        self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:0/255.0 green:169/255.0  blue:98/255.0 alpha:1.0];;
        self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:0/255.0 green:169/255.0  blue:98/255.0 alpha:1.0];;
    }
    
    /* give title to navigation bar */
    self.navigationItem.title = @"Edit Details";
    
    
    /* give Right Button to Navigation Bar */
    UIBarButtonItem *rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Save" style:UIBarButtonItemStylePlain target:self action:@selector(saveButtonClicked)];
    
    UIBarButtonItem *lefttBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"< Back" style:UIBarButtonItemStylePlain target:self action:@selector(backButtonClicked)];

    
    /* Chnage TextColor of Left Or Right BarButton on Navigation Item */
    [rightBarButtonItem setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]} forState:UIControlStateNormal];
    [lefttBarButtonItem setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]} forState:UIControlStateNormal];
    
    self.navigationItem.rightBarButtonItem = rightBarButtonItem;
    self.navigationItem.leftBarButtonItem = lefttBarButtonItem;

    /* give titleColor to Navigation Title */
    [self.navigationController.navigationBar setTitleTextAttributes:
     @{NSForegroundColorAttributeName:[UIColor whiteColor]}];
    
}

- (void)initializeStudentFormView
{
    UILabel *labelName = [[UILabel alloc]init];
    [self.view addSubview:labelName];
    [labelName autolayout];
    [labelName leftAlign:PADDING];
    [labelName topAlign:40];
    [labelName width:90];
    [labelName height:24];
    labelName .text = @"Name :";
    labelName.textColor = [UIColor colorWithRed:0/255.0 green:169/255.0  blue:98/255.0 alpha:1.0];
    labelName.font = [UIFont fontWithName:@"Helvetica-Bold" size:20.0];
    
    
    textFieldName = [[UITextField alloc]init];
    [self.view addSubview:textFieldName];
    [textFieldName autolayout];
    [textFieldName leftAlign:PADDING relativeToView:labelName];
    [textFieldName topAlign:40];
    [textFieldName rightAlign:PADDING];
    [textFieldName height:24];
    textFieldName.placeholder = @"Name";
    textFieldName.layer.borderColor = [UIColor colorWithRed:0/255.0 green:169/255.0  blue:98/255.0 alpha:1.0].CGColor;
    textFieldName.layer.borderWidth = 1.0;
    textFieldName.layer.cornerRadius = 3.0;
    textFieldName.textAlignment = NSTextAlignmentCenter;
    [textFieldName becomeFirstResponder];
    textFieldName.clearButtonMode = UITextFieldViewModeWhileEditing;
    
    UILabel *labelAge = [[UILabel alloc]init];
    [self.view addSubview:labelAge];
    [labelAge autolayout];
    [labelAge leftAlign:PADDING];
    [labelAge topAlign:PADDING relativeToView:labelName];
    [labelAge width:90];
    [labelAge height:24];
    labelAge.text = @"Age";
    labelAge.textColor = [UIColor colorWithRed:0/255.0 green:169/255.0  blue:98/255.0 alpha:1.0];
    labelAge.font = [UIFont fontWithName:@"Helvetica-Bold" size:20.0];
    
    
    textFieldAge = [[UITextField alloc]init];
    [self.view addSubview:textFieldAge];
    [textFieldAge autolayout];
    [textFieldAge leftAlign:PADDING relativeToView:labelAge];
    [textFieldAge topAlign:PADDING relativeToView:labelName];
    [textFieldAge rightAlign:PADDING];
    [textFieldAge height:24];
    textFieldAge.placeholder = @"Age";
    textFieldAge.layer.borderColor = [UIColor colorWithRed:0/255.0 green:169/255.0  blue:98/255.0 alpha:1.0].CGColor;
    textFieldAge.layer.borderWidth = 1.0;
    textFieldAge.layer.cornerRadius = 3.0;
    textFieldAge.textAlignment = NSTextAlignmentCenter;
    textFieldAge.keyboardType = UIKeyboardTypeNumberPad;
    textFieldAge.clearButtonMode = UITextFieldViewModeWhileEditing;
    
    /* Prepopulate data into textField */
    
    textFieldName.text = [_studentDetailsDictToBeEdited valueForKey:@"name"];
    textFieldAge.text = [_studentDetailsDictToBeEdited valueForKey:@"age"];
    
    
    
}

/* Get data From Previous Controller to be Prepopulate Student Info */
-(void)setStudentDetailsDictToBeEdited:(NSMutableDictionary *)studentDetailsDictToBeEdited
{
    _studentDetailsDictToBeEdited = studentDetailsDictToBeEdited;
}

#pragma mark - Actions
-(void)saveButtonClicked
{
    [studentDict setObject:textFieldName.text forKey:@"name"];
    [studentDict setObject:textFieldAge.text forKey:@"age"];

    
    [self.delegateRef editDetailsMethod:studentDict];
    
    /* Pop to Previous Controller once Done */
    [self.navigationController popViewControllerAnimated:YES];
}

-(void)backButtonClicked
{
    [self.navigationController popViewControllerAnimated:YES];
}
@end

In EditStudentDetailsViewController.h file we declared Delegate named EditStudentDetailsDelegate which includes -(void)editDetailsMethod : (NSDictionary *)studentDetailsDictionary; method. With the help of this method we pass the edited data back to original Form. Please try not to skip any part of this tutorial . Everything is linked .

/* Get data From Previous Controller to be Prepopulate Student Info */
-(void)setStudentDetailsDictToBeEdited:(NSMutableDictionary *)studentDetailsDictToBeEdited
{
    _studentDetailsDictToBeEdited = studentDetailsDictToBeEdited;
}

This is simply gettter/Setter method concept. What you have passed from Orignal ViewController is setted by using this SetMethod. StudentDetailsDictToBeEdited this is name of Dictionary which we declared in EditStudentDetailsController.h File. Simply you have to write setBefore Dictionary name.

#pragma mark - Actions
-(void)saveButtonClicked
{
    [studentDict setObject:textFieldName.text forKey:@"name"];
    [studentDict setObject:textFieldAge.text forKey:@"age"];

    
    [self.delegateRef editDetailsMethod:studentDict];
    
    /* Pop to Previous Controller once Done */
    [self.navigationController popViewControllerAnimated:YES];
}

This method uses delegateRef to pass edited data back to orignal ViewController . Make sure you implemnted the delegate method in ViewController.h file

Then in ViewController.h file we implemented the delegate method

#pragma mark - EditStudentDetails Delagate
-(void)editDetailsMethod:(NSDictionary *)studentDetailsDictionary
{
    labelNameDetails.text = [studentDetailsDictionary valueForKey:@"name"];
    labelAgeDetails.text = [studentDetailsDictionary valueForKey:@"age"];
}