Travis
Travis

Reputation: 21

ios 7 calculator app with decimal point

OK Here is my Code

It now limits user input to two characters after the decimal and checks for a decimal but now it wont let me add or subtract anymore.... /sigh

//
//  CalculatorViewController.h
//  
//


#import "ViewController.h"

int Method;
long int SelectNumber;
float RunningTotal;


@interface CalculatorViewController : ViewController <UITextFieldDelegate>

@property (strong, nonatomic) IBOutlet UILabel *screen;

- (IBAction)backToMainViewFromCalculatorViewButton:(id)sender;


@end

and my .m

//
//  CalculatorViewController.m
//  
//


#import "CalculatorViewController.h"
BOOL isDecimal;
float resultNumber;
float displayNumber;
int operation;

NSUInteger decimalPlacesLimit = 2;


@interface CalculatorViewController ()

@end

@implementation CalculatorViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

//    self.screen.text = @"";
    isDecimal = false;
    resultNumber = 0;
    self.screen.adjustsFontSizeToFitWidth = TRUE;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

- (IBAction)backToMainViewFromCalculatorViewButton:(id)sender {

    // Dismiss the VIEW
    // DO NOT SEGUE back
    // DO THIS
    //Going back using segue just stacks views and then soon you run out of memory and APP crashes
    [self dismissViewControllerAnimated:YES completion:NULL];
}

-(void)setResultWithNumber:(int)theNumber{

    if(!isDecimal){
        displayNumber *= 10;
        displayNumber += theNumber;
        self.screen.text = [NSString stringWithFormat:@"%.0f", displayNumber];
    }
    else
    {
        self.screen.text = [self.screen.text stringByAppendingString:[NSString stringWithFormat:@"%d", theNumber]];
    }
    displayNumber = [self.screen.text floatValue];
}

-(void)operationWithNumber:(int)theNumber{

    isDecimal = false;

    if(resultNumber == 0){
        resultNumber = displayNumber;
    }
    else{
        self.screen.text = [NSString stringWithFormat:@"%.2f",resultNumber];
        switch (operation) {
            case 1:
                resultNumber += displayNumber;
                break;
            case 2:
                resultNumber -= displayNumber;
                break;
            case 3:
                resultNumber = displayNumber*resultNumber;
                break;
            case 4:
                resultNumber /= displayNumber;
                break;

            default:
                break;
        }
    }
    operation = theNumber;
    displayNumber = 0;

}
- (IBAction)AC:(id)sender {
    operation = 0;
    resultNumber = 0;
    displayNumber = 0;
    isDecimal = false;
    self.screen.text = [NSString stringWithFormat:@"%i",0];

}
/*
- (IBAction)plus_minus:(id)sender {

    displayNumber = 0 - displayNumber;
    if(isDecimal)
        result.text = [NSString stringWithFormat:@"%.2f", displayNumber];
    else
        result.text = [NSString stringWithFormat:@"%.0f", displayNumber];

}

- (IBAction)divide:(id)sender {
    if(resultNumber != 0){
        [self operationWithNumber:operation];
        result.text = [NSString stringWithFormat:@"%.2f",resultNumber];
        displayNumber = [result.text floatValue];
        resultNumber = 0;
    }
    [self operationWithNumber:4];


}
 */
