Thursday 13 June 2013

Secure Text Field With Custom Numeric KeyPad

Hi Guys,

Today I have decided to discuss about a custom secure text field with custom numeric keypad. Usually, when we have a UITextField with secure option enabled and using a default keyboard, last character entered by user will be shown for some time and then it will be converted in to a dot. Please see below screenshot.

But this is not same if we use a custom keyboard. If we use a custom keyboard, last digit won't appear to end user. When ever we press a key in custom keyboard, a dot will be added directly with out any animation. Please see the below screenshot.


To have last character animation for custom keyboard, I came up with a Custom secured UITextField called MLKSecuredTextField. Lets see how I have implemented it. 

Create a Single View application as shown below :
Now, create MKLSecureTextField class which will be a subclass of UITextField as shown below :
The logic I have followed is, I have subclasses UITextField and created following initializers :

- (id)init
{
    if( self = [super init] )
    {
        [self setUpTextFieldProperties];
    }
    
    return self;
}

- (id)initWithFrame:(CGRect)frame
{
    if( self = [super initWithFrame:frame] )
    {
        [self setUpTextFieldProperties];
    }
    
    return self;
}

- (void)setUpTextFieldProperties
{
    // Following are default Values. Can assign custom values after creating MLKSecuredTextField.
    self.borderStyle = UITextBorderStyleRoundedRect;
    self.textColor = [UIColor clearColor];
    self.font = [UIFont systemFontOfSize:FONT_SIZE];
    self.clearButtonMode = UITextFieldViewModeAlways;
    self.placeholder = PLACEHOLDER_TEXT;
    self.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
    
    self.dotViews = [[NSMutableArray alloc] init];
    
    self.textLength = 0;
    self.text = @"";
    
    // Add text changes observer to get notifications whenever text changes
    [self addObserver:self forKeyPath:TEXT options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
}

 setUpTextFieldProperties method will setup the default properties of our custom textfield and adds a observer to "text" property of textfield. We are observing changes made to text of the text field. I am setting the text color as clear color so that whatever text user enters won't appear.

Whenever there is a change in the text, I am updating the last character to dot and showing the current character for some time. If no text entered, last enter character will be changed to dot after 2 seconds time interval. I have used NSTimer to achieve this. Following is the code :

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context {
    
    if ([keyPath isEqual:TEXT])
    {
        [self textChanged];
    }
}

- (void)textChanged
{
    // Remove the dot view if a character removed
    if( self.textLength > [self.text length] )
    {
        [self invalidateDotViewTimerForIndex:([self.text length ]- 1)];
        
        [[self.dotViews objectAtIndex:(self.textLength - 1)] removeFromSuperview];
        [self.dotViews removeObjectAtIndex:(self.textLength - 1)];
    }
    else if( [self.text length] > 0 )
    {
        [self invalidateDotViewTimerForIndex:([self.text length] - 2)];
        
        [self addCharacterLabelAtIndex:([self.text length] - 1)];
        dotViewTimer = [NSTimer scheduledTimerWithTimeInterval:TIMER_INTERVAL target:self selector:@selector(addDotToLastCharacter) userInfo:nil repeats:NO];
    }
    
    // Capture new lenght
    self.textLength = [self.text length];
    
    // User clicked clear text button. Clear all dot views
    if( self.textLength == 0 )
    {
        [self clearAllDotViews];
    }
}

Override following UITextField methods to set the text rect and editing rect for our custom MLKSecureTextField :

- (CGRect)textRectForBounds:(CGRect) bounds
{
    CGRect origValue = [super textRectForBounds: bounds];
    
    return TEXT_LABEL_OFFSET;
}

- (CGRect)editingRectForBounds:(CGRect) bounds
{
    CGRect origValue = [super textRectForBounds: bounds];
    
    return TEXT_LABEL_OFFSET;
}

Now add business logic to add dots, to show last character for time and clearing all dots when user taps clear button on text field.

- (void)addDotToLastCharacter
{
    [self.characterLabel removeFromSuperview];
    [self addDotViewForCharAtIndex:([self.text length] - 1)];
}

- (void)addDotViewForCharAtIndex:(NSInteger)index
{
    UIView *dotView = [[UIView alloc] initWithFrame:DOT_VIEW_RECT];
    dotView.backgroundColor = [UIColor blackColor];
    [dotView.layer setMasksToBounds:YES];
    [dotView.layer setCornerRadius:DOT_RADIUS];
    
    [self addSubview:dotView];
    [self.dotViews addObject:dotView];
}

- (void)addCharacterLabelAtIndex:(NSInteger)index
{
    self.characterLabel = [[UILabel alloc] initWithFrame:CHAR_LABEL_RECT];
    self.characterLabel.text = [NSString stringWithFormat:@"%C",[self.text characterAtIndex:index]];
    self.characterLabel.font = self.font;
    self.characterLabel.backgroundColor = [UIColor clearColor];
    
    [self addSubview:self.characterLabel];
}

- (void)invalidateDotViewTimerForIndex:(NSInteger)index
{
    if( dotViewTimer.isValid )
    {
        [dotViewTimer invalidate];
        [self.characterLabel removeFromSuperview];
        [self addDotViewForCharAtIndex:index];
    }
}

- (void)clearAllDotViews
{
    while( self.dotViews.count )
    {
        [[self.dotViews objectAtIndex:self.dotViews.count-1] removeFromSuperview];
        [self.dotViews removeObjectAtIndex:self.dotViews.count-1];
    }
}

Here are the #defines I have used :

#define DOT_VIEW_RECT       CGRectMake(8 + (index * (9 + 1.5)), 13, 9, 9)
#define CHAR_LABEL_RECT     CGRectMake(8 + (index * (9 + 1.5)), 10, 9, 14)

#define TEXT_LABEL_OFFSET   CGRectOffset(origValue, 0.0f, 3.0f)

#define TEXT            @"text"
#define FONT_SIZE       17
#define TIMER_INTERVAL  2.0

#define DOT_RADIUS      4.5f

#define PLACEHOLDER_TEXT    @"MLKSecuredTextField"

Okay, we have completed creating custom secure text field. Now use it in a view controller and see the output. Create MLKSecureTextField and add it to the View :

secureTextField = [[MLKSecuredTextField alloc] initWithFrame:CGRectMake(20, 20, 280, 30)];
secureTextField.delegate = self;
[self.view addSubview:secureTextField];

For your understanding, I have used three text fields, one MLKTextFieldField with custom numeric keypad, one UITextField with default keypad and one UITextField with custom numeric keypad.
Now try to enter text in the UITextField with default keyboard :
See you are able to see last character for some time, after that it will be converted to a dot. Lets see what is the behavior with UITextField with custom numeric keypad :
Observe the behavior, when ever you press a key it will be directly added as a dot in the text field. Lets see behavior with our custom MLKSecureTextField :
Have you observed that, last character is appeared for some time and after that changed to a dot. Yeah!!!! we got the expected behavior. 

Thats all from this post. Please add your comments and suggestions.


Wednesday 12 June 2013

Constructors and Creating Objects in Objective C

Hi, how are you doing guys.... I am back... I hope you guys got some familiarity with the Objective C syntax we discussed in one of my last tutorial. In this tutorial we will learn about how we write constructors/initializers and how to create an object in Objective C.

Lets start.... constructor/initializer is a method which we call while creating a new object in Object Oriented Programming. In this method we write all the code related to initial setup of an object. Objective C have a default construction called init which is present in its root class NSObject. We can override default initializer. It looks like below :

Default Initializer


- (id)init
{
    if( self = [super init] )
    {
        // Initialize your object here
    }
    
    return self;
}

Confused!!!! Lets go one by one line. 

1. - (id)init

- represents it is a class method. id is generic type. It can hold any kind of object. We will see more about id in our next tutorials. init is the initializer name.

2. ifself = [super init] )

