Reputation: 45
building a simple calculator here to get my feet wet with iOS dev. I want to prohibit the entry of more than one decimal point. Put my logic in the comment.
It builds and runs with no problem, but it's not blocking the entry of more than one "." any help is appreciated. Thanks.
- (IBAction)digitPressed:(UIButton *)sender
{
NSString *digit = [[sender titleLabel] text];
if (userIsInTheMiddleofTypingANumber) {
[display setText:[[display text] stringByAppendingString:digit]];
// if the user enters a decimal point, check if the existing display text contains a "." if not, then allow it, but if it does, do not allow it.
NSString *decimal = @".";
NSRange range = [digit rangeOfString:decimal];
if (range.location == NSNotFound) {
[display setText:digit];
}
} else {
[display setText:digit];
userIsInTheMiddleofTypingANumber = YES;
}
}
Upvotes: 4
Views: 1945
Reputation: 11
This worked for me:
- (IBAction)digitPressed:(UIButton *)sender
{
NSString *digit = [[sender titleLabel] text];
if (userIsInTheMiddleOfTypingANumber)
{
if (decimalEntered)
{
NSRange range = [digit rangeOfString:@"."];
if (range.location == NSNotFound)
{
[display setText:[[display text] stringByAppendingString:digit]];
}
else
{
NSLog(@"You can't enter more than one decimal");
}
}
else if (!decimalEntered)
{
NSRange range = [digit rangeOfString:@"."];
if (range.location == NSNotFound)
{
[display setText:[[display text] stringByAppendingString:digit]];
}
else
{
[display setText:[[display text] stringByAppendingString:digit]];
decimalEntered = YES;
}
}
}
else
{
decimalEntered = NO;
[display setText:digit];
userIsInTheMiddleOfTypingANumber = YES;
}
}
Upvotes: 1
Reputation: 5112
- (IBAction)digitPressed:(UIButton *)sender
{
NSString *digit = [[sender titleLabel] text];
NSString *decimal = @".";
BOOL decimalAlreadyEntered = [display.text rangeOfString:decimal].location == NSNotFound ? NO : YES;
if (userIsInTheMiddleofTypingANumber) {
if (([digit isEqual:decimal] && !decimalAlreadyEntered) || !([digit isEqual:decimal])) {
[display setText:[[display text] stringByAppendingString:digit]];
}
}
else if (display.text isEqual:@"0" && digit == decimal){
[display setText:[[display text] stringByAppendingString:digit]];
userIsInTheMiddleofTypingANumber = YES;
}
else {
[display setText:digit];
userIsInTheMiddleofTypingANumber = YES;
}
}
I think this should work. It looks like you are appending the digit first thing in your loop, even if a decimal has been entered. I haven't tried this code in the compiler but it checks to see if a decimal has been entered first.
Upvotes: 2
Reputation: 64002
Don't frustrate your user. Give them feedback about what you can and cannot accept for input:
- (IBAction)digitPressed:(UIButton *)sender
{
NSString *char = [[sender titleLabel] text];
if( [char isEqualTo:@"."] ){
[sender setEnabled:NO];
}
[display setText:[[display text] stringByAppendingString:char]];
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)replacementRange replacementString:(NSString *)replacementString {
// Re-enable the button if the decimal point is deleted
NSRange rangeForPoint = [[display.text substringWithRange:replacementRange]
rangeOfString:@"."];
if( NSNotFound != rangeForPoint.location ){
// You may also want to check that replacementString does not contain a new
// decimal point, in the case of pasted text, e.g.
[decimalPointButton setEnabled:YES];
}
}
This delegate method, textField:shouldChangeCharactersInRange:replacementString:
is really the key to handling restricted input. You should also look at NSFormatter, which can take a format and validate input as the user types, using its isPartialStringValid...
methods.
Upvotes: 2
Reputation: 11834
You might want to check an earlier post by me, which deals with sort of the same issue. I tried creating a textfield that accepts limited input (for example only numbers in the following format: 0.00). It never worked completely great (it had some bugs with currency I believe), but it might be good enough for your purposes:
Re-Apply currency formatting to a UITextField on a change event
Upvotes: 1
Reputation: 1631
Try below updated code of yours
- (IBAction)digitPressed:(UIButton *)sender
{
NSString *digit = [[sender titleLabel] text];
if (userIsInTheMiddleofTypingANumber)
{
// if the user enters a decimal point, check if the existing display text contains a "." if not, then allow it, but if it does, do not allow it.
NSString *decimal = @".";
NSRange range = [digit rangeOfString:decimal];
if (range.location == NSNotFound)
{
[display setText:[[display text] stringByAppendingString:digit]];
[display setText:digit];
}
}
else
{
[display setText:digit];
userIsInTheMiddleofTypingANumber = YES;
}
}
Upvotes: 0