3 回答
Pragmatically I would simply remove the comma before parsing the string into a number then it must work.
NSString *s = [self.calDisplay.stringValue
stringByReplacingOccurrencesOfString:@"," withString:@""];
Leaving you with
- (IBAction)digitPressed:(NSButton *)sender {
if (userIsEnteringANumber) {
NSString *s = [self.calDisplay.stringValue stringByReplacingOccurrencesOfString:@"," withString:@""];
NSNumber *number = [formatter numberFromString:[s stringByAppendingString:sender.title]];
self.calDisplay.stringValue = [formatter stringFromNumber:number];
} else {
self.calDisplay.stringValue = sender.title;
userIsEnteringANumber = YES;
}
}
I believe this is what happens:
The string you have is "2,569". Which is two thousand something. This works fine, because the thousands delimiter is a comma.
After another button press (e.g. 1), your string becomes "2,5691". This is not a proper number, because it has the thousands delimiter (comma) wrong, hence the nil number. "25,691" would have been correct, but you have "2,5691".
Try this:
- (IBAction)digitPressed:(NSButton *)sender {
if (userIsEnteringANumber) {
double previous = [[self.calDisplay.stringValue] doubleValue];
double pressed = [sender.title doubleValue];
NSNumber *number = [NSNumber numberWithDouble:previous*10+pressed];
self.calDisplay.stringValue = [formatter stringFromNumber:number];
}
else {
self.calDisplay.stringValue = sender.title;
userIsEnteringANumber = YES;
}
}
to expand on the bogdansrc's answer pointing out that the formatter is not at fault here, one way to solve this (homework?) problem that allows entering digits for strings that already appear as double in your display would be as follows:
- (IBAction)digitPressed:(NSButton *)sender {
if (userIsEnteringANumber)
{
double previous = self.calDisplay.stringValue.doubleValue;
NSString* pressed = sender.title;
NSString* newNumber = [NSString stringWithFormat:@"%g%s", previous, pressed];
self.calDisplay.stringValue = [formatter stringFromNumber:[newNumber doubleValue]];
}
else
{
self.calDisplay.stringValue = sender.title;
userIsEnteringANumber = YES;
}
}
of course, this is not really ideal MVC, as the code relies on the View to track its Model … and by so doing, it's hard to be able to know from only the code snippet you provided how to transition from 260 to 260.4 when 4 is pressed after getting into the state that is supposed to be a fractional decimal number. is the decimal place being shown and tracked as the last character in stringValue? if so, the above will break because the "." at the end will get lost. if not, well then the Model is basically spread out partly in the View and partly in separate state, which is even less ideal.