self represents current instance/object. [super init] will call the super class initializer.

3. return self;

Finally it returns the properly initialized object.

Custom Initializer 

Okay, now lets create a custom constructor. We will take the same Employee class earlier and will try to initialize his firstName, lastName and salary. Here is the code for it :

Interface 


@interface Employee : NSObject
{
    NSString *firstName;
    NSString *lastName;
    float salary;
}

- (id)initWithFirstName:(NSString *)aFirstName
               lastName:(NSString *)aLastName
                 salary:(float)aSalary;

@end

Implementation 


#import "Employee.h"

@implementation Employee

- (id)initWithFirstName:(NSString *)aFirstName
               lastName:(NSString *)aLastName
                 salary:(float)aSalary
{
    if( self = [super init] )
    {
        firstName = aFirstName;
        lastName = aLastName;
        salary = aSalary;
    }
    
    return self;
}

@end

Above code explains how a class Employee with properties firstName, lastName and salary and a constructor looks like. Now, lets create an object of type Employee....

Object Creation

Option 1:

// Using Default Initializer
Employee *employeeWithDefaultInit = [[Employee alloc] init];
        
// Using Custom Initializer
Employee *employeeWithCustomInit = [[Employee alloc] initWithFirstName:@"Naga" lastName:@"Malleswar" salary:5000];

