2010-01-03 4 views
1

iPhone/Objective-C/Cocoa newbie here. stackoverflow에 게시물의 수를 기반으로, 나는 내가 만들고있는 기본 아이폰 계산기 애플 리케이션에서 사용하고있는 IBAction을 함께 수선했다. IBAction은 숫자 키패드와 함께 작동하여 소수점을 입력하지 않고도 10 진수를 입력 할 수 있습니다.iPhone 통화 입력에 float 대신 NSDecimal을 사용합니다.

질문을 게시 한 다른 많은 사람들처럼 그렇게하기가 어려울지라도 "통화 할 때 NSDecimal 사용"이라는 말을 고수하기 란 매우 어렵습니다. 나는 꾸준한 진전을 보이고 있지만, NSDecimal과 Format Specifications에 대해 머리 글을 쓰고 나면 사소한 것처럼 보일 것이라고 확신한다. 여기

내가 (이 UITextField에 이벤트를 변경 편집에 의해 트리거)를 사용하고있어 IBAction를 수 있습니다 :

// called when user touches a key or button 
- (IBAction)processKeystrokes:(id)sender 
{ 
static BOOL toggle = YES; // was this method triggered by the user? 

// the user touched the keypad 
if (toggle) 
{ 
    toggle = NO; 

    // retrieve the strings in input fields 
    NSString *currencyField1Text = currencyField1.text; 
    NSString *currencyField2Text = currencyField2.text; 

    if (sender == currencyField1) { 
    currencyField1Text = [currencyField1Text stringByReplacingOccurrencesOfString:@"." withString:@""]; 
    float currency = [currencyFieldText floatValue]/100; 
    currencyField1.text = [@"" stringByAppendingFormat:@"%0.2f", currency]; 
    } 
    else if (sender == currencyField2) { 
    currencyField2Text = [currencyField2Text stringByReplacingOccurrencesOfString:@"." withString:@""]; 
    NSDecimalNumber *currency2 = [[NSDecimalNumber decimalNumberWithString:currencyField2Text] decimalNumberByDividingBy:[NSDecimalNumber decimalNumberWithString:@"100"]]; 
    currencyField2.text = [@"" stringByAppendingFormat:@"%@", currency2]; 
    } 
    else { 
    NSLog(@"Some unexpected input"); 
    } 
} 
else 
{ 
    toggle = YES; 
} 

} // end method calculateResults 

currencyField1 코드 세그먼트가 수레를 사용의 currencyField2 세그먼트는 NSDecimal를 사용합니다.

currencyField1 세그먼트는 원하는대로 작동합니다. 소수점 이하 두 자리 숫자로 모든 숫자를 표시합니다 (삭제 된 키를 사용하여 입력 한 모든 숫자를 삭제하는 경우에도 마찬가지 임). 그러나 큰 통화 값을 처리 할 때 float를 사용할 때의 문제점을 완벽하게 설명합니다. 입력 된 숫자가 8 자리를 초과하면 반올림 오류가 표시됩니다.

currencyField2 세그먼트는 float 대신 NSDecimal을 사용하여 반올림 오류 문제를 방지합니다. 그러나 소수점 뒤에 두 자리 숫자가 항상 표시되는 것은 아닙니다. 삭제 키를 사용하여 입력 한 모든 숫자를 삭제할 때 표시됩니다.

currencyField1.text = [@"" stringByAppendingFormat:@"%0.2f", currency]; 

그래서, 내가 동등 필요가 있다고 생각 :이 수레에 대해 원하는 형식을 만들어 다음 줄에 대한 추론이

currencyField2.text = [@"" stringByAppendingFormat:@"%@", currency2]; 

: 나는 문제 때문에이 코드 줄을 믿습니다 "0"값 NSDecimalNumber의 표시 형식을 지정하기위한 @ "% 0.2f" 나는 이렇게 많은 시간 동안 내가 당혹 스럽다. 그러나 나는 단지 그것을 이해할 수 없다.

도움이나 의견을 보내 주시면 감사하겠습니다.

