Подтвердить что ты не робот

Каков наилучший способ ввода числовых значений с десятичными точками?

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

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

Спасибо!

4b9b3361

Ответ 1

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

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

Почему? Потому что вы можете просто вывести его из пользовательского ввода. Например, в локали США, когда вам нужно ввести $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, без головных болей пользовательских клавиатур, проверки правильности и т.д.

Ответ 2

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

Итак, теперь вам просто нужно:

myTextField.keyboardType=UIKeyboardTypeDecimalPad;

Ответ 3

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

-(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 или что-то еще, и б) строки формата, округляющей любую точность, которую мы удалили в области backspace.

Ответ 4

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

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

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

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

Ответ 5

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

Ответ 6

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

Ответ 8

Как и в iOS4.1, есть новый тип клавиатуры UIKeyboardTypeNumberPad, но, к сожалению, пока он не появляется в списке выбора Interface Builder.

Ответ 9

Здесь, как это сделать, не используя 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 и установите format/maximumFractionDigits, который вы хотите.

Ответ 10

A Swift 2 реализация сообщения Майка Уэллера, а также только USD:

 func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    guard let str = textField.text else {
        textField.text = "0.00"
        return false
    }

    let value = (str as NSString).doubleValue

    var cents = round(value * 100)
    if string.characters.count > 0 {
        for c in string.characters {
            if let num = Int(String(c)) {
                cents *= 10
                cents += Double(num)
            }
        }
    }
    else {
        cents = floor(cents / 10)
    }

    textField.text = NSString(format: "%.2f", cents/100) as String

    return false
}

Ответ 11

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

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

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

Предоставляет текстовое поле, которое имитирует поведение входа в систему ATM.