iOS 8 数字转换/格式错误?(无法复制) [英] iOS 8 number conversion/formatting error? (cannot reproduce)

查看:24
本文介绍了iOS 8 数字转换/格式错误?(无法复制)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下方法从 UITextField 获取输入并将其格式化以进行显示.这段代码多年来一直完美运行,但刚刚在使用 iOS 8.1 的 iPhone 6 Plus 上报告了一个问题.用户每次都会发生这种情况,但我无法重现它.我相信这与 iOS 8 上的 NSNumber/NSDecimalNumber 转换和格式有关,也许是针对 64 位应用程序/设备.

The following method takes input from a UITextField and formats it for display. This code has worked flawlessly for years, but a problem was just reported on the iPhone 6 Plus using iOS 8.1. It happens every time for the user but I have not been able to reproduce it. I believe it has to do with NSNumber/NSDecimalNumber conversions and formatting on iOS 8, perhaps for a 64-bit app/device.

用于输入的键盘是数字小键盘,因此可以在文本字段中输入的唯一文本是数字 0-9 和删除".

The keyboard used for input is a number pad, so the only text that can be entered into the textfield are the numbers 0-9 and "delete".

根据用户的说法,这是正在发生的事情:

According to the user, this is what is happening:

我正在尝试输入 250 美元的预算金额.当我把它拉起来最初是显示 0.00.然后只要我输入 2,它就会显示220.02 然后当我输入 5 时它会显示 2,200.25 然后当我输入 0 时它会出现 22,002.50 如果我尝试擦除它出现的任何数字数量很大.

I am trying to enter a budget amount of $250. When I pull it up initially is shows 0.00. Then as soon as I enter 2, it then show 220.02 then when I enter the 5 it says 2,200.25 then when I enter the 0 it comes up with 22,002.50 if I try to erase any numbers it come up with a really large number.

就我在模拟器中的所有设备(包括 iPhone 6 Plus)上进行的测试,以下代码与 iOS 8.1 完美配合.它也适用于装有 iOS 8.1 的 iPhone 5S 设备(64 位).我没有 iPhone 6 Plus 设备.

The code below works perfectly with iOS 8.1, as far as I have tested, on every device in the simulator, including the iPhone 6 Plus. It also works in the iPhone 5S device (64-bit) with iOS 8.1. I do not have an iPhone 6 Plus device.

我是否遗漏了某些人认为可能导致此错误的内容?

Am I missing something that someone sees might be causing this error?

这可能是因为decimalNumberWithMantissa 参数应该是unsigned long long 而我使用的是NSInteger?这是否会导致问题,如果是,为什么它一直工作到 iPhone 6 Plus 上的 iOS 8.1?如果可以的话,我会自己检查一下...

Could this possibly be because decimalNumberWithMantissa parameter should be unsigned long long and I am using NSInteger? Would this cause the problem, and if so, why has it worked until iOS 8.1 on iPhone 6 Plus? I would check this myself if I could...

entryField UITextField 初始化如下:

The entryField UITextField is initialized as follows:

entryField.text = [NSString stringWithFormat:@"%@", [[[ObjectsHelper sharedManager] currencyFullFormatter] stringFromNumber:[NSDecimalNumber zero]]];

这里是其余的相关代码:

and here is the rest of the relevant code:

#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.m:

From DateHelper.m:

+ (NSNumberFormatter *)decimalFormatter {   

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

        return decimalFormatter;
    }

来自 ObjectsHelper.m:

From 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 可能是在正确的轨道上,只是不确定这里会如何翻译.会改变

Seems like this answer might be on the right track, just not exactly sure how that would translate here. Would changing

    //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];

有可能解决问题吗?

推荐答案

似乎 iOS 8 的自定义键盘可能存在问题.需要进一步调查,但此时至少出现了一次此问题已由从设备上移除自定义键盘.

Seems like there may be an issue with custom keyboards for iOS 8. Need to investigate further but at this point at least one occurrence of this issue has been fixed by removing the custom keyboard from the device.

是否确认此特定问题是由 iOS 8 自定义键盘应用程序引起的.该问题已报告给应用的发布者.

Is it confirmed that this particular issue was caused by an iOS 8 custom keyboard app. The issue has been reported to the publishers of the app.

这篇关于iOS 8 数字转换/格式错误?(无法复制)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