In the above code I have associated two method calls in single statement. We can make them two separate statements like below, but followed convention is Option 1.

Option 2:

// Using Default Initializer
Employee *employeeWithDefaultInit = [Employee alloc];
employeeWithDefaultInit = [employeeWithDefaultInit init];
        
// Using Custom Initializer
Employee *employeeWithCustomInit = [Employee alloc];
employeeWithCustomInit = [employeeWithCustomInit initWithFirstName:@"Naga" lastName:@"Malleswar" salary:5000];

Both the above options are same. Only thing is convention. Most of the programmers follow Option 1 to create objects. One may get a doubt. What is alloc is??? alloc is a method to allocate memory. Object creation completes only if we send both alloc and init messages to a new object.

Thanks for your time guys. In our next tutorial, we will create set and get methods for the properties in Employee class. Please feel free to add your comments and suggestion.

Wednesday 5 June 2013

Introduction to Objective C and its Syntax


Hi Guys, hope all of you are doing good. In this tutorial, I am planning to discuss something about Objective C and how it differs from other programming languages. I am writing this post to help beginners who are learning Objective C to develop Mac OS X or iOS applications. Prior knowledge of OOPS will help to understand Objective C better. Apple have used Objective C for their OS X, iOS and to develop their frameworks COCOA(MAC) and COCOA Touch(iOS) frame works.

Object Oriented Language :

Objective C is Object Oriented C. C is a structured language. We can't create classes and objects in C. Where as in Objective C we can create classes, objects etc how other object oriented languages are doing. Objective C is super set of C. We can compile any C program using a Objective C complier and we can write any C code inside a Objective C class.

Message Passing :

Objective C uses message passing instead of method calling  which is different from other languages like C++, Java etc. Message passing means, the target of the message is resolved during run time. System resolves during run time whether the receiver responds to the method or not. This helps in attaining dynamic binding. In Objective C, if you send a message to nil, it will simply discard the message and nothing happens. Where as in Java, you will get a run time exception.

Syntax :

Objective C syntax differs from Java, C++ and other Object Oriented languages. It follows Small talk kind of syntax. When comes to using primitive data types(int, float, char etc) it follows C syntax.

Lets suppose there is a method called firstName in class Employee. Following code snippet shows how Objective C syntax looks like to send setFirstName message to object emp of class Employee :

Objective C :

// Method Syntax
- (NSString *)firstName
{
return firstName;
}

// Message Passing
[emp firstName];

Java :

// Method Syntax
String firstName()
{
return firstName;
}

// Method Calling
emp.firstName();

C++ :

// Method Syntax
string firstName
{
return firstName;
}

// Method Calling
emp->firstName();

Now, take a look at syntax of method having single argument. Lets say, setSalary with int argument.

Objective C :

// Method Syntax
- (void)setSalary:(int)aSalary
{
}

//  Message Passing
[emp setSalary:10000];

Java :

// Method Syntax
void setSalary()
{
}

// Method Calling
emp. setSalary(1000);

 C++ :

// Method Syntax
void setSalary()
{
}

// Method Calling
emp-> setSalary(1000);

Now, take a look at syntax of method having multiple arguments. For method to set firstName and lastName of employee :

Objective C :

// Method Syntax

- (void)setFirstName:(NSString *)fName andLastName:(NSString *)lName
{
}

// Message passing
[emp setFirstName:fName andLastName:lName];

Java :

// Method Syntax
void setFirstNameAndLastName(String fName, String lName)
{
}

// Method Calling
emp. setFirstNameAndLastName(fName,lName);

C++ :

// Method Syntax
void setFirstNameAndLastName(string fName, string lName)
{
}

// Method Calling
emp->firstName(fName,lName);

Interfaces and implementations

In Objective C, each class has two sections. One is interface and other one is implementation. As per coding conventions, interface will be placed in "Header(.h)" file and implementation placed in "Implementation(.m)" file.

We will continue with Employee class. Interface for an Employee class will look like below:


Interface :

@interface Employee
{
         // Instance variables
         NSString *firstName;
         NSString *lastName:
}

// Instance Methods
- (NSString *)firstName;
- (NSString *)lastName;

- (void)setFirstName:(NSString *)firstName;
- (void)setLastName:(NSString *)lastName;

// Class Methods
+ (int)numberOfEmployees;

@end

Implementation :

@implementation Employee

// Instance Methods
- (NSString *)firstName
{

}

- (NSString *)lastName
{

}

- (void)setFirstName:(NSString *)firstName
{

}

- (void)setLastName:(NSString *)lastName
{

}

// Class Methods
+ (int)numberOfEmployees
{

}


@end