- (IBAction)seven:(id)sender
{
       NSRange range = [self.screen.text rangeOfString:@"."];

    // Search for a Period
    // If not found append one to the text
    if (range.location == NSNotFound)
    {
        [self setResultWithNumber:7];
        isDecimal = false;
    }
    else
    {
        // If we allready ahve a character move on to test for .
        NSArray *explodedString = [self.screen.text componentsSeparatedByString:@"."];
        NSString *decimalPart = explodedString[1];

        if (decimalPart.length >= decimalPlacesLimit && ![self.screen.text isEqualToString:@""])
        {
            NSLog(@"textField already contains %lu decimal places", (unsigned long)decimalPlacesLimit);
            isDecimal = true;

        }
        else
        {
            isDecimal = false;
            [self setResultWithNumber:7];
        }
    }
}
- (IBAction)eight:(id)sender
{

    NSRange range = [self.screen.text rangeOfString:@"."];

    // Search for a Period
    // If not found append one to the text
    if (range.location == NSNotFound)
    {
        [self setResultWithNumber:8];
    }
    else
    {
        // If we allready ahve a character move on to test for .
        NSArray *explodedString = [self.screen.text componentsSeparatedByString:@"."];
        NSString *decimalPart = explodedString[1];

        if (decimalPart.length >= decimalPlacesLimit && ![self.screen.text isEqualToString:@""])
        {
            NSLog(@"textField already contains %lu decimal places", (unsigned long)decimalPlacesLimit);
             isDecimal = true;
        }
        else
        {
            [self setResultWithNumber:8];
        }
    }
}
- (IBAction)nine:(id)sender
{

    NSRange range = [self.screen.text rangeOfString:@"."];

    // Search for a Period
    // If not found append one to the text
    if (range.location == NSNotFound)
    {
        [self setResultWithNumber:9];
    }
    else
    {
        // If we allready ahve a character move on to test for .
        NSArray *explodedString = [self.screen.text componentsSeparatedByString:@"."];
        NSString *decimalPart = explodedString[1];

        if (decimalPart.length >= decimalPlacesLimit && ![self.screen.text isEqualToString:@""])
        {
            NSLog(@"textField already contains %lu decimal places", (unsigned long)decimalPlacesLimit);
              isDecimal = true;
        }
        else
        {
            [self setResultWithNumber:9];
        }
    }
}
/*
- (IBAction)multiply:(id)sender {
    if(resultNumber != 0){
        [self operationWithNumber:operation];
        result.text = [NSString stringWithFormat:@"%.2f",resultNumber];
        displayNumber = [result.text floatValue];
        resultNumber = 0;
    }
    [self operationWithNumber:3];
}
 */
- (IBAction)six:(id)sender
{
       NSRange range = [self.screen.text rangeOfString:@"."];

    // Search for a Period
    // If not found append one to the text
    if (range.location == NSNotFound)
    {
        [self setResultWithNumber:6];
    }
    else
    {
        // If we allready ahve a character move on to test for .
        NSArray *explodedString = [self.screen.text componentsSeparatedByString:@"."];
        NSString *decimalPart = explodedString[1];

        if (decimalPart.length >= decimalPlacesLimit && ![self.screen.text isEqualToString:@""])
        {
            NSLog(@"textField already contains %lu decimal places", (unsigned long)decimalPlacesLimit);
            isDecimal = true;
        }
        else
        {
            [self setResultWithNumber:6];
        }
    }
}
- (IBAction)five:(id)sender
{

    NSRange range = [self.screen.text rangeOfString:@"."];

    // Search for a Period
    // If not found append one to the text
    if (range.location == NSNotFound)
    {
        [self setResultWithNumber:5];
    }
    else
    {
        // If we allready ahve a character move on to test for .
        NSArray *explodedString = [self.screen.text componentsSeparatedByString:@"."];
        NSString *decimalPart = explodedString[1];

        if (decimalPart.length >= decimalPlacesLimit && ![self.screen.text isEqualToString:@""])
        {
            NSLog(@"textField already contains %lu decimal places", (unsigned long)decimalPlacesLimit);
              isDecimal = true;
        }
        else
        {
            [self setResultWithNumber:5];
        }
    }
}
- (IBAction)four:(id)sender
{

    NSRange range = [self.screen.text rangeOfString:@"."];

    // Search for a Period
    // If not found append one to the text
    if (range.location == NSNotFound)
    {
        [self setResultWithNumber:4];
    }
    else
    {
        // If we allready ahve a character move on to test for .
        NSArray *explodedString = [self.screen.text componentsSeparatedByString:@"."];
        NSString *decimalPart = explodedString[1];

        if (decimalPart.length >= decimalPlacesLimit && ![self.screen.text isEqualToString:@""])
        {
            NSLog(@"textField already contains %lu decimal places", (unsigned long)decimalPlacesLimit);
              isDecimal = true;
        }
        else
        {
            [self setResultWithNumber:4];
        }
    }
}
- (IBAction)substract:(id)sender {
    if(resultNumber != 0){
        [self operationWithNumber:operation];
        self.screen.text = [NSString stringWithFormat:@"%.2f",resultNumber];
        displayNumber = [self.screen.text floatValue];
        resultNumber = 0;
    }
    [self operationWithNumber:2];

}
- (IBAction)three:(id)sender
{

    NSRange range = [self.screen.text rangeOfString:@"."];

    // Search for a Period
    // If not found append one to the text
    if (range.location == NSNotFound)
    {
        [self setResultWithNumber:3];
    }
    else
    {
        // If we allready ahve a character move on to test for .
        NSArray *explodedString = [self.screen.text componentsSeparatedByString:@"."];
        NSString *decimalPart = explodedString[1];

        if (decimalPart.length >= decimalPlacesLimit && ![self.screen.text isEqualToString:@""])
        {
            NSLog(@"textField already contains %lu decimal places", (unsigned long)decimalPlacesLimit);
              isDecimal = true;
        }
        else
        {
            [self setResultWithNumber:3];
        }
    }
}

