The Pensive Programmer

Objective-C Protocols and Delegates

My earlier  article about building a currency formatter for a UITextField generated a few comments and some confusion about how to use delegates in iPhone programming. In this article/tutorial I hope to clear up any confusion and tie it back to using the the currency formatter with the UITextField.

What Is A Protocol?

The Apple documentation on a protocol can be found  here. The documentation summarizes that:
Protocols declare methods that can be implemented by any class. Protocols are useful in at least three situations:
  • To declare methods that others are expected to implement
  • To declare the interface to an object while concealing its class
  • To capture similarities among classes that are not hierarchically related
The situation that we are interested in is the first one that allows methods to be declared that others are expected to implement. In this situation protocols are very similar to Java and C# interfaces. In our particular case Apples UIKit framework provides a protocol for use with the UITextField. This protocol is conveniently named  UITextFieldDelegate. Defined in this protocol are 7 optional methods that a program can implement to change the behavior of a UITextField. Keep in mind that Apple has only provided the skeleton of the method and not any actual implementation. The implementation is left up to the programmer to implement for their specific needs. In our case we only need to implement 2 of the methods.
?
1
2
3
- ( BOOL )textField:(UITextField *)textField shouldChangeCharactersInRange:( NSRange )range
             replacementString:( NSString *)string
- ( BOOL )textFieldShouldReturn:(UITextField *)textField

So now we have all we need to create a stubbed out version of our UITextFieldDelegate protocol implementation:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
//  CurrencyFormatDelegate.h
#import <Foundation/Foundation.h>
 
@interface CurrencyFormatDelegate : NSObject <UITextFieldDelegate>{
 
}
 
//MARK: -
//MARK: UITextFieldDelegate Methods
-( BOOL )textFieldShouldReturn:(UITextField *)textField;
-( BOOL )textField:(UITextField *)textField shouldChangeCharactersInRange:( NSRange )range
             replacementString:( NSString *)string;
@end

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//  CurrencyFormatDelegate.m
#import "CurrencyFormatDelegate.h"
 
@implementation CurrencyFormatDelegate
 
//  Dismisses the keyboard when the return button is pressed
-( BOOL )textFieldShouldReturn:(UITextField *)textField{
  [textField resignFirstResponder];
  return NO ;
}
 
-( BOOL )textField:(UITextField *)textField shouldChangeCharactersInRange:( NSRange )range
             replacementString:( NSString *)string{
  return YES ;
}
@end

The @interface line is where we tell the compiler that we are implementing the UITextFieldDelegate with this class. Keep in mind that it doesn't have to be a separate class like here, and could instead be the controller or any other class where you think the delegate methods should be implemented. I like doing a separate class since it makes the delegate easy to reuse and keeps the code modularized.

Since we have not yet provided any implementation, if we took this above code as is and made it the delegate of a UITextField the text field would work the same way it does without a delegate attached. Since this post is not about the implementation of the currency format delegate I'm going to point readers to my  previous post on implementation and move on to how to use the delegate.

What Is A Delegate?

Once again the Apple  documentation is quite good at explaining delegation. In delegation programming one object (in our case the UITextField) relies on another object (the CurrencyFormatDelegate) to provide a certain set of functionality. As the Apple documentation explains, using delegation programming allows the programmer to customize the behavior of framework objects without having to subclass. In turn this allows the programmer to aggregate multiple delegates into one object and extend the functionality of the existing framework. Now, what does all this mean for the currency formatter? In order to get our delegate to execute at the proper time we have to attach it to our UITextField. Assume that we have already defined and linked a UITextField in Interface Builder and we called it currencyTextField. In the controllers viewDidLoad we just need to assign the CurrencyFormatDelegate our UITextFields delegate property.
?
1
2
3
4
5
6
7
8
9
10
11
12
//  TestController.h
@class CurrencyFormatDelegate;
 
@interface BuyCarViewController : UIViewController {
  UITextField *currencyTextField;
@private
  CurrencyFormatDelegate* currencyFormatDelegate;
}
 
@property ( nonatomic , retain) IBOutlet UITextField* currencyTextField;
@property ( nonatomic , assign) CurrencyFormatDelegate* currencyFormatDelegate;
@end

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//  TestController.m
 
#import "TestController.h"
#import "CurrencyFormatDelegate.h"
 
@implementation TestController
 
@synthesize currencyTextField;
@synthesize currencyFormatDelegate;
@synthesize buyCarView, amortizationView;
 
// MARK: -
// MARK: View Boilerplate - Object Management
// Implement viewDidLoad to do additional setup after
// loading the view, typically from a nib.
- ( void )viewDidLoad {
  [ self setCurrencyFormatDelegate:[[CurrencyFormatDelegate alloc] init]];
  
  [currencyTextField setDelegate:currencyFormatDelegate];
  [ super viewDidLoad];
}
 
- ( void )viewDidUnload {
  [currencyTextField setDelegate: nil ];
}
 
- ( void )dealloc {
     [currencyFormatDelegate release];
     [ super dealloc];
}

You'll notice a bit of object management code to make sure that we properly allocate and release the delegate when we are done with it. The key line in all of the controller code is:
?
1
[currencyTextField setDelegate:currencyFormatDelegate];

It is here where we tell the text field to user our delegate and call our implementation of the protocol methods.

I hope that this clears up some of the issues people were having while trying to use my text field currency formatter. The code above should mostly work as is since I took it from a working program and pared it down for the post. If there are any copy and paste issues they shouldn't be too hard to correct.

Further Reading

The  delegate pattern is a fundamental object oriented design pattern. If you want to know more about the delegate pattern and design patters in general check out  Design Patterns.

转自: http://www.thepensiveprogrammer.com/2010/05/objective-c-protocols-and-delegates.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值