以下方法從UITextField獲取輸入並將其格式化以供顯示。這段代碼多年來一直運行良好,但是使用iOS 8.1在iPhone 6 Plus上報告了一個問題。它每次都會發生在用戶身上,但我一直無法重現它。我相信它與iOS 8上的NSNumber/NSDecimalNumber轉換和格式有關,可能是針對64位應用程序/設備。iOS 8號碼轉換/格式錯誤? (無法重現)
用於輸入的鍵盤是一個數字鍵盤,所以只能輸入文本框的文本是數字0-9和「刪除」。
根據用戶,這是發生了什麼事:
我試圖進入的$ 250的預算金額。當我拉起來 最初是顯示0.00。然後,當我進入2,它然後顯示 220.02然後當我進入5它說2,200.25然後當我進入0它22,002.50來了,如果我試圖抹掉它拿出 一個很大數字的任何數字。
就我測試過的模擬器中的每個設備(包括iPhone 6 Plus)而言,以下代碼與iOS 8.1完美協作。它也適用於使用iOS 8.1的iPhone 5S設備(64位)。我沒有iPhone 6 Plus設備。
我是否錯過某人看到的東西可能會導致此錯誤?
編輯: 這可能是因爲decimalNumberWithMantissa參數應該是無符號long long,我使用NSInteger?這是否會導致問題,如果是這樣,爲什麼它一直工作到iPhone 6 Plus上的iOS 8.1?如果我能我會檢查這個自己...
的entryField的UITextField如下初始化:
entryField.text = [NSString stringWithFormat:@"%@", [[[ObjectsHelper sharedManager] currencyFullFormatter] stringFromNumber:[NSDecimalNumber zero]]];
這裏是相關的代碼的其餘部分:
#define MAX__NUMBER_LENGTH 10
- (BOOL)textField:(UITextField *)textFieldHere shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
__ENTERING_METHOD__
NSMutableString *mstring = [[NSMutableString alloc] initWithString:[entryField text]];
if([string length] > 0){
//add case
[mstring insertString:string atIndex:range.location];
}
else {
//delete case - the length of replacement string is zero for a delete
[mstring deleteCharactersInRange:range];
}
NSString *clean_string = [[mstring componentsSeparatedByCharactersInSet:
[[NSCharacterSet decimalDigitCharacterSet] invertedSet]]
componentsJoinedByString:@""];
//clean up mstring since it's no longer needed
if ((clean_string.length >= MAX__NUMBER_LENGTH && range.length == 0) || ([clean_string length] == 0 && [string isEqualToString:@"0"]))
{
return NO; // return NO to not change text
}
else {
//get the cleaned price in the form of a NSNumber - it has not yet been scaled
NSNumber *priceNumberBeforeScale = [[DateHelper decimalFormatter] numberFromString:clean_string];
self.budgetIntNumber = priceNumberBeforeScale;
//get the cleaned price in the form of an integer - it has not yet been scaled
NSInteger priceIntBeforeScale = [priceNumberBeforeScale integerValue];
//scale the price for currency
NSDecimalNumber *priceScaled = [NSDecimalNumber decimalNumberWithMantissa:priceIntBeforeScale exponent:(0-[[[ObjectsHelper sharedManager] currencyScale] integerValue]) isNegative:NO];
//now format the price for currency
//and get the grouping separators added in and put it in the UITextField
entryField.text = [[[ObjectsHelper sharedManager] currencyFullFormatter] stringFromNumber:priceScaled];
//always return no since we are manually changing the text field
return NO;
}
}
從DateHelper。米:
從ObjectsHelper.m:
- (NSNumberFormatter*)currencyFullFormatter {
__ENTERING_METHOD__
if (currencyFullFormatter != nil) {
return currencyFullFormatter;
}
currencyFullFormatter = [[NSNumberFormatter alloc] init];
[currencyFullFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
[currencyFullFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
return currencyFullFormatter;
}
- (NSNumber*)currencyScale {
__ENTERING_METHOD__
if (currencyScale != nil) {
return currencyScale;
}
self.currencyScale = [NSNumber numberWithInteger:[[[ObjectsHelper sharedManager] currencyFullFormatter] maximumFractionDigits]];
return currencyScale;
}
編輯: 看起來像這樣answer可能是在正確的軌道上,只是不完全確定如何在這裏翻譯。會改變
//get the cleaned price in the form of an integer - it has not yet been scaled
NSInteger priceIntBeforeScale = [priceNumberBeforeScale integerValue];
//scale the price for currency
NSDecimalNumber *priceScaled = [NSDecimalNumber decimalNumberWithMantissa:priceIntBeforeScale exponent:(0-[[[ObjectsHelper sharedManager] currencyScale] integerValue]) isNegative:NO];
到
//scale the price for currency
NSDecimalNumber *priceScaled = [NSDecimalNumber decimalNumberWithMantissa:[priceNumberBeforeScale unsignedLongLongValue] exponent:(0-[[[ObjectsHelper sharedManager] currencyScale] integerValue]) isNegative:NO];
有可能解決這個問題?
不知道這是否有幫助,但不是你的「添加大小寫/刪除大小寫」,你應該做'[mstring replaceCharactersInRange:range withString:string]'。請注意,用戶可能會選擇文本字段的一部分,並通過複製/粘貼來替換它。 – 2014-11-04 19:18:57
謝謝。你相信會導致這個問題嗎?我相信,如果我能重現錯誤,我可以(最終)修復它,但不幸的是,我是一名獨立開發人員,無法購買iPhone 6 Plus。任何想法爲什麼像這樣的錯誤會每次出現在設備上(至少有一個設備),但從來沒有在該設備的模擬器中顯示? – SAHM 2014-11-04 19:21:48
此外,textField不可選,如果這有助於任何事情(它可能不會)。用戶可以更改內容的唯一方法是通過鍵盤上的鍵0-9和刪除。 – SAHM 2014-11-04 19:24:24