- (IBAction)two:(id)sender
{

    NSRange range = [self.screen.text rangeOfString:@"."];

    // Search for a Period
    // If not found append one to the text
    if (range.location == NSNotFound)
    {
        [self setResultWithNumber:2];
    }
    else
    {
        // If we allready ahve a character move on to test for .
        NSArray *explodedString = [self.screen.text componentsSeparatedByString:@"."];
        NSString *decimalPart = explodedString[1];

        if (decimalPart.length >= decimalPlacesLimit && ![self.screen.text isEqualToString:@""])
        {
            NSLog(@"textField already contains %lu decimal places", (unsigned long)decimalPlacesLimit);
             isDecimal = true;
        }
        else
        {
            [self setResultWithNumber:2];
        }
    }
}
- (IBAction)one:(id)sender
{

    NSRange range = [self.screen.text rangeOfString:@"."];

    // Search for a Period
    if (range.location == NSNotFound)
    {
        // No period found
        isDecimal = false;
        // set the number
        [self setResultWithNumber:1];
    }
    else
    {
        // If we allready have a character move on to test for .
        NSArray *explodedString = [self.screen.text componentsSeparatedByString:@"."];
        NSString *decimalPart = explodedString[1];

        if (decimalPart.length >= decimalPlacesLimit && ![self.screen.text isEqualToString:@""])
        {
            NSLog(@"textField already contains %lu decimal places", (unsigned long)decimalPlacesLimit);
             isDecimal = true;
        }
        else
        {
            [self setResultWithNumber:1];
        }
    }}


- (IBAction)add:(id)sender {
    if(resultNumber != 0)
    {
        [self operationWithNumber:operation];
        self.screen.text = [NSString stringWithFormat:@"%.2f",resultNumber];
        displayNumber = [self.screen.text floatValue];
        resultNumber = 0;
    }
[self operationWithNumber:1];
}

- (IBAction)zero:(id)sender
{

    NSRange range = [self.screen.text rangeOfString:@"."];

    // Search for a Period
    // If not found append one to the text
    if (range.location == NSNotFound)
    {
       [self setResultWithNumber:0];
    }
    else
    {
     // If we allready ahve a character move on to test for .
     NSArray *explodedString = [self.screen.text componentsSeparatedByString:@"."];
     NSString *decimalPart = explodedString[1];

        if (decimalPart.length >= decimalPlacesLimit && ![self.screen.text isEqualToString:@""])
        {
            NSLog(@"textField already contains %lu decimal places", (unsigned long)decimalPlacesLimit);
             isDecimal = true;
        }
        else
        {
            [self setResultWithNumber:0];
        }
    }
}


- (IBAction)dot:(id)sender {

    isDecimal = true;
    NSRange range = [self.screen.text rangeOfString:@"."];

    // Search for a Period
    // If not found append one to the text
    if (range.location == NSNotFound)
    {
        self.screen.text = [self.screen.text stringByAppendingString:@"."];
    }
    // We must have a period so now lets test for how many places after the decimal
    // and limit it to two



 //   NSLog(@"text on the way: %@", string);


    /*
    NSUInteger decimalPlacesLimit = 2;

    NSRange rangeDot = [self.screen.text rangeOfString:@"." options:NSCaseInsensitiveSearch];
    NSRange rangeComma = [self.screen.text rangeOfString:@"," options:NSCaseInsensitiveSearch];
    if (rangeDot.length > 0 || rangeComma.length > 0)
    {
        if([self.screen.text isEqualToString:@"."])
        {
            NSLog(@"textField already contains a separator");
        }
        else
        {
            NSArray *explodedString = [self.screen.text componentsSeparatedByString:@"."];
            NSString *decimalPart = explodedString[1];

            if (decimalPart.length >= decimalPlacesLimit && ![self.screen.text isEqualToString:@""])
            {
                NSLog(@"textField already contains %lu decimal places", (unsigned long)decimalPlacesLimit);
            }
        }
    }
     */
}