EDIT : 문제를 해결 한 것으로 보이는 Brad의 의견과 비슷한 NSNumberFormatter 객체를 통합했습니다. 그러나 코드를 리펙토링하는 것에 대한 피드백을 받고 싶습니다. 다음은 수정 된 코드입니다 :

// called when user touches a key or button 
- (IBAction)processKeystrokes:(id)sender 
{ 
static BOOL toggle = YES; // was this method triggered by the user? 

// the user touched the keypad 
if (toggle) 
{ 
    toggle = NO; 

    // retrieve the strings in input fields 
    NSString *currencyField1Text = currencyField1.text; 
    NSString *currencyField2Text = currencyField2.text; 

    // new code elements 
    NSNumberFormatter * nf = [[[NSNumberFormatter alloc] init]autorelease]; 
    [nf setNumberStyle:NSNumberFormatterCurrencyStyle]; 
    [nf setCurrencySymbol:@""]; 
    [nf setCurrencyGroupingSeparator:@""]; 

    if (sender == currencyField1) { 
    currencyField1Text = [currencyField1Text stringByReplacingOccurrencesOfString:@"." withString:@""]; 
    NSDecimalNumber *currency = [[NSDecimalNumber decimalNumberWithString:currencyField1Text] decimalNumberByDividingBy:[NSDecimalNumber decimalNumberWithString:@"100"]]; 
    currencyField1.text = [nf stringFromNumber:currency]; 
    } 
    else if (sender == currencyField2) { 
    currencyField2Text = [currencyField2Text stringByReplacingOccurrencesOfString:@"." withString:@""]; 
    NSDecimalNumber *currency2 = [[NSDecimalNumber decimalNumberWithString:currencyField2Text] decimalNumberByDividingBy:[NSDecimalNumber decimalNumberWithString:@"100"]]; 
    currencyField2.text = [nf stringFromNumber:currency2]; 
    } 
    else { 
    NSLog(@"Some unexpected input"); 
    } 
} 
else 
{ 
    toggle = YES; 
} 

} // end method calculateResults 

그것은 내 초기 문제를 해결,하지만 난 그것을 개선하는 방법에 대한 조언을 부탁드립니다. 감사.

답변

1

당신이 당신의 텍스트 값의 소수점 2 개 자리를 보장하려면 다음 코드 (답 here에서 가져온)처럼, 당신은 NSNumberFormatter을 사용할 수

NSNumberFormatter *decimalNumberFormatter = [[NSNumberFormatter alloc] init]; 
[decimalNumberFormatter setMinimumFractionDigits:2]; 
[decimalNumberFormatter setMaximumFractionDigits:2]; 
currencyField2.text = [decimalNumberFormatter stringFromNumber:currency2]; 
[decimalNumberFormatter release]; 

나는이 보존한다고 생각 NSDecimalNumber의 정밀도 개인적으로, 성능상의 이유로 NSDecimal C 구조체를 사용하는 것을 선호하지만 값을 가져오고 나가는 것이 조금 어렵습니다.

+0

감사 브래드. 귀하의 제안은 효과가 있었지만 사용자가 입력 한 모든 자릿수를 삭제하면 선두의 "0"이 사라졌습니다. 그러면 "0.00"을 표시하려는 값이 ".00"이됩니다. "[nf setNumberStyle : NSNumberFormatterCurrencyStyle];"로 고정했습니다. 소수점과 두 개의 후행 자리를 가져왔다. "nf setCurrencySymbol : @" "];"을 사용하여 제거한 통화 기호 ("$") 및 통화 그룹 구분 기호 (",") 및 "[nf setCurrencyGroupingSeparator : @" "];" 각기. 포인터 주셔서 감사합니다 - NSNumberFormatter 문제를 해결! –

0

NSNumberFormatter 대신 (NSNumberFormatter의) -setFormat: 메서드를 사용할 수 없습니까? 귀하의 목적에 맞게 구성 할 수 있어야하고 통화 서식이 지정된 문자열에서 이상한 "해킹"을 처리 할 필요가 없을 것입니다.더 많은 정보를 들어

은 다음을 참조하십시오

관련 문제