How to put a decimal point according to the will of the user in a calculator in iphone? - iphone

I have a calculator in which i would like to put the decimal point according to the button press for the decimal point. I get the decimal point but if I enter another digit the decimal pint vanishes and is overwritten .
The code is mentioned below for the decimal press:-
-(IBAction)decimalPressed:(id)sender{
calculatorScreen.text = [calculatorScreen.text stringByAppendingString:#"."];
}
For the digit press it is :-
-(IBAction)buttonDigitPressed:(id)sender{
currentNumber = currentNumber*10 + (float)[sender tag];
calculatorScreen.text = [NSString stringWithFormat:#"%g",currentNumber];
}
How can i do something like 23 then "." then 45. The result would be 23.45

I've recently done a calculator app and could understand your problem. Another thing you want to take note about the point is that you do not want to have multiple point in your calculation, e.g. 10.345.1123.5. Simply put, you want it to be a legal float number as well.
With that said, you can use a IBAction (remember to link it to your storyboard or xib file)
-(IBAction)decimalPressed:(UIButton *)sender
{
NSRange range = [self.display.text rangeOfString:#"."];
if (range.location ==NSNotFound){
self.display.text = [ self.display.text stringByAppendingString:#"."];
}
self.userIsInTheMiddleOfEnteringANumber = YES;
}
While it might be possible we are doing on the same project, it could also be entirely different (you starting from scratch by yourself) so i will go through some of the codes
you could replace UIButton with the default id, but it is better to static replace it to make clear clarification for yourself, or anyone else who view your code.
NSRange as the name implies, mark the range, and the range will be ur display text of calculation (e.g. 1235.3568), and the range of string it is targeting in this case is "."
therefore, if NSNotfound (rangeOfString "." is not found in the text range) you will append the current display text with "." with the function stringByAppendingString:#".", there is no else, so no function will take place if "." is already found, which solve the problem of multiple point on the display.
userIsInTheMiddleOfEnteringANumber is a BOOL to solve the problem of having 0 in ur display (e.g. 06357), if you have a method to change it, then replace my method name with your own.

Try with below code:
-(IBAction)buttonDigitPressed:(id)sender
{
UIButton *pressedButton = (UIButton *)sender;
calculatorScreen.text = [calculatorScreen.text stringByAppendingFormat:#"%d",pressedButton.tag];
currentNumber = [calculatorScreen.text floatValue];
}

-(IBAction)ButtonDot
{
decimalChecker = 10;
calculatorScreen.text = [NSString stringWithFormat:#"$ %g.", currentSavings];
decimalChecker=1;
}
-(IBAction)buttonDigitPressed:(id)sender
{
if (decimalChecker ==1)
{
currentDecimal = currentDecimal*10 + (float)[sender tag];
calculatorScreen.text = [NSString stringWithFormat:#"$ %g.%g", currentSavings,currentDecimal];
}
else
{
currentSavings = currentSavings*10 + (float)[sender tag];
calculatorScreen.text = [NSString stringWithFormat:#"$ %g",currentSavings];
}
}

This is my solution:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController {
float result;
IBOutlet UILabel *TextInput;
int currentOperation;
float currentNumber;
BOOL userInTheMiddleOfEnteringDecimal;
}
- (IBAction)buttonDigitPressed:(id)sender;
- (IBAction)buttonOperationPressed:(id)sender;
- (IBAction)cancelInput;
- (IBAction)cancelOperation;
- (IBAction)dotPressed;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (IBAction)buttonDigitPressed:(id)sender {
if(!userInTheMiddleOfEnteringDecimal)
{
currentNumber = currentNumber*10 + (float)[sender tag];
TextInput.text = [NSString stringWithFormat:#"%d",(int)currentNumber];
}
else{
TextInput.text= [TextInput.text stringByAppendingString:[NSString stringWithFormat:#"%d",[sender tag]]];
currentNumber = [TextInput.text floatValue];
}
}
- (IBAction)buttonOperationPressed:(id)sender {
if (currentOperation == 0) result = currentNumber;
else {
switch (currentOperation) {
case 1:
result = result + currentNumber;
break;
case 2:
result = result - currentNumber;
break;
case 3:
result = result * currentNumber;
break;
case 4:
result = result / currentNumber;
break;
case 5:
currentOperation = 0;
break;
default:
break;
}
}
currentNumber = 0;
TextInput.text = [NSString stringWithFormat:#"%.2f",result];
if ([sender tag] == 0) result = 0;
currentOperation = [sender tag];
userInTheMiddleOfEnteringDecimal = NO;
}
-(IBAction)cancelInput{
currentNumber = (int)(currentNumber/10);
TextInput.text = [NSString stringWithFormat:#"%.2f",currentNumber];;
}
-(IBAction)cancelOperation{
currentNumber = 0;
TextInput.text = #"0";
userInTheMiddleOfEnteringDecimal = NO;
}
- (IBAction)dotPressed{
if(!userInTheMiddleOfEnteringDecimal){
userInTheMiddleOfEnteringDecimal = YES;
TextInput.text= [TextInput.text stringByAppendingString:#"."];
}
}
#end
Hope this helps.. Another way of solution...

after pressing the "." all values after will be divided as following
the first number ur press after pressing "." will be divided by 10 the second by 100 and so on
so editing ur function it would be like this
-(IBAction)buttonDigitPressed:(id)sender{
currentNumber = currentNumber + (float)[sender tag] / 10.0;
calculatorScreen.text = [NSString stringWithFormat:#"%g",currentNumber];
}

i think in that solve your problem
http://www.datasprings.com/resources/articles-information/iphone-sdk-getting-started-example-code
There is sample code of calculator.

Related

Adding a method to my uitextfield in cell?

I am adding this Method to my code to format the textfield. I am using the code below to try and add the method, but it not working, what am I doing wrong?
.h file
NSString* phone_;
UITextField* phoneFieldTextField;
#property (nonatomic,copy) NSString* phone;
.m file
#synthesize phone = phone_;
ViewDidLoad{
self.phone = #"";
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
// Make cell unselectable and set font.
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.font = [UIFont fontWithName:#"ArialMT" size:13];
if (indexPath.section == 0) {
UITextField* tf = nil;
switch ( indexPath.row ) {
case 3: {
cell.textLabel.text = #"Phone" ;
tf = phoneFieldTextField = [self makeTextField:self.phone placeholder:#"xxx-xxx-xxxx"];
phoneFieldTextField.keyboardType = UIKeyboardTypePhonePad;
[self formatPhoneNumber:phoneFieldTextField.text deleteLastChar:YES];
[cell addSubview:phoneFieldTextField];
break ;
}
// Textfield dimensions
tf.frame = CGRectMake(120, 12, 170, 30);
// Workaround to dismiss keyboard when Done/Return is tapped
[tf addTarget:self action:#selector(textFieldFinished:) forControlEvents:UIControlEventEditingDidEndOnExit];
}
}
// Textfield value changed, store the new value.
- (void)textFieldDidEndEditing:(UITextField *)textField {
//Section 1.
if ( textField == nameFieldTextField ) {
self.name = textField.text ;
} else if ( textField == addressFieldTextField ) {
self.address = textField.text ;
} else if ( textField == emailFieldTextField ) {
self.email = textField.text ;
} else if ( textField == phoneFieldTextField ) {
self.phone = textField.text ;
}else if ( textField == dateOfBirthTextField ) {
self.dateOfBirth = textField.text ;
}
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString* totalString = [NSString stringWithFormat:#"%#%#",textField.text,string];
// if it's the phone number textfield format it.
if(textField.tag == 10 ) {
if (range.length == 1) {
// Delete button was hit.. so tell the method to delete the last char.
textField.text = [self formatPhoneNumber:totalString deleteLastChar:YES];
} else {
textField.text = [self formatPhoneNumber:totalString deleteLastChar:NO ];
}
return false;
}
return YES;
NSLog(#"Testing should change character in range");
}
-(NSString*) formatPhoneNumber:(NSString*) simpleNumber deleteLastChar:(BOOL)deleteLastChar {
if(simpleNumber.length == 0) return #"";
// use regex to remove non-digits(including spaces) so we are left with just the numbers
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"[\\s-\\(\\)]" options:NSRegularExpressionCaseInsensitive error:&error];
simpleNumber = [regex stringByReplacingMatchesInString:simpleNumber options:0 range:NSMakeRange(0, [simpleNumber length]) withTemplate:#""];
// check if the number is to long
if(simpleNumber.length>10) {
// remove last extra chars.
simpleNumber = [simpleNumber substringToIndex:10];
}
if(deleteLastChar) {
// should we delete the last digit?
simpleNumber = [simpleNumber substringToIndex:[simpleNumber length] - 1];
}
// 123 456 7890
// format the number.. if it's less then 7 digits.. then use this regex.
if(simpleNumber.length<7)
simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:#"(\\d{3})(\\d+)"
withString:#"($1) $2"
options:NSRegularExpressionSearch
range:NSMakeRange(0, [simpleNumber length])];
else // else do this one..
simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:#"(\\d{3})(\\d{3})(\\d+)"
withString:#"($1) $2-$3"
options:NSRegularExpressionSearch
range:NSMakeRange(0, [simpleNumber length])];
if (simpleNumber.length == 10 && deleteLastChar == NO) { [self resignFirstResponder];}
return simpleNumber;
NSLog(#"Testing format phone number");
}
#pragma mark - TextField
-(UITextField*) makeTextField: (NSString*)text
placeholder: (NSString*)placeholder {
UITextField *tf = [[UITextField alloc] init];
tf.placeholder = placeholder;
tf.text = text ;
tf.autocorrectionType = UITextAutocorrectionTypeNo ;
tf.autocapitalizationType = UITextAutocapitalizationTypeNone;
tf.adjustsFontSizeToFitWidth = YES;
tf.returnKeyType = UIReturnKeyDone;
tf.textColor = [UIColor colorWithRed:56.0f/255.0f green:84.0f/255.0f blue:135.0f/255.0f alpha:1.0f];
return tf ;
}
The method you are using:
-(NSString*) formatPhoneNumber:(NSString*) simpleNumber deleteLastChar:(BOOL)deleteLastChar
Returns an NSString Object. In your case you are calling the method correctly but you are not setting the Returned NSString object to anything. It is simply hanging there. You need to set the phoneFieldTextField to the formatted text like so:
phoneFieldTextField.text = [self formatPhoneNumber:phoneFieldTextField.text deleteLastChar:YES];
NOTE - If you want to learn more about return methods then read the following:
If you noticed some most methods are of the void type. You know this when you see a method like this:
- (void)someMethod {
int x = 10;
}
What void means is that the someMethod does not return anything to you. It simply executes the code within the method. Now methods than return an object or some other data type look like this:
- (int)returnSomething {
int x = 10;
return x;
}
First thing you will notice is the return type is no longer void, it is an int. This means the method will return an integer type. In this case the code executes and you are returned the value of x.
This is just the start of the topic of return methods but hopefully it makes things a bit clearer for you.
First off you need to tell us What is not working we don't have your app and all your code. You need to explain what is working and what is not working exactly. It took longer then necessary to figure out that your question is why is textField:shouldChangeCharactersInRange: not working. Did you set a breakpoint in the function to see what it was doing. Was it not being called?
That said your bug is that textField:shouldChangeCharactersInRange: is using tags to identify text fields but the rest of the code is using pointers
// if it's the phone number textfield format it.
- if(textField.tag == 10 ) {
+ if(textField.tag == phoneFieldTextField ) {
Also you didn't include the code for makeTextField:placeholder: There could be issues in it too. Compare your code to the makeTextField:placeholder: in my sample.
I created a sample project on GitHub. To fix this. I also demos a better approach to creating input forms using table views.
https://github.com/GayleDDS/TestTableViewTextField.git
Look at both diffs to see what I did to YourTableViewController.m to make things work.
https://github.com/GayleDDS/TestTableViewTextField/commit/d65a288cb4da7e1e5b05790ea23d72d472564793
https://github.com/GayleDDS/TestTableViewTextField/commit/31ecaec8c9c01204643d72d6c3ca5a4c58982099
There is a bunch of other Issues here:
You need to call [super viewDidLoad]; in your viewDidLoad method
You need to correctly indent your code (could be a cut and paste issue)
You should be using the storyboard to create your views. See the better solution tab and BetterTableViewController implementation.
Must Watch - iOS Development Videos
WWDC 2011 - Session 309 - Introducing Interface Builder Storyboarding
https://developer.apple.com/videos/wwdc/2011/?id=309
Stanford iPhone Programing Class (Winter 2013)
Coding Together: Developing Apps for iPhone and iPad
https://itunes.apple.com/us/course/coding-together-developing/id593208016
Lecture 9. Scroll View and Table View
Lecture 16. Segues and Text Fields
Looks like you are not setting the delegate <UITextFieldDelegate> in the .h file, and not assigning your textfield's delegate property to self tf.delegate = self; in order to call - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
Try that and let me know how it goes
-Good Luck!
#koray was right: you need to setup the delegate for the class. Your class should be declared as implementing the protocol UITextFieldDelegate (in addition to UITableViewDataSource, I assume)
then in your makeTextField: (NSString*)text placeholder: (NSString*)placeholder method, you need to have something like:
-(UITextField*) makeTextField: (NSString*)text
placeholder: (NSString*)placeholder {
UITextField *tf = [[UITextField alloc] initWithFrame:CGRectMake(40, 0, 150, 40)];
tf.placeholder = placeholder;
// (...)
tf.delegate = self;
return tf ;
}
Then you need to setup the delegate methods correctly. In the following example, I have a nav bar, since the numbers pad doesn't have a return or a done button. I setup a button that will act as the done button (you may have another way of making the keyboard go, and switching between text fields will trigger the end of edition anyway):
- (void) textFieldDidBeginEditing:(UITextField *)textField {
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(doneEditing:)];
self.navBar.topItem.rightBarButtonItem = doneBtn;
}
- (void) doneEditing:(id) sender {
if(phoneFieldTextField.isFirstResponder) {
[phoneFieldTextField resignFirstResponder];
}
// (...)
self.navBar.topItem.rightBarButtonItem = nil;
}
Then, the magic happens in the textDidEndEditing delegate method:
- (void)textFieldDidEndEditing:(UITextField *)textField {
if ( textField == phoneFieldTextField ) {
self.phone = [self formatPhoneNumber:textField.text deleteLastChar:YES] ; // convert
[phoneFieldTextField setText:self.phone]; // display
}
// (...)
}

How we can perform Action on Sequence UIButtons?

As My Screen shot show that i am working on word matching game.In this game i assign my words to different UIButtons in Specific sequence on different loctions(my red arrow shows this sequence)and of rest UIButtons i assign a one of random character(A-Z).when i Click on any UIButtons its title will be assign to UILabel which is in Fornt of Current Section:i campare this UILabel text to below UILabels text which is in fornt of timer.when it match to any of my UILabels its will be deleted.i implement all this process already.
But my problem is that which is show by black lines.if the player find the first word which is "DOG". he click the Two UIButtons in Sequence,but not press the Third one in Sequence.(as show by black line).so here i want that when player press the any UIButtons which is not in Sequence then remove the previous text(which is "DO") of UILabel and now the Text of UILabel is only "G" .
Here is my code to get the UIButtons titles and assign it UILabel.
- (void)aMethod:(id)sender
{
UIButton *button = (UIButton *)sender;
NSString *get = (NSString *)[[button titleLabel] text];
NSString *origText = mainlabel.text;
mainlabel.text = [origText stringByAppendingString:get];
if ([mainlabel.text length ]== 3)
{
if([mainlabel.text isEqualToString: a]){
lbl.text=#"Right";
[btn1 removeFromSuperview];
score=score+10;
lblscore.text=[NSString stringWithFormat:#"%d",score];
words=words-1;
lblwords.text=[NSString stringWithFormat:#"%d",words];
mainlabel.text=#"";
a=#"tbbb";
}
else if([mainlabel.text isEqualToString: c]){
lbl.text=#"Right";
[btn2 removeFromSuperview];
score=score+10;
lblscore.text=[NSString stringWithFormat:#"%d",score];
words=words-1;
lblwords.text=[NSString stringWithFormat:#"%d",words];
mainlabel.text=#"";
c=#"yyyy";
}
else
if([mainlabel.text isEqualToString: d]){
lbl.text=#"Right";
[btn3 removeFromSuperview];
score=score+10;
lblscore.text=[NSString stringWithFormat:#"%d",score];
words=words-1;
lblwords.text=[NSString stringWithFormat:#"%d",words];
mainlabel.text=#"";
d=#"yyyy";
}
else {
lbl.text=#"Wrong";
mainlabel.text=#"";
}
}}
Thanx in advance
Assign tag to each button from left to right.
So you will have,
GButton.tag = 0;
TButton.tag = 1;
DButton.tag = 2;
.
.
.
VButton.tag = 9;
.
.
.
EButton.tag = 18;
.
.
.
CButton.tag = 26;
Now keep the track of previous pressed button and current pressed button.
Call below function when your button delegate hits:
Write below code into your .h file
#define SEQ_TYPE_ANY 0
#define SEQ_TYPE_RIGHT 1
#define SEQ_TYPE_LEFT 2
#define SEQ_TYPE_TOP 3
#define SEQ_TYPE_BOTTOM 4
#define SEQ_TYPE_RIGHT_DIAGONAL_DOWN 5
#define SEQ_TYPE_RIGHT_DIAGONAL_UP 6
#define SEQ_TYPE_LEFT_DIAGONAL_DOWN 7
#define SEQ_TYPE_LEFT_DIAGONAL_UP 8
#define NO_OF_BUTTONS_IN_ROW 9
//Add below variables into your class
int curentSequence;
UILabel *resultLabel;
UIButton *previousButton;
//Declare property for previousButton
#property(nonatomic, retain) UIButton *previousButton;
//Write below code to .m file
#synthesize previousButton;
-(BOOL) isAdjacent:(UIButton *)currentButton
{
if(previousButton == nil)
{
resultLabel.text = currentButton.titleLabel.text;
curentSequence = SEQ_TYPE_ANY;
return TRUE;
}
if((curentSequence == SEQ_TYPE_ANY || curentSequence == SEQ_TYPE_RIGHT) &&
(previousButton.tag + 1 == currentButton.tag))
{
resultLabel.text = [resultLabel.text stringByAppendingString:currentButton.titleLabel.text];
curentSequence = SEQ_TYPE_ANY;
return TRUE;
}
else if((curentSequence == SEQ_TYPE_ANY || curentSequence == SEQ_TYPE_LEFT) &&
(previousButton.tag - 1 == currentButton.tag))
{
resultLabel.text = [resultLabel.text stringByAppendingString:currentButton.titleLabel.text];
curentSequence = SEQ_TYPE_LEFT;
return TRUE;
}
else if((curentSequence == SEQ_TYPE_ANY || curentSequence == SEQ_TYPE_TOP) &&
(previousButton.tag - NO_OF_BUTTONS_IN_ROW == currentButton.tag))
{
resultLabel.text = [resultLabel.text stringByAppendingString:currentButton.titleLabel.text];
curentSequence = SEQ_TYPE_TOP;
return TRUE;
}
else if((curentSequence == SEQ_TYPE_ANY || curentSequence == SEQ_TYPE_BOTTOM) &&
(previousButton.tag + NO_OF_BUTTONS_IN_ROW == currentButton.tag))
{
resultLabel.text = [resultLabel.text stringByAppendingString:currentButton.titleLabel.text];
curentSequence = SEQ_TYPE_BOTTOM;
return TRUE;
}
else if((curentSequence == SEQ_TYPE_ANY || curentSequence == SEQ_TYPE_RIGHT_DIAGONAL_DOWN) &&
(previousButton.tag + NO_OF_BUTTONS_IN_ROW + 1 == currentButton.tag))
{
resultLabel.text = [resultLabel.text stringByAppendingString:currentButton.titleLabel.text];
curentSequence = SEQ_TYPE_RIGHT_DIAGONAL_DOWN;
return TRUE;
}
else if((curentSequence == SEQ_TYPE_ANY || curentSequence == SEQ_TYPE_RIGHT_DIAGONAL_UP) &&
(previousButton.tag - NO_OF_BUTTONS_IN_ROW + 1 == currentButton.tag))
{
resultLabel.text = [resultLabel.text stringByAppendingString:currentButton.titleLabel.text];
curentSequence = SEQ_TYPE_RIGHT_DIAGONAL_UP;
return TRUE;
}
else if((curentSequence == SEQ_TYPE_ANY || curentSequence == SEQ_TYPE_LEFT_DIAGONAL_UP) &&
(previousButton.tag - NO_OF_BUTTONS_IN_ROW - 1 == currentButton.tag))
{
resultLabel.text = [resultLabel.text stringByAppendingString:currentButton.titleLabel.text];
curentSequence = SEQ_TYPE_LEFT_DIAGONAL_UP;
return TRUE;
}
else if((curentSequence == SEQ_TYPE_ANY || curentSequence == SEQ_TYPE_LEFT_DIAGONAL_DOWN) &&
(previousButton.tag + NO_OF_BUTTONS_IN_ROW - 1 == currentButton.tag))
{
resultLabel.text = [resultLabel.text stringByAppendingString:currentButton.titleLabel.text];
curentSequence = SEQ_TYPE_LEFT_DIAGONAL_DOWN;
return TRUE;
}
else
{
resultLabel.text = #"";
curentSequence = SEQ_TYPE_ANY;
return FALSE;
}
}
// Event handler for button event
- (void)aMethod:(id)sender
{
UIButton *currentButton = (UIButton *)sender;
BOOL result = [self isAdjacent:currentButton];
if(result == FALSE)
{
self.previousButton = nil;
resultLabel.text = #"";
curentSequence = SEQ_TYPE_ANY;
}
else
{
self.previousButton = sender;
}
}
Hope it will help.
If I understand correctly, you need to know if the pushed button is adjacent to the previously pushed button? Use this function to test for adjacency in the grid:
bool isAdjacent(UIButton* current, UIButton* previous) {
if( !previous )
return false;
//Create a rectangle around the previous button (assuming all buttons are in a fixed grid)
CGRect previousRect = previous.frame;
CGRect adjacentRect = CGRectMake(previous.frame.origin.x - previous.frame.size.width,
previous.frame.origin.y - previous.frame.size.height,
previous.frame.size.width*3,
previous.frame.size.height*3);
return CGRectIntersectsRect(adjacentRect, previousRect);
}
And only append if they are adjacent, ie:
- (void)aMethod:(id)sender
{
UIButton *button = (UIButton *)sender;
static UIButton* previous = nil;
NSString *get = (NSString *)[[button titleLabel] text];
NSString *origText = mainlabel.text;
if( isAdjacent(button, previous) )
mainlabel.text = [origText stringByAppendingString:get];
previous = button;
//Rest of function
}
Fun question:
In this particular case, I agree with Luke about subclassing the UIButton. This way you could give each button an (X, Y) on your grid, as well as a (Xnext, Ynext) list for all of the possible expected next press locations (if the button itself can be used to make multiple words). Externally you will compare the currently being hit against the expected (Xnext, Ynext). If the two dont match, this is the signal you are looking for.
This is an answer that accounts for all of your situations, forward and backward horizontal (if you choose to implement backware), upward and downward vertical (if you choose to implement upward), and any diagonal, or any other combination you can come up with!
This also accounts for lets say hitting the D, then the O then trying to press the D again versus hitting the G. It also takes care of hitting the incorrect G.
Create a new .m .h pair of files (a new object) and give it your name.
Some example code for implementing a custom UIButton (h file):
#interface myConnectedUIButton : UIButton {
BOOL isAWordBeginCharacter;
unsigned int beginWordKey;
unsigned int myGridX;
unsigned int myGridY;
NSMutableArray * myConnectedSet;
}
-(id)init;
-(void)initWithGridX:(unsigned int)X GridY:(unsigned int)Y BeginChar:(BOOL)yesNo BeginWordKey:(unsigned int)key;
-(void)setGridPosWithX:(unsigned int)X Y:(unsigned int)Y;
-(void)setGridX:(unsigned int)X;
-(void)setGridY:(unsigned int)Y;
-(unsigned int)getGridX;
-(unsigned int)getGridY;
-(void)setIsABeginChar:(BOOL)yesNo;
-(BOOL)getIsABeginChar;
-(void)addPosToConnectedSetGridX:(unsigned int)X GridY:(unsigned int)Y WordKey:(unsigned int)key;
-(NSArray *)getMyConnectedSetArray;
-(void)clearConnectedSet;
#end
In the .m file of your
#implementation myConnectedUIButton
-(id)init{
[super init];
// Lets go ahead and initialize the NSMutableArray here also IFF it hasnt already been allocated
if( nil == myConnectedSet ){
myConnectedSet = [[NSMutableArray alloc] init];
}
// Lets also zero out the x, y position
myGridX = 0;
myGridY = 0;
// Lets also state that this is NOT a begin char for the time being and 0 for the begin char key
isAWordBeginCharacter = NO;
beginWordKey = 0;
return self;
}
-(void)initWithGridX:(unsigned int)X GridY:(unsigned int)Y BeginChar:(BOOL)yesNo BeginWordKey:(unsigned int)key{
// Lets go ahead and initialize the NSMutableArray here also IFF it hasnt already been allocated
if( nil == myConnectedSet ){
myConnectedSet = [[NSMutableArray alloc] init];
}
myGridX = X;
myGridY = Y;
isAWordBeginCharacter = yesNo;
beginWordKey = key;
}
-(void)setGridPosWithX:(unsigned int)X Y:(unsigned int)Y{
myGridX = X;
myGridY = Y;
}
-(void)setGridX:(unsigned int)X{
myGridX = X;
}
-(void)setGridY:(unsigned int)Y{
myGridY = Y;
}
-(unsigned int)getGridX{
return myGridX;
}
-(unsigned int)getGridY{
return myGridY;
}
-(void)setIsABeginChar:(BOOL)yesNo{
isAWordBeginCharacter = yesNo;
}
-(BOOL)getIsABeginChar{
return isAWordBeginCharacter;
}
-(void)addPosToConnectedSetGridX:(unsigned int)X GridY:(unsigned int)Y WordKey:(unsigned int)key{
[myConnectedSet addObject:[GridPointNext GridPointNextWithX:X GridPointY:Y NextWordKey:key]];
}
-(NSArray *)getMyConnectedSetArray{
return myConnectedSet;
}
-(void)clearConnectedSet{
[myConnectedSet removeAllObjects];
}
-(void)dealloc{
[myConnectedSet release];
[super dealloc];
}
#end
You will also now need a "GridPointNext" object.
The Grid Object header should look as follows:
#interface GridPointNext : NSObject {
unsigned int GridPointX;
unsigned int GridPointY;
unsigned int nextWordKey;
}
+(GridPointNext *)GridPointNextWithX:(unsigned int)X GridPointY:(unsigned int)Y NextWordKey:(unsigned int)key;
-(id)initWithX:(unsigned int)X GridPointY:(unsigned int)Y NextWordKey:(unsigned int)key;
-(unsigned int)getGridX;
-(unsigned int)getGridY;
-(unsigned int)getNextWordKey;
#end
The m file for the object should look as follows:
#implementation GridPointNext
+(GridPointNext *)GridPointNextWithX:(unsigned int)X GridPointY:(unsigned int)Y NextWordKey:(unsigned int)key{
GridPointNext * aPoint = [[GridPointNext alloc] initWithX:X GridPointY:Y NextWordKey:key];
[aPoint autorelease];
return aPoint;
}
-(id)initWithX:(unsigned int)X GridPointY:(unsigned int)Y NextWordKey:(unsigned int)key{
GridPointX = X;
GridPointY = Y;
nextWordKey = key;
return self;
}
-(unsigned int)getGridX{
return GridPointX;
}
-(unsigned int)getGridY{
return GridPointY;
}
-(unsigned int)getNextWordKey{
return nextWordKey;
}
#end
You will have to deal with the dealloc portion. This at least give you some tools for creating your custom button and your word list algorithm around it.
If I understand correctly. The user can only have a correct word, if the letters chosen are all sitting next to each other?
Have you tried this:
Keep two references. One UIButton for previousPressedButton and one UIButtonfor lastPressedButton.
First a user presses D. lastPressedButton will refer to the D.
Then a user presses O. previousPressedButton will be D. lastPressedButton will be O.
Now, get the width and height of the UIButtons and compare if the lastPressedButton.frame.origin.x will be less than width or -width away.
Also check if the lastPressedButton.frame.origin.y will be less than height or -height away.
Now you know if it's touching the previous button. Use this to decide if it's a new word or not.
I would put this into a method.
-(BOOL)isAdjacentLetter {
float buttonWidth = lastPressedButton.size.width;
float buttonHeight = lastPressedButton.size.height;
if(lastPressedButton.frame.origin.x>previousPressedButton.frame.origin.x+buttonWidth) return NO;
if(lastPressedButton.frame.origin.y>previousPressedButton.frame.origin.y+buttonHeight) return NO;
if(lastPressedButton.frame.origin.x<previousPressedButton.frame.origin.x-buttonWidth) return NO;
if(lastPressedButton.frame.origin.y<previousPressedButton.frame.origin.y-buttonHeight) return NO;
return YES;
}
Then whenever a button is clicked. you can use
if ([self isAdjacentLetter]) {
//still same word
} else {
//new word. erase
}
Or, if I understand differently. The words can only be made when the letters are in a row.Such as : From left to right. From down to up. From bottom right to top left etc.
In this case, determine all directions.
Such as, top left is 0, top is 1, top right is 2. right is 3. down right is 4. down is 5. down left is 6. left is 7.
When two buttons are clicked, store the directions. For example:
If it's from left to right, direction = 3;
Then when another button is clicked, check the new direction. If it's 3, the word is still in the same direction. if it's something else, then erase and start over.
Hope this helps.

iPhone Calculator decimal digits reversed on input

While doing tutorial work, it took me forever to implement a decimal point, and now i have one, that works in the formula, but the issue is it reverses the input - e.g.. enter 1.4, the calculator screen shows it as 4.1 - i know its something to do with my housekeeping of the variables.. planning to use BOOL's instead of a float..but..any takers?
The code:
- (IBAction) pressedDecimal: (id) sender
{
pressedDec = 1;
}
- (IBAction) pressedDigit: (id) sender
{
if (pressedDec == 1)
{currentNumber = .1 * currentNumber + (double)[sender tag];
calculatorScreen.text = [NSString stringWithFormat:#"%g",currentNumber];
}
else
{
currentNumber = currentNumber * 10 + (double)[sender tag];
calculatorScreen.text = [NSString stringWithFormat:#"%g",currentNumber];
pressedDec = 0;
}
}
- (IBAction) pressedOperation: (id) sender
{
if (currentOperation == 0) result = currentNumber;
else {
switch (currentOperation) {
case 1:
result = result + currentNumber;
break;
case 2:
result = result - currentNumber;
break;
case 3:
result = result * currentNumber;
break;
case 4:
result = result / currentNumber;
break;
case 5:
currentOperation = 0;
break;
}
}
currentNumber = 0;
calculatorScreen.text = [NSString stringWithFormat:#"%g",result];
if ([sender tag] == 0) result = 0;
currentOperation = [sender tag];
}
Consider more carefully what this extract from your code does:
currentNumber = .1 * currentNumber + (double)[sender tag];
(I'm not being very explicit because if I've understood the question right you're doing this in order to learn, and the more you have to think the better you'll learn :-).)
Lesson number 2 here: Stanford iTunes U tutorial covers building a simple calculator. Might be helpful. Either way it's a great tutorial series.

How to change number of decimal places and add decimal button iPhone Calculator?

So, look at the following code below- my first question is, how can I make it so there is only 0, 1, or 2 decimal places or make it automatically have however many decimal places are there? the second question is, how would I add a decimal button to the calculator? it has +-/*, how would I add a decimal button? Tutorial I used is here http://www.youtube.com/watch?v=Ihw0cfNOrr4 and here is my code-
viewcontroller.h
#import <UIKit/UIKit.h>
#interface calcViewController : UIViewController {
float result;
IBOutlet UILabel *calculatorScreen;
int currentOperation;
float currentNumber;
}
-(IBAction)buttonDigitPressed:(id)sender;
-(IBAction)buttonOperationPressed:(id)sender;
-(IBAction)cancelInput;
-(IBAction)cancelOperation;
#end
in the .m
#import "calcViewController.h"
#implementation calcViewController
-(IBAction)buttonDigitPressed:(id)sender {
currentNumber = currentNumber *10 + (float)[sender tag];
calculatorScreen.text = [NSString stringWithFormat:#"%2f", currentNumber];
}
-(IBAction)buttonOperationPressed:(id)sender {
if (currentOperation ==0) result = currentNumber;
else {
switch (currentOperation) {
case 1:
result = result + currentNumber;
break;
case 2:
result = result - currentNumber;
break;
case 3:
result = result * currentNumber;
break;
case 4:
result = result / currentNumber;
break;
case 5:
currentOperation = 0;
break;
}
}
currentNumber = 0;
calculatorScreen.text = [NSString stringWithFormat:#"%2f", result];
if ([sender tag] ==0) result=0;
currentOperation = [sender tag];
}
-(IBAction)cancelInput {
currentNumber =0;
calculatorScreen.text = #"0";
}
-(IBAction)cancelOperation {
currentNumber = 0;
calculatorScreen.text = #"0";
currentOperation = 0;
}
you can use this on the output.
Float *number = 2.2f;
NSLog(#"%.2f",number);
Another thing you want to take note about the point is that you do not want to have multiple point in your calculation, e.g. 10.345.1123.5. Simply put, you want it to be a legal float number as well.
With that said, you can use a IBAction (remember to link it to your storyboard or xib file)
-(IBAction)decimalPressed:(UIButton *)sender
{
NSRange range = [self.display.text rangeOfString:#"."];
if (range.location ==NSNotFound){
self.display.text = [ self.display.text stringByAppendingString:#"."];
}
self.userIsInTheMiddleOfEnteringANumber = YES;
}
While it might be possible we are doing on the same project, it could also be entirely different (you starting from scratch by yourself) so i will go through some of the codes
you could replace UIButton with the default id, but it is better to static replace it to make clear clarification for yourself, or anyone else who view your code.
NSRange as the name implies, mark the range, and the range will be ur display text of calculation (e.g. 1235.3568), and the range of string it is targeting in this case is "." therefore, if NSNotfound (rangeOfString "." is not found in the text range) you will append the current display text with "." with the function stringByAppendingString:#".", there is no else, so no function will take place if "." is already found, which solve the problem of multiple point on the display.
userIsInTheMiddleOfEnteringANumber is a BOOL to solve the problem of having 0 in ur display (e.g. 06357), if you have a method to change it, then replace my method name with your own.
Regarding the display, as I'm using a different approach compared to yours, I'm unable to give any help or guide in that aspect.
This is my solution:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController {
float result;
IBOutlet UILabel *TextInput;
int currentOperation;
float currentNumber;
BOOL userInTheMiddleOfEnteringDecimal;
}
- (IBAction)buttonDigitPressed:(id)sender;
- (IBAction)buttonOperationPressed:(id)sender;
- (IBAction)cancelInput;
- (IBAction)cancelOperation;
- (IBAction)dotPressed;
#end
Viewcontroller.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (IBAction)buttonDigitPressed:(id)sender {
if(!userInTheMiddleOfEnteringDecimal)
{
currentNumber = currentNumber*10 + (float)[sender tag];
TextInput.text = [NSString stringWithFormat:#"%d",(int)currentNumber];
}
else{
TextInput.text= [TextInput.text stringByAppendingString:[NSString stringWithFormat:#"%d",[sender tag]]];
currentNumber = [TextInput.text floatValue];
}
}
- (IBAction)buttonOperationPressed:(id)sender {
if (currentOperation == 0) result = currentNumber;
else {
switch (currentOperation) {
case 1:
result = result + currentNumber;
break;
case 2:
result = result - currentNumber;
break;
case 3:
result = result * currentNumber;
break;
case 4:
result = result / currentNumber;
break;
case 5:
currentOperation = 0;
break;
default:
break;
}
}
currentNumber = 0;
TextInput.text = [NSString stringWithFormat:#"%.2f",result];
if ([sender tag] == 0) result = 0;
currentOperation = [sender tag];
userInTheMiddleOfEnteringDecimal = NO;
}
-(IBAction)cancelInput{
currentNumber = (int)(currentNumber/10);
TextInput.text = [NSString stringWithFormat:#"%.2f",currentNumber];;
}
-(IBAction)cancelOperation{
currentNumber = 0;
TextInput.text = #"0";
userInTheMiddleOfEnteringDecimal = NO;
}
- (IBAction)dotPressed{
if(!userInTheMiddleOfEnteringDecimal){
userInTheMiddleOfEnteringDecimal = YES;
TextInput.text= [TextInput.text stringByAppendingString:#"."];
}
}
#end
Hope this helps.. This includes the decimal point in the button...

how to use only numeric keyboard

i had made an application of temperature converter in iphone i want that when it launches in simulator only numeric keyboard should come and not the alpha keyboard.
#import "farh_celcius_conv_AppDelegate.h"
float i;
float s;
float p;
#implementation farh_celcius_conv_AppDelegate
#synthesize window,display,farhenite,display1;
-(IBAction) convert {
s = ('0','1','2');
if( p == s)
{
NSString *str = farhenite. text;
float n = [str floatValue];
if (n != 0) {
k =.5559* (n-32);
i = 5*(n -32)/9 +273 ;
[display setText:[NSString stringWithFormat:#"%f",k]];
[display1 setText:[NSString stringWithFormat:#"%f",i]];
}
}
}
- (void)dealloc {
[window release];
[super dealloc];
}
#end
You can set various types of keyboard for your text field. Look into inspector under Text Input traits, keyboard.
Try this,
yourTextField.keyboardType = UIKeyboardTypePhonePad;
or
yourTextField.keyboardType = UIKeyboardTypeNumberPad;
You can also do this in the nib file.
[myTextField setKeyboardType:UIKeyboardTypeNumberPad];