Следующий метод принимает входные данные из 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];
, вероятно, чтобы решить эту проблему?
Не знаю, помогает ли это, но вместо вашего «случая сложения/удаления» вы должны, вероятно, сделать '[mstring replaceCharactersInRange: range withString: string]'. Обратите внимание, что пользователь может выбрать часть текстового поля и заменить его с помощью копирования/вставки. –
Спасибо. Считаете ли вы, что это вызовет эту проблему? Я уверен, что если бы смог воспроизвести ошибку, которую я смог (в конечном итоге) исправить, но, к сожалению, я являюсь независимым разработчиком и не могу позволить себе купить iPhone 6 Plus. Любые мысли о том, почему такая ошибка будет отображаться каждый раз на устройстве (по крайней мере, на одном устройстве), но никогда в симуляторе для этого устройства? – SAHM
Кроме того, textField не выбирается, если это помогает чему-либо (что, вероятно, не так). Единственный способ, которым пользователь может изменить содержимое, - это клавиатура с клавишами 0-9 и удаление. – SAHM