2014-11-04 7 views
5

Следующий метод принимает входные данные из UITextField и форматирует его для отображения. Этот код работал безупречно годами, но проблема была только что сообщена на iPhone 6 Plus с использованием iOS 8.1. Это происходит каждый раз для пользователя, но я не смог воспроизвести его. Я считаю, что это связано с преобразованиями NSNumber/NSDecimalNumber и форматированием на iOS 8, возможно, для 64-разрядного приложения/устройства.iOS 8 номер изменение/форматирование ошибка? (не может воспроизводиться)

Клавиатура, используемая для ввода, представляет собой цифровую клавиатуру, поэтому только текст, который можно ввести в текстовое поле, это цифры 0-9 и «удалить».

По словам пользователя, это то, что происходит:

Я пытаюсь войти в бюджет сумму $ 250. Когда я его вытащил, изначально показывает 0.00. Затем, как только я вхожу в 2, он показывает 220.02, затем, когда я вхожу в 5, он говорит 2,200.25, затем, когда я вхожу в 0, он появляется с 22 002.50, если я попытаюсь стереть все числа, которые он набрал с действительно большим количеством.

Код, приведенный ниже, отлично работает с iOS 8.1, насколько я проверял, на каждом устройстве в тренажере, включая iPhone 6 Plus. Он также работает в устройстве iPhone 5S (64-бит) с iOS 8.1. У меня нет устройства iPhone 6 Plus.

Я пропустил что-то, что кто-то видит, может вызвать эту ошибку?

EDIT: Возможно, это возможно потому, что параметр decimalNumberWithMantissa должен быть без знака длинным, и я использую NSInteger? Это вызовет проблему, и если да, то почему она работает до iOS 8.1 на iPhone 6 Plus? Я хотел бы проверить это сам, если бы я мог ...

The 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. м:

+ (NSNumberFormatter *)decimalFormatter { 

     __ENTERING_METHOD__ 
     NSNumberFormatter *decimalFormatter = [[NSNumberFormatter alloc] init]; 
     [decimalFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4]; 
     [decimalFormatter setNumberStyle:NSNumberFormatterDecimalStyle]; 

     return decimalFormatter; 
    } 

От 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; 
} 

EDIT: Похоже, что этот 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]'. Обратите внимание, что пользователь может выбрать часть текстового поля и заменить его с помощью копирования/вставки. –

+0

Спасибо. Считаете ли вы, что это вызовет эту проблему? Я уверен, что если бы смог воспроизвести ошибку, которую я смог (в конечном итоге) исправить, но, к сожалению, я являюсь независимым разработчиком и не могу позволить себе купить iPhone 6 Plus. Любые мысли о том, почему такая ошибка будет отображаться каждый раз на устройстве (по крайней мере, на одном устройстве), но никогда в симуляторе для этого устройства? – SAHM

+0

Кроме того, textField не выбирается, если это помогает чему-либо (что, вероятно, не так). Единственный способ, которым пользователь может изменить содержимое, - это клавиатура с клавишами 0-9 и удаление. – SAHM

ответ

1

Похоже, что может возникнуть проблема с пользовательскими клавиатурами для iOS 8. Необходимо продолжить исследование, но на этом этапе по крайней мере одно возникновение этой проблемы было устранено путем удаления пользовательской клавиатуры с устройства.

EDIT: подтверждено, что эта проблема была вызвана пользовательским приложением клавиатуры iOS 8. Об этом сообщается издателям приложения.

+0

На боковой стороне заметки - я должен связаться с Apple об этом? Если сторонние приложения для клавиатуры могут вызвать такую ​​проблему, следует ли Apple об этом знать? Я не совсем уверен, как работают такие приложения, но это похоже на то, что делегаты UITextfield были переписаны в моем случае. – SAHM