Friday, July 9, 2010

Outlets and Actions - Easy Loan Calculator Part 2

Ok, let's go on to implement the codes, the nuts and bolts of the calculator. In summary, we have to drag drop labels, textboxes to receive user input, some buttons to trigger the execution of the program, code the formula for the loan, and out put the result to labels again. Let's begin.

Under Resources, click on EasyLoanCalculatorViewController.xib file to open Interface Builder.
You will see a blank view. From the Library window, (you can open the Library from Tools -> Library) you can select your UI controls to the view. Its essentially like toolbox in visual studio.

So carry on and design your UI till it resembles something like the below. Ignore the picture of the percetage sign at the end.


In the process, you would have dragged and dropped several labels, text boxes, and buttons.

Next, let's type out the code for the EasyLoanCalculatorViewController.h file. The code is listed below.




#import

@interface EasyLoanCalculatorViewController : UIViewController {
IBOutlet UITextField *tbxLoanAmount;
IBOutlet UITextField *annualInterestRate;
IBOutlet UITextField *noOfYears;
IBOutlet UILabel *monthlyPayment;
IBOutlet UILabel *totalInterest;
IBOutlet UILabel *totalPayment;
}

@property (nonatomic,retain) UITextField *tbxLoanAmount;
@property (nonatomic,retain) UITextField *annualInterestRate;
@property (nonatomic,retain) UITextField *noOfYears;
@property (nonatomic,retain) UILabel *monthlyPayment;
@property (nonatomic,retain) UILabel *totalInterest;
@property (nonatomic,retain) UILabel *totalPayment;


-(IBAction) bgTouched:(id) sender;
-(IBAction) btnCalculate:(id) sender;

@end



Explanation of the codes. 

#import 

Import the UIKit framework. There are many other frameworks you can import like the Accelerometer, the MapKit and many others which we will go through in future tutorials.

@interface EasyLoanCalculator3ViewController : UIViewController {

Declare an interface EasyLoanCalculator3ViewController that inherits from UIViewController.





IBOutlet UITextField *tbxLoanAmount;
IBOutlet UITextField *annualInterestRate;
IBOutlet UITextField *noOfYears;
IBOutlet UILabel *monthlyPayment;
IBOutlet UILabel *totalInterest;
IBOutlet UILabel *totalPayment;
}


Declare the UIControls that you are to use in the xib file. These are what we have dragged and dropped previously. These are also called Outlets. Outlets are declarations of UIControls where we take in or out put data from/to user. Btw, you need to declare these variables with a * which means that there are object references. Don't understand? Just do it first. Will slowing understand later.

@property (nonatomic,retain) UITextField *tbxLoanAmount;
@property (nonatomic,retain) UITextField *annualInterestRate;
@property (nonatomic,retain) UITextField *noOfYears;
@property (nonatomic,retain) UILabel *monthlyPayment;
@property (nonatomic,retain) UILabel *totalInterest;
@property (nonatomic,retain) UILabel *totalPayment;

Set these UIControls as properties. Nonatomic refers to that there can be multiple threads running at the same time. 

-(IBAction) bgTouched:(id) sender;
-(IBAction) btnCalculate:(id) sender;

These are Actions. Typically, we use buttons to activate actions. We have to code these actions later on in the .m file. Here we have two actions. Just concentrate on btnCalculate for now. It is used for the calculation of the loan formula later on.

@end

I won't even comment on this. Next up, the .m file. Find the code below.





#import "EasyLoanCalculatorViewController.h"

@implementation EasyLoanCalculator3ViewController

@synthesize tbxLoanAmount;
@synthesize annualInterestRate;
@synthesize noOfYears;
@synthesize monthlyPayment;
@synthesize totalInterest;
@synthesize totalPayment;

-(IBAction) bgTouched:(id) sender{
[tbxLoanAmount resignFirstResponder];
[annualInterestRate resignFirstResponder];
[noOfYears resignFirstResponder];
}

-(IBAction) btnCalculate:(id) sender{
double loanAmount = [tbxLoanAmount.text doubleValue];
double intRate = [annualInterestRate.text doubleValue];
double years = [noOfYears.text doubleValue];
double r = intRate/1200; // to optimize to handle different payment periods
double n = years * 12;
double rPower = pow(1+r,n);
double paymentAmt = loanAmount * r * rPower / (rPower - 1);
double totalPaymentd = paymentAmt * n; 
double totalInterestd = totalPaymentd - loanAmount; 
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
[numberFormatter setMaximumFractionDigits:2];
NSNumber *n1 = [NSNumber numberWithDouble:paymentAmt];
NSNumber *n2 = [NSNumber numberWithDouble:totalPaymentd];
NSNumber *n3 = [NSNumber numberWithDouble:totalInterestd];
NSString *paymentAmtString = [numberFormatter stringFromNumber:n1];
monthlyPayment.text = paymentAmtString;
NSString *totalInterestString =[numberFormatter stringFromNumber:n3];
totalInterest.text = totalInterestString;
NSString *totalPaymentString =[numberFormatter stringFromNumber:n2];
totalPayment.text = totalPaymentString;
}

- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}


- (void)dealloc {
[tbxLoanAmount release];
[annualInterestRate release];
[noOfYears release];
[monthlyPayment release];
[totalInterest release];
[totalPayment release];
    [super dealloc];
}

@end


Explanation






#import "EasyLoanCalculatorViewController.h"

Import the header file which we have just coded.

@implementation EasyLoanCalculatorViewController

@synthesize tbxLoanAmount;
@synthesize annualInterestRate;
@synthesize noOfYears;
@synthesize monthlyPayment;
@synthesize totalInterest;
@synthesize totalPayment;

The synthesize keyword just means generating the getter and setter methods for each of the UIControls which we have declared in the .h file.

-(IBAction) bgTouched:(id) sender{
[tbxLoanAmount resignFirstResponder];
[annualInterestRate resignFirstResponder];
[noOfYears resignFirstResponder];
}

This is the first Action we have declared earlier in the .h file. Ignore this for now.

-(IBAction) btnCalculate:(id) sender{

Start to implement the btnCalculate Action. Its essentially a method. We name the method btnCalculate that takes an argument of id type and call it sender.
double loanAmount = [tbxLoanAmount.text doubleValue];
double intRate = [annualInterestRate.text doubleValue];
double years = [noOfYears.text doubleValue];

Declare some double variables, and assign the value of the text property of the Textbox. i.e. what the user typed in. Before assigning it, change it to a double type. [tbxLoanAmount.text doubleValue] is essentially tbxLoanAmount.text.ConvertToDouble(); 

To generalize, obj.method() in objective c is [obj method];
double r = intRate/1200// to optimize to handle different payment periods
double n = years * 12;
double rPower = pow(1+r,n);
double paymentAmt = loanAmount * r * rPower / (rPower - 1);
double totalPaymentd = paymentAmt * n; 
double totalInterestd = totalPaymentd - loanAmount; 

Above should be reasonably understood unless you have never coded before. Perhaps what is more difficult to understand who be the formula itself. But you worry about it, you can change the formula to what you want, its just a financial formula which can be readily changed to anything formula you want.
NSNumberFormatter *numberFormatter = [[NSNumberFormatter allocinit];
[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
[numberFormatter setMaximumFractionDigits:2];

NSNumber *n1 = [NSNumber numberWithDouble:paymentAmt];
NSNumber *n2 = [NSNumber numberWithDouble:totalPaymentd];
NSNumber *n3 = [NSNumber numberWithDouble:totalInterestd];

NSString *paymentAmtString = [numberFormatter stringFromNumber:n1];
monthlyPayment.text = paymentAmtString;
NSString *totalInterestString =[numberFormatter stringFromNumber:n3];
totalInterest.text = totalInterestString;
NSString *totalPaymentString =[numberFormatter stringFromNumber:n2];
totalPayment.text = totalPaymentString;
Will discuss the above in depth in a separate article. Essentially, its creating the Formatter object to format a double to 2 decimal places. And converting the double values into a string to assign them to the labels.text property. So, out the calculated results to the labels - monthly payment, total interest and total payment.

}

- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}

Certain events that the program throws. But we do not have to handle them for the moment.


- (void)dealloc {
[tbxLoanAmount release];
[annualInterestRate release];
[noOfYears release];
[monthlyPayment release];
[totalInterest release];
[totalPayment release];
    [super dealloc];
}

Called when the program exits, release all my objects used for the UIControls.

@end

Await Part 3 where we will link the Outlets to the UIControls and buttons to the Actions.
And of course, build and run the app.

3 comments:

  1. Hi Jason
    I love your tutorial but I was wondering if you could help me develop this further. I want to add a deposit type field and display the results on a flip side. How do I do this?

    ReplyDelete
  2. I also want to add a picker, so that the user can pick a date and the calculator will say, repayment on...date

    Please let me know if you can help. Thank you

    ReplyDelete
  3. Your website is really cool and this is a great inspiring article. This Website

    ReplyDelete