- (IBAction)equals:(id)sender {
    [self operationWithNumber:operation];
    self.screen.text = [NSString stringWithFormat:@"%.2f",resultNumber];
    displayNumber = [self.screen.text floatValue];
    resultNumber = 0;

}



- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSLog(@"text on the way: %@", string);
    NSUInteger decimalPlacesLimit = 2;

    NSRange rangeDot = [textField.text rangeOfString:@"." options:NSCaseInsensitiveSearch];
    NSRange rangeComma = [textField.text rangeOfString:@"," options:NSCaseInsensitiveSearch];
    if (rangeDot.length > 0 || rangeComma.length > 0){
        if([string isEqualToString:@"."]) {
            NSLog(@"textField already contains a separator");
            return NO;
        } else {
            NSArray *explodedString = [textField.text componentsSeparatedByString:@"."];
            NSString *decimalPart = explodedString[1];
            if (decimalPart.length >= decimalPlacesLimit && ![string isEqualToString:@""]) {
                NSLog(@"textField already contains %lu decimal places", (unsigned long)decimalPlacesLimit);
                return NO;
            }
        }
    }

    return YES;
}

@end

I cant figure out how to make sure I check for a decimal and then limit entries to no more then two places after the decimal and still be able to calculate

Any help would be appreciated

Travis

Upvotes: 1

Views: 265

Answers (3)

Eric Qian
Eric Qian

Reputation: 2256

I build a calculator application before. What I did was:
Use tag to identify different buttons, 0 is for button 0, 1 is for button 1 ... and 99 is for button dot. All these button triggered the same IBAction function, and in this function just check whether the button user pressed could be added to the Label (You can just use UILabel instead of UITextField here) by applying the rules you created above. Try this code:

// Assume that, the number buttons have tags from 0 - 9 respectively, and dot button has tag 99
- (IBAction)onButtonPressed:(UIButton *)sender
{
    NSRange range = [self.screen.text rangeOfString:@"."];

    BOOL canUpdateScreen = YES;
    if(range.location != NSNotFound) {
        if(sender.tag == 99) {
            // Already got dot, cannot show another dot
            canUpdateScreen = NO;
        } else {
            NSArray *explodedString = [self.screen.text componentsSeparatedByString:@"."];
            if(explodedString[1].length >= decimalPlacesLimit) {
                canUpdateScreen = NO;
            }
        }
    }

    if(canUpdateScreen) {
        if(sender.tag == 99) {
            self.screen.text = [NSString stringWithFormat:@"%@%@", self.screen.text, @"."];
        } else {
            self.screen.text = [NSString stringWithFormat:@"%@%d", self.screen.text, sender.tag];
        }
    }
}

Upvotes: 1

user4226071
user4226071

Reputation:

Issue,

The code you have posted is, UITextFieldDelegate method implementation. It will not be triggered, if you update the UITextField text through code.

Solution

You can use any of the below solution.

To simplify the tasks, you can use, tag 0 to 9 for buttons 0 to 9 and some other value for “.” and "," as mentioned in another answer.

// 1. Call the method (in your code) on tapping the buttons (0 - 9 and “.”) and conditionally update the UITextField.text (yourTextField.text), like

    update = [self textField:yourTextField shouldChangeCharactersInRange:NSMakeRange(yourTextField.text.length, 1) replacementString:yourButtonLabel];

    if (update)
    {
        // Uodate yourTextField
    }
    else
    {
        // Don’t update yourTextField
    }

// 2. Before updating yourTextField.text, check there is any decimal point or comma already in yourTextField, using

    if([yourTextField.text rangeOfString:@"."].location != NSNotFound) // Update condition to check comma if the tapped button is so
    {
        // Don’t update yourTextField
    }
    else
    {
        // Update yourTextField
    }

Upvotes: 0

Logic
Logic

Reputation: 705

Here

-(IBAction)NUmber1:(id)sender{

    SelectNumber = SelectNumber * 10;
    SelectNumber = SelectNumber + 1;
    Screen.text = [NSString stringWithFormat:@"%i", SelectNumber];
}
you are erasing your current string with new INTEGER value. Try to change to

-(IBAction)NUmber1:(id)sender{
    Screen.text = [Screen.text stringByAppendingString:@"1"];
}

Also you need to change your SelectNumber calculation logic. I suggest you to get it from string when you really need it

double SelectNumber = [Screen.text doubleValue];

Upvotes: 1

Related Questions