12

ユーザーからの数値入力のみを受け取ることになってUITextFieldいるアプリケーションに があります。この数値入力は、通貨を表す (つまり、小数点以下 2 桁のみ) と想定されており、何も入力されていない場合のデフォルト値は0.00です。また、次のように数字が右から左に移動するように、左端に「$」記号を配置し、数字を右揃えにしたいと思います。

たとえば、数字「1234.56」を入力する場合。

1. $ 0.00 .

2. $0.01 .

3. $0.12 .

4. $1.23 .

5. $12.34 .

6. $123.45 .

7. $1,234.56 .

8. などなど…

すでに数字が右から左に移動するようにUITextField右揃えにしています。ただし、「$」をUITextField内に配置する必要があり、デフォルトの0.00値を、ユーザーが一度に 1 桁ずつ入力した数値に変更したいと考えています。ユーザーは小数点を入力する必要はありません。小数点はテキストフィールドに既に存在し、その位置を保持しているはずです。次に、数字に「,」を付けて、3桁ごとに区切って自動的に入力したいと思います。USER IS ENTERING THE NUMBERSとしてアプリケーションにこれを実行させ、後ですべてを入力したときにフォーマットしないようにしたいと思います。どうすればいいですか?私は多くの人が私が使うべきだと言っているのを見てきましたNSNumberFormatterUITextField、しかし、上記のように、数値テキストをオンザフライでフォーマットするなどと組み合わせて使用​​する方法を知りたいですか?

少し前に StackOverflow に投稿された次の質問を見つけました。

小数点を含む数値を入力する最良の方法は何ですか?

しかし、私の問題の解決策として実際に組み込む方法を知りたいです。

4

5 に答える 5

15

ここにそれを行うための良い方法があります。viewDidLoad メソッドで UITextField を self に設定することを忘れないでください。ヘッダー ファイルは UITextFieldDelegate プロトコルに準拠する必要があります。

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

    NSString *cleanCentString = [[textField.text componentsSeparatedByCharactersInSet: [[NSCharacterSet decimalDigitCharacterSet] invertedSet]] componentsJoinedByString:@""];
    NSInteger centValue = [cleanCentString intValue];
    NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
    NSNumber *myNumber = [f numberFromString:cleanCentString];
    NSNumber *result;

    if([textField.text length] < 16){
        if (string.length > 0)
        {
            centValue = centValue * 10 + [string intValue];
            double intermediate = [myNumber doubleValue] * 10 +  [[f numberFromString:string] doubleValue];
           result = [[NSNumber alloc] initWithDouble:intermediate];
        }
        else
        {
            centValue = centValue / 10;
            double intermediate = [myNumber doubleValue]/10;
            result = [[NSNumber alloc] initWithDouble:intermediate];
        }

        myNumber = result;
         NSLog(@"%ld ++++ %@", (long)centValue, myNumber);
            NSNumber *formatedValue;
            formatedValue = [[NSNumber alloc] initWithDouble:[myNumber doubleValue]/ 100.0f];
            NSNumberFormatter *_currencyFormatter = [[NSNumberFormatter alloc] init];
            [_currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
            textField.text = [_currencyFormatter stringFromNumber:formatedValue];
            return NO;
    }else{

        NSNumberFormatter *_currencyFormatter = [[NSNumberFormatter alloc] init];
        [_currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
        textField.text = [_currencyFormatter stringFromNumber:00];

        UIAlertView *alert = [[UIAlertView alloc]initWithTitle: @"Deposit Amount Limit"
                                                       message: @"You've exceeded the deposit amount limit. Kindly re-input amount"
                                                      delegate: self
                                             cancelButtonTitle:@"Cancel"
                                             otherButtonTitles:@"OK",nil];

        [alert show];
        return NO;
    }
    return YES;
}
于 2014-06-21T14:48:09.840 に答える
3

これがSwiftでの私の解決策です。私のアプローチは、入力された数値を追跡し、それに0.01を掛けて、NSNumberFormatterを使用して小数点以下2桁で結果数値を設定することでした。テキストフィールドのキーボードをテンキーとして設定していることに注意してください。

amountTextfield?.keyboardType = UIKeyboardType.NumberPad

var amountTypedString = ""

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {

    let formatter = NSNumberFormatter()
    formatter.minimumFractionDigits = 2
    formatter.maximumFractionDigits = 2

    if string.characters.count > 0 {
        amountTypedString += string
        let decNumber = NSDecimalNumber(float: Float(amountTypedString)!).decimalNumberByMultiplyingBy(0.01)
        let newString = "$" + formatter.stringFromNumber(decNumber)!
        textfield.text = newString
    } else {
        amountTypedString = String(amountTypedString.characters.dropLast())
        if amountTypedString.characters.count > 0 {
            let decNumber = NSDecimalNumber(float: Float(amountTypedString)!).decimalNumberByMultiplyingBy(0.01)
            let newString = "$" +  formatter.stringFromNumber(decNumber)!
            textfield.text = newString
        } else {
            textfield.text = "$0.00"
        }

    }
    return false

}

func textFieldShouldClear(textField: UITextField) -> Bool {
    amountTypedString = ""
    return true
}
于 2016-04-14T18:24:28.500 に答える
1

UITextFieldDelegateおそらくプロトコルをチェックアウトする必要があります。何か (最も一般的には ViewController クラス) を UITextField のデリゲートとして割り当てることで、コントロールからインタラクティブなテキスト入力イベントを受け取ることができます。特に:

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

そのメソッドから NO を返すことにより、ユーザーが押したキーがテキスト フィールドに適用されないようにすることができます。

ただし、NO を返しても、デリゲート メソッドに渡された情報を使用して、コード内のテキスト フィールドの内容を独自に操作することを妨げるものは何もありません。

擬似コード形式:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if (string-contains-number) {
        alter textfield.text to be what it should be now, adding the number;
    }
    else {
        string contains something you don't wan the user typing, so ignore it.
    }

    // Tell iOS not to apply the user's change (since you just did by 
    // updating the text yourself:
    return NO;
}