NSObject is the root class of all Objective C classes. Each class of Objective C is inherited from root class NSObject.

Thats all for now. I hope you guys got good understanding about Objective C. Please feel free to add your comments and suggestions.

In our next topic, we will cover constructors and creating objects in Objective C.

Monday 3 June 2013

Custom Split View with Animation

Hi All,

Hope you guys are doing well. In our last tutorial Custom Split View , we have discussed about creating a custom split view controller which will show both Master and Detail views at a time. I hope all of you guys have enjoyed that tutorial.

In this tutorial, we will add some UIView animations to the Custom Split View which we have created last week. If user applies a left gesture on the split view, it will hide the "Master View", if user applies a right gesture, it will show the "Master View".

Okay, lets start. Please open the Custom Split View class MLKSplitViewController class we have created. Create two gesture recognizers(one for left and other one for right) and a BOOL property to keep track the status of Master View. 

@property(nonatomic,retain) UISwipeGestureRecognizer *leftSwipeGestureRecognizer;

@property(nonatomic,retain) UISwipeGestureRecognizer *rightSwipeGestureRecognizer;

@property(nonatomic,assign) BOOL isMasterViewHidden;

Synthesize newly created properties :

@synthesize leftSwipeGestureRecognizer;
@synthesize rightSwipeGestureRecognizer;

@synthesize isMasterViewHidden;



In - (void)viewDidLoad method add the code to create gesture recognizers and hooking up with appropriate action methods :

    // Add left gesture recognizer
    self.leftSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(hideMasterView:)];
    [self.leftSwipeGestureRecognizer setDirection:UISwipeGestureRecognizerDirectionLeft];
    [self.view addGestureRecognizer:leftSwipeGestureRecognizer];

    // Add right gesture recognizer
    self.rightSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(showMasterView:)];
    [self.rightSwipeGestureRecognizer setDirection:UISwipeGestureRecognizerDirectionRight];
    [self.view addGestureRecognizer:rightSwipeGestureRecognizer];

Now, implement the two actions for gesture recognizers and corresponding utility method :


#pragma mark -
#pragma mark - Gestures

- (IBAction)hideMasterView:(id)sender
{
    if( !isMasterViewHidden )
    {
        [UIView animateWithDuration:1.0 animations:^{
        
            [self setMasterViewFrame: CGRectMake(-MASTER_VIEW_WIDTH,0, MASTER_VIEW_WIDTH, self.view.bounds.size.height) detailViewFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
        }];
        
        isMasterViewHidden = YES;
    }
    
}

- (IBAction)showMasterView:(id)sender
{
    if( isMasterViewHidden )
    {
        [UIView animateWithDuration:1.0 animations:^{
                        
            [self setMasterViewFrame:CGRectMake(0,0, MASTER_VIEW_WIDTH, self.view.bounds.size.height) detailViewFrame:CGRectMake(MASTER_VIEW_WIDTH + SPLIT_GAP, 0, self.view.bounds.size.width - MASTER_VIEW_WIDTH - SPLIT_GAP, self.view.bounds.size.height)];
        }];
        
        isMasterViewHidden = NO;
    }
}

- (void)setMasterViewFrame:(CGRect)masterViewFrame detailViewFrame:(CGRect)detailViewFrame
{
    UIViewController *masterViewController = [self.viewControllers objectAtIndex:0];
    UIViewController *detailViewController = [self.viewControllers objectAtIndex:1];
    
    masterViewController.view.frame = masterViewFrame;
    detailViewController.view.frame = detailViewFrame;
}

Change the implementation of the - (void)layoutSubviews method according to the newly added utility method - (void)setMasterViewFrame:(CGRect)masterViewFrame detailViewFrame:(CGRect)detailViewFrame :

- (void)layoutSubviews
{
    if( !isMasterViewHidden )
    {
        [self setMasterViewFrame:CGRectMake(0,0, MASTER_VIEW_WIDTH, self.view.bounds.size.height) detailViewFrame:CGRectMake(MASTER_VIEW_WIDTH + SPLIT_GAP, 0, self.view.bounds.size.width - MASTER_VIEW_WIDTH - SPLIT_GAP, self.view.bounds.size.height)];
    }
}

We are done with the coding, lets see how output looks :
 Now apply a left swipe. See the output. "Master View" is hidden!!!!!!!!!!.
 Apply a right swipe. See the output. "Master View" is shown!!!!!!!!!!.
 Apply left and right swipes in landscape mode. Results are same as portrait!!!!!!


Hope you guys have enjoyed this tutorial about Custom Split View with Animation. Please feel free to add your comments and suggestions.

You can find source code here Source Code .