2014-11-04 43 views
5

以下方法從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]; 

有可能解決這個問題?

+1

不知道這是否有幫助,但不是你的「添加大小寫/刪除大小寫」,你應該做'[mstring replaceCharactersInRange:range withString:string]'。請注意,用戶可能會選擇文本字段的一部分,並通過複製/粘貼來替換它。 – 2014-11-04 19:18:57

+0

謝謝。你相信會導致這個問題嗎?我相信,如果我能重現錯誤,我可以(最終)修復它,但不幸的是,我是一名獨立開發人員,無法購買iPhone 6 Plus。任何想法爲什麼像這樣的錯誤會每次出現在設備上(至少有一個設備),但從來沒有在該設備的模擬器中顯示? – SAHM 2014-11-04 19:21:48

+0

此外,textField不可選,如果這有助於任何事情(它可能不會)。用戶可以更改內容的唯一方法是通過鍵盤上的鍵0-9和刪除。 – SAHM 2014-11-04 19:24:24

回答

1

看起來有可能是爲iOS 8的自定義鍵盤的問題需要進一步研究,但這個問題在這一點上至少出現問題被修正,從設備移除自定義鍵盤。

編輯:能否確認這一具體問題是由一個iOS的8個自定義鍵盤的應用程序引起的。這個問題已經報告給應用程序的發佈者。

+0

在側欄上註明 - 我應該聯繫Apple嗎?如果第三方鍵盤應用程序可能導致這樣的問題,Apple是否應該知道這一點?我不確定這些應用程序是如何運作的,但似乎UITextfield代表在我的情況下被覆蓋。 – SAHM 2014-11-13 23:24:58