0

I need help using NSTextField and its inputs/outputs.

In a functioning code I have three different NSTextFields (in Cocoa + Obj-C) I know how calculate result from more integer inputs...

--- AppController.h ---
@interface AppController : NSObject {
   IBOutlet NSTextField *firsTextField;    // 1st Outlet
   IBOutlet NSTextField *secondTextField;  // 2nd Outlet
   IBOutlet NSTextField *resultTextField;  // 3rd Outlet
}
- (IBAction)result:(id)sender;
@end

--- AppController.m ---
@Implementation AppController
- (IBAction)result:(id)sender {
   double first = [firstTextField doubleValue];   // set value 1st outlet
   double second = [secondTextField doubleValue]; // set value 2nd outlet
   double result = first + second;                // count result
   [resultTextField setDoubleValue:result];       // set value 3rd outlet
}
@end

But while I try do the same thing in only one NSTextField, I don't know how to do it... My idea is, that process should be following:

  1. Set 1st integer (input)
  2. *Choose math function "/, , -, +" (method/action)
  3. Set 2nd integer (input)
  4. Result (method/action) for calculating above mentioned inputs based on math function

But it is actually all what I am able to explain... problem is that I don't know how I can store 1st input value (before choosing math function) and how to count up result between 1st and 2nd input value.

Thank you in advance for every tip / link / reference / tutorial / etc.

Hancz
  • 65
  • 9

2 Answers2

1

As long as you have only one cycle, it is pretty easy. (BTW: The human math syntax (infix notation) is a little bit weird for computer programming, priority rules and brackets are needed, so some invented another algebraic syntax, the PN or reverse PN.)

When a operator is pressed, you store the operator and the first operand into a ivar. This is a state you enter and usually in GUI programming you try to prevent states. However it is, what users expect from a calculator.

First let us beautify your code with properties and generated ivars.

@interface AppController : NSObject
@property (weak, nonatomic)  IBOutlet NSTextField *operandTextField;
@property (weak, nonatomic)  IBOutlet NSTextField *resultTextField;
@end

Add properties for the first value and the operation:

@interface AppController : NSObject
@property (weak, nonatomic)  IBOutlet NSTextField *operandTextField;
@property (weak, nonatomic)  IBOutlet NSTextField *resultTextField;

@property (nonatomic) double operand;
@property (nonatomic) NSString *operator;
@end

Then you need the actions for the operations. Here is an example for one:

@interface AppController : NSObject
@property (weak, nonatomic)  IBOutlet NSTextField *operandTextField;
@property (weak, nonatomic)  IBOutlet NSTextField *resultTextField;

@property (nonatomic) double operand;
@property (nonatomic) NSString *operator;

- (IBAction)plus:(id)sender;
@end

The next thing you need is to add an action for "operation begin". You can connect it to the text field and make it its "enter" action.

@interface AppController : NSObject
@property (weak, nonatomic)  IBOutlet NSTextField *operandTextField;
@property (weak, nonatomic)  IBOutlet NSTextField *resultTextField;

@property (nonatomic) double operand;
@property (nonatomic) NSString *operator;

- (IBAction)plus:(id)sender;
- (IBAction)operate:(id)sender;
@end

Okay, done with the interface. Let's go to the implementation:

@implementation AppController
- (IBAction)plus:(id)sender
{
  // Store operator
  self.operator = [valueTextField doubleValue]; // Some checking?

  // Store operation
  self.operation = @"+"; // You can use int constant for that, but this is the easy way
}

- (IBAction)operate:(id)sender
{
  // Check, whether a operation is already selected
  if ([self.operation length]==0)
  {
     // No: Do nothing
     return;
  }     

  // Get the second operand
  double operand = [valueTextField doubleValue];

  // Do the calculation
  double result;
  if  ([self.operation isEqualToString:@"+"])
  {
   result = self.operand + operand;
  }
  else if ([self.operation isEqualToString:@"-"])
  {
    result = self.operand - operand;
  }
  …

  [self.resultTextField setDoubleValue:result];
  self.operation = @""; 
  // If you do not set this, the next operand will start a new calculation with the first 
  // operand. Another feature would be to store the result we got and repeatedly perform
  // the operation on the last result. But I would change the UI in that case.
}
@end

Typed in Safari.

Amin Negm-Awad
  • 16,582
  • 3
  • 35
  • 50
0

after what I studying your code ... I'm finally got functional code ;-)

at first... here is how looks app: enter image description here

and here is the code:

---------- CalcController.h -----------
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>

@interface CalcController : NSObject {
    IBOutlet NSTextField *textField;
}

@property (weak) IBOutlet NSTextField *operandTextField;
@property (weak) IBOutlet NSTextField *resultTextField;

@property (nonatomic) double value1;
@property (nonatomic) double value2;
@property (nonatomic) double result;
@property (nonatomic) NSString *operator;

- (IBAction)plus:(id)sender;
- (IBAction)result:(id)sender;

@end


---------- CalcController.m -----------
#import "CalcController.h"

@implementation CalcController

@synthesize operandTextField;
@synthesize resultTextField;

@synthesize value1;
@synthesize value2;
@synthesize result;
@synthesize operator;

- (IBAction)plus:(id)sender {
    value1 = [textField doubleValue];
    NSLog(@"operand1 = %lf", value1);   // for test and see value in console
    [textField setStringValue:@""];     // for clear text after 1st input done
    operator = @"+";
}

- (IBAction)result:(id)sender {

    value2 = [textField doubleValue];
    NSLog(@"operand2 = %lf", value2);   // for test and see value in console
    
    if ([operator isEqualToString:@"+"]) {
        result = value1 + value2;
        NSLog(@"value1: %lf + value2: %lf = result: %lf", value1, value2, result); // for tests and see values in console
    }
    
    [resultTextField setDoubleValue:result];
    operator = @"";
}

@end

I Think that working good .... now it is time to add next functions, buttons with numbers etc...

Thanks for showing the right way to do this!

Community
  • 1
  • 1
Hancz
  • 65
  • 9
  • This property `@property (weak) IBOutlet NSTextField *operandTextField;` and this synthesize `@synthesize operandTextField;` are not relevant and could be removed .... is it right? Or I need it for something? – Hancz May 03 '15 at 04:14