Каков наилучший способ ввода числовых значений с десятичными точками? - PullRequest
51 голосов
/ 09 ноября 2008

В моем приложении пользователи должны иметь возможность вводить числовые значения с десятичными знаками. В iPhone нет клавиатуры, специально предназначенной для этой цели, - только цифровая клавиатура и клавиатура с цифрами и символами.

Существует ли простой способ использовать последнее и предотвратить ввод любых нечисловых значений без необходимости повторного выражения конечного результата?

Спасибо!

Ответы [ 11 ]

53 голосов
/ 13 февраля 2011

Я думаю, что было бы хорошо отметить, что начиная с iOS 4.1 вы можете использовать новую UIKeyboardTypeDecimalPad.

Так что теперь вам просто нужно:

myTextField.keyboardType=UIKeyboardTypeDecimalPad;
49 голосов
/ 26 ноября 2008

Более элегантное решение бывает и самым простым.

Вам не нужен десятичный разделитель

Почему? Потому что вы можете просто сделать вывод из ввода пользователя. Например, в локали США, когда вы вводите $ 1,23, вы начинаете с ввода чисел 1-2-3 (в таком порядке). В системе при вводе каждого символа это будет распознаваться как:

  • пользователь вводит 1: $ 0,01
  • пользователь вводит 2: $ 0,12
  • пользователь вводит 3: $ 1,23

Обратите внимание, как мы вывели десятичный разделитель на основе ввода пользователя. Теперь, если пользователь хочет ввести $ 1,00, он просто введет цифры 1-0-0.

Чтобы ваш код мог обрабатывать валюты другой локали, вам необходимо получить максимальные дробные цифры валюты. Это можно сделать с помощью следующего фрагмента кода:

NSNumberFormatter *currencyFormatter = [[NSNumberFormatter alloc] init];
[currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
int currencyScale = [currencyFormatter maximumFractionDigits];

Например, максимальная дробная цифра в японской иене равна 0. Таким образом, при работе с вводом иены десятичный разделитель отсутствует и, следовательно, нет необходимости беспокоиться о дробных величинах.

Такой подход к проблеме позволяет использовать стандартную цифровую клавиатуру ввода, предоставляемую Apple, без головной боли от пользовательских клавиатур, проверки регулярных выражений и т. Д.

12 голосов
/ 14 апреля 2010

Вот пример решения, предложенного в принятом ответе. Это не касается других валют или чего-либо еще - в моем случае мне нужна была только поддержка долларов, независимо от локали / валюты, поэтому для меня все было в порядке:

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range
    replacementString:(NSString *)string {

    double currentValue = [textField.text doubleValue];
    //Replace line above with this
    //double currentValue = [[textField text] substringFromIndex:1] doubleValue];
    double cents = round(currentValue * 100.0f);

    if ([string length]) {
        for (size_t i = 0; i < [string length]; i++) {
            unichar c = [string characterAtIndex:i];
            if (isnumber(c)) {
                cents *= 10;
                cents += c - '0'; 
            }            
        }
    } else {
        // back Space
        cents = floor(cents / 10);
    }

    textField.text = [NSString stringWithFormat:@"%.2f", cents / 100.0f];
    //Add this line
    //[textField setText:[NSString stringWithFormat:@"$%@",[textField text]]];
    return NO;
}

Важны округления и этажи а) из-за того, что представление с плавающей запятой иногда теряет .00001 или что-то еще, и б) строка формата округляет любую точность, которую мы удалили в части возврата.

3 голосов
/ 11 ноября 2008

Я хотел сделать то же самое, за исключением валют, а не прямых десятичных значений.

В итоге я создал собственное представление, которое содержит UITextField и UILabel. Метка покрывает текстовое поле, но текстовое поле все еще получает прикосновения. Я использую уведомление UITextFieldTextDidChange, чтобы наблюдать изменения в текстовом поле (и я использовал NSNumberFormatter, чтобы превратить полученное число в форматированное значение валюты), чтобы обновить метку.

Чтобы отключить лупу, которая позволяет пользователю перемещать точку вставки, вам нужно использовать пользовательский подкласс UITextField и переопределить touchesBegan: withEvent: и установить для него ничего не делать.

Мое решение может отличаться от того, что вам нужно, потому что десятичная точка всегда фиксирована - я использую настройку валюты системы, чтобы определить, сколько цифр должно быть после десятичной точки. Однако цифровая клавиатура не имеет десятичной точки. И вы не можете добавить какие-либо кнопки на клавиатуру (что особенно отягчает, потому что в левом нижнем углу клавиатуры есть пустая кнопка, которая была бы идеальной для десятичной точки!) Так что у меня нет решения для этого К сожалению.