免責事項: テストする実際のコードを書いていないため、このデリゲート メソッド内のコードを変更すると、別の shouldChangeCharactersInRange: メッセージが発生する可能性があります。しかし、そうではないと思います。コード内のテキストを変更すると、デリゲート イベントが発生するとは思いません。

これは明らかに、数値テキスト入力ボックスのすべてのルールをすでに実装しているカスタム コントロールほど優れていません (私は今、何年にもわたる Visual Basic プログラミングへのフラッシュバックを抱えています...)。しかし、誰かが書いてオープンソースにしたようなコントロールは知りません。

于 2013-03-05T07:41:56.770 に答える
0

私はジュリアンからの回答を受け取り、それを変更して、異なる通貨形式の他のロケールがサポートされるようにしました。また、再利用のために数値フォーマッターを保存したので、コストのかかる操作であるたびに数値フォーマッターが作成されることはありません。

オーバーフローは、格納された値がオーバーフローする原因となる入力を無視することによって処理されます。

このソリューションは、テキストがテキスト フィールドの最後にのみ入力されたことを前提としているため、入力前にテキスト カーソルがどこにあったかに関係なく、最後にのみ動作します。

let outputFormatter: NSNumberFormatter = {
    let formatter = NSNumberFormatter()
    formatter.numberStyle = .CurrencyStyle
    if formatter.maximumFractionDigits > 0 {
        formatter.multiplier = pow(10, -CGFloat(formatter.maximumFractionDigits))
    }
    return formatter
}()

let inputFormatter: NSNumberFormatter = {
    let formatter = NSNumberFormatter()
    formatter.numberStyle = .DecimalStyle
    return formatter
}()

private var value: UInt = 0

var currencyValue: NSDecimalNumber {
    let exponent = Int16(truncatingBitPattern: outputFormatter.maximumFractionDigits)
    return NSDecimalNumber(mantissa: UInt64(value), exponent: -exponent, isNegative: false)
}

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    if string.isEmpty {
        /* User pressed backspace, shift right one space. */
        value /= 10
    } else if let number = inputFormatter.numberFromString(string)?.unsignedIntegerValue {
        /* User entered a number, shift left one space and add. */
        let shiftedValue = UInt.multiplyWithOverflow(value, 10)
        let addedValue = UInt.addWithOverflow(shiftedValue.0, number)
        if !shiftedValue.overflow && !addedValue.overflow {
            value = addedValue.0
        }
    }

    textField.text = outputFormatter.stringFromNumber(NSDecimalNumber(unsignedInteger: value))
    return false
}

func textFieldShouldClear(textField: UITextField) -> Bool {
    value = 0
    return true
}

これをさまざまなロケールのプレイグラウンドで使用すると、これらの結果が得られました (申し訳ありませんが、まだ直接埋め込むことはできません)。

于 2016-04-27T04:10:54.683 に答える