Използвайки NSNumberFormatter, как можете да използвате 2 знака след десетичната запетая, но въпреки това да запазите дали потребителят е въвел само 1 или 2 знака след десетичната запетая?

Знам всичко за начина, по който се съхраняват десетичните точки, но не съм сигурен как мога да ги покажа правилно, за да отговоря на изискванията си.

Имам поле, което позволява на потребителя да въвежда до максимум 2 знака след десетичната запетая. 11.25, 9.9 и т.н.

Въпреки това е изключително важно въведената стойност да се показва точно както е въведена.

Например, въвеждам 9.9 (което вероятно се съхранява като 9.8999999999999). След това, когато се показва на потребителя, се показва като 9,89.

Имам нужда това да се покаже, както е написано, като 9.9.

По същия начин 11.25 трябва да се показва като 11.25. Ако 2 десетични знака са били въведени от потребителя, 2 трябва да се покаже. Ако само 1 е въведено от потребителя, 1 трябва да се покаже, независимо как се съхранява (т.е. 9.899999999999)


person chris P    schedule 15.03.2015    source източник


Отговори (3)


За точни десетични числа използвайте NSDecimalNumber, по този начин няма да получите 9,899999999999, а 9,9.

Режимът на закръгляване може да бъде зададен с метода setRoundingMode: на класа NSNumberFormatter на една от NSNumberFormatterRoundingMode константите.

Форматът на дисплея може да бъде зададен с метода setFormat: от NSNumberFormatter.

За да покажете броя на въведените десетични цифри, трябва или да запазите низа, или броя на цифрите. След като бъде променена на цифрова стойност от текстово представяне, начинът, по който е въведен, се губи.

person zaph    schedule 15.03.2015

Не знам повече за вашия потребителски интерфейс, но трябва да използвате NSNumber и NSNumberFormatter

Първо вземете въведеното от потребителя като число от низа за въвеждане с помощта на основен NSNumberformatter. Номерът ще бъде съхранен така, както е бил въведен (напр. "1.23" се съхранява като 1.23, "6.3" се съхранява като 6.3):

NSString *inputstring = inputTextField.text;
NSNumberFormatter * inputFormatter = [NSNumberFormatter new];
NSNumber * inputNumber = [inputFormatter numberFromString:inputstring];

Второ, когато показвате числото, използвайте по-прецизно NSNumberFormatter, за да ограничите броя на десетичните знаци:

NSNumberFormatter *outputFormatter = [[NSNumberFormatter alloc]init];
outputFormatter.locale = [NSLocale currentLocale];     // make sure to show the number with the local setting of the device!
outputFormatter.numberStyle = NSNumberFormatterDecimalStyle;
outputFormatter.usesGroupingSeparator = YES;           // your choice...
outputFormatter.groupingSize = 3;
outputFormatter.maximumFractionDigits = 2;             // <-- here you limit the number of decimal places

и покажете номера, локализиран в етикет, текстово поле или каквото и да било:

outputLabel.text = [NSString localizedStringWithFormat:@"%@", [outputFormatter stringForObjectValue:inputNumber]];

Това ще ограничи изхода до макс. 2 знака след десетичната запетая, но също така ще покаже не повече знаци след десетичната запетая, отколкото въвежда потребителят.

person JFS    schedule 26.03.2015
comment
Това ми помогна много в обратния смисъл: преобразуване на низ с различни разделители (десетичен/група) в NSDecimalNumber. - person Mike Lischke; 09.06.2015

Можете да приложите потребителски подклас на NSFormatter. Той ще използва низове като стойност на обекта, за да запази точно въведеното от потребителя. Вашият модел също ще трябва да съхранява стойностите като низове, ако трябва да запазите точно това, което потребителят е въвел. Както Zaph посочи, ако преобразувате в числов скаларен тип (напр. double) или в NSNumber, точният характер на въведеното от потребителя се губи.

Можете или сами да приложите методите за валидиране на NSFormatter, или вашият персонализиран форматиращ клас ще използва (а не наследява) NSNumberFormatter и ще го използва, за да валидира входа (без вашия форматиращ изход NSNumbers ). Ако сами прилагате валидиране, трябва да внимавате за локала. Например, като използвате подходящия десетичен разделител за локала.

Реализацията на -stringForObjectValue: от вашия клас ще върне копие на входа (автоматично освободено, ако не използвате ARC).

Неговата реализация на -getObjectValue:forString:errorDescription: ще провери дали текущият низ е валиден. Ако не, ще върне NO. Ако сами прилагате валидиране, ще напишете този код. Ако използвате NSNumberFormatter, ще декларирате променлива NSNumber* и ще извикате същия метод на вашия екземпляр на форматиране на номера, като предавате адреса на вашата променлива NSNumber* като обект, който да получите. Ако върне NO, вашият метод трябва да върне NO. Ако върне YES, задайте *anObject на копие на string (автоматично освободено, ако не използвате ARC) и върнете YES.

Ако искате проверка на частични низове, заменете -isPartialStringValid:proposedSelectedRange:originalString:originalSelectedRange:errorDescription:. Ако прилагате валидиране сами, вие пишете кода. Ако използвате NSNumberFormatter, обадете се на вашия екземпляр за форматиране на номера. Вярвам, че трябва да сте задали partialStringValidationEnabled на обекта за форматиране на числа, когато го настройвате.

person Ken Thomases    schedule 15.03.2015