2 голосов
/ 11 мая 2010

Я построил пользовательский контроллер представления цифровой клавиатуры с десятичной запятой ... посмотрите:

http://sites.google.com/site/psychopupnet/iphone-sdk/tenkeypadcustom10-keypadwithdecimal

2 голосов
/ 10 ноября 2008

Вы можете использовать ползунок (как было предложено Мартином против Лёвиса) или UIPickerView с отдельным колесом для каждой из цифр.

2 голосов
/ 09 ноября 2008

В зависимости от конкретного приложения, на слайдере iphone лучше выбрать ползунок, из которого пользователь может выбрать позицию. Тогда вообще не нужно вводить цифры.

1 голос
/ 07 февраля 2011

Вот как это сделать, не используя float, round () или ceil () независимо от валюты.

В вашем контроллере установите следующие переменные экземпляра (с соответствующими операторами @property, если это ваша сумка):

@interface MyViewController : UIViewController <UITextFieldDelegate> {
@private
    UITextField *firstResponder;
    NSNumberFormatter *formatter;
    NSInteger currencyScale;
    NSString *enteredDigits;
}

@property (nonatomic, readwrite, assign) UITextField *firstResponder;
@property (nonatomic, readwrite, retain) NSNumberFormatter *formatter;
@property (nonatomic, readwrite, retain) NSString *enteredDigits;

@end

и ваш метод viewDidLoad должен содержать следующее:

- (void)viewDidLoad {
    [super viewDidLoad];

    NSNumberFormatter *aFormatter = [[NSNumberFormatter alloc] init];
    [aFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
    currencyScale = -1 * [aFormatter maximumFractionDigits];
    self.formatter = aFormatter;
    [aFormatter release];
}

Затем реализуйте ваши методы UITextFieldDelegate следующим образом:

#pragma mark -
#pragma mark UITextFieldDelegate methods

- (void)textFieldDidBeginEditing:(UITextField *)textField {
    // Keep a pointer to the field, so we can resign it from a toolbar
    self.firstResponder = textField;
    self.enteredDigits = @"";
}

- (void)textFieldDidEndEditing:(UITextField *)textField {
    if ([self.enteredDigits length] > 0) {
        // Get the amount
        NSDecimalNumber *result = [[NSDecimalNumber decimalNumberWithString:self.enteredDigits] decimalNumberByMultiplyingByPowerOf10:currencyScale];
        NSLog(@"result: %@", result);
    }
}

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {

    // Check the length of the string
    if ([string length]) {
        self.enteredDigits = [self.enteredDigits stringByAppendingFormat:@"%d", [string integerValue]];
    } else {
        // This is a backspace
        NSUInteger len = [self.enteredDigits length];
        if (len > 1) {
            self.enteredDigits = [self.enteredDigits substringWithRange:NSMakeRange(0, len - 1)];
        } else {
            self.enteredDigits = @"";
        }
    }

    NSDecimalNumber *decimal = nil;

    if ( ![self.enteredDigits isEqualToString:@""]) {
        decimal = [[NSDecimalNumber decimalNumberWithString:self.enteredDigits] decimalNumberByMultiplyingByPowerOf10:currencyScale];
    } else {
        decimal = [NSDecimalNumber zero];
    }

    // Replace the text with the localized decimal number
    textField.text = [self.formatter stringFromNumber:decimal];

    return NO;  
}

Проверял это только в фунтах и ​​пенсов, но это должно работать и с японской иеной. Если вы хотите отформатировать десятичные числа для не валютных целей, просто прочитайте документацию по NSNumberFormatter и установите любой формат / MaximumFractionDigits, который вы хотите.

1 голос
/ 10 ноября 2010

Начиная с iOS4.1, появился новый тип клавиатуры UIKeyboardTypeNumberPad, но, к сожалению, на данный момент его нет в списке выбора Interface Builder.

0 голосов
/ 16 февраля 2016

Вы можете использовать STATextField и установить для currencyRepresentation значение YES, которое:

Гарантирует, что введено не более одной десятичной точки и что не более 2 цифр вводится справа от указанной десятичной точки.

Также имеется STAATMTextField , который поддерживает валютный режим и Ввод текста банкомата по умолчанию:

Предоставляет текстовое поле, имитирующее поведение ввода банкомата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...