www tradusir traductor traducir spanishdict oraciones online introductor inglés ingles gratis frases español convertidor como cocoa cocoa-touch uitextfield currency

cocoa - traductor - tradusir en ingles



Luchando con la moneda en Cocoa (7)

Aquí está el plan de ataque aproximado que usaría si tuviera que escribir eso ahora. El truco será tipear en un UITextField oculto y actualizar un UILabel con el valor formateado a medida que el usuario escribe.

  1. Cree un UITextField, hágalo oculto, asígnelo un delegado y luego conviértalo en el primer respondedor que convoque el teclado.
  2. En su delegado, responda al mensaje textDidChange: (demasiado vago para buscar el nombre exacto) tomando el nuevo valor del campo de texto y convirtiéndolo en un número. Asegúrese de que la cadena vacía se convierta en cero.
  3. Ejecute el número a través de su formateador y actualice un UILabel con ese valor de moneda formateado.

En cada pulsación de tecla, la etiqueta se actualizará, por lo que el usuario sentirá que está editando el valor formateado, cuando realmente está editando el campo de texto oculto. ¡Qué astuto!

Estoy tratando de hacer algo que creo sería bastante simple: dejar que un usuario ingrese una cantidad en dólares, almacenar esa cantidad en un NSNumber (NSDecimalNumber?), Luego mostrar esa cantidad formateada como moneda de nuevo en algún momento posterior.

Mi problema no es tanto con setNumberStyle: NSNumberFormatterCurrencyStyle y mostrar carrozas como moneda. El problema está más en cómo dicho numberFormatter funciona con este UITextField. Puedo encontrar algunos ejemplos. Este hilo de noviembre y este me dan algunas ideas pero me deja con más preguntas.

Estoy usando el teclado UIKeyboardTypeNumberPad y entiendo que probablemente debería mostrar $ 0.00 (o cualquier formato de moneda local) en el campo en la pantalla y luego, cuando el usuario ingrese los números para desplazar el lugar decimal a lo largo:

  • Comience con pantalla $ 0.00
  • Tecla 2: mostrar $ 0.02
  • Toque la tecla 5: mostrar $ 0.25
  • Toque la tecla 4: visualizar $ 2.54
  • Toque la tecla 3: mostrar $ 25.43

Entonces [numberFormatter numberFromString: textField.text] debería darme un valor que pueda almacenar en mi variable NSNumber.

Tristemente todavía estoy luchando: ¿Es esta la mejor / la mejor manera? Si es así, ¿entonces alguien puede ayudarme con la implementación? Siento que UITextField puede necesitar que un delegado responda cada pulsación de tecla, pero no está seguro de qué, dónde y cómo implementarlo. ¿Algún código de muestra? ¡Lo agradecería muchísimo! He buscado alto y bajo ...

Edit1: entonces estoy buscando en NSFormatter''s stringForObjectValue: y lo más cercano que puedo encontrar a lo que recomienda benzado : UITextViewTextDidChangeNotification . Tener dificultades para encontrar el código de muestra en cualquiera de ellos ... así que avíseme si sabe dónde buscar.


Bueno, esto es un poco tarde, pero de todos modos pensé que podría intentarlo. Esta es probablemente más una solución y puede ser un código desordenado, pero funcionó para mí. Conecté una etiqueta y un campo de texto oculto en IB, y escribí este código usando el delegado UITextFieldDelegate.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { if (textField == fineHiddenTextField) { NSString *fineText = [textField.text stringByReplacingCharactersInRange:range withString:string]; if ([fineText length] == 0) { NSString *emptyFine = @"0.00"; float fineValue = [emptyFine floatValue]; fineEntryLabel.text = [NSString stringWithFormat:@"%.2f", fineValue]; } else if ([fineText length] == 1) { NSString *firstDec = [NSString stringWithFormat:@"0.0%@", fineText]; float fineValue = [firstDec floatValue]; fineEntryLabel.text = [NSString stringWithFormat:@"%.2f", fineValue]; } else if ([fineText length] == 2) { NSString *secondDec = [NSString stringWithFormat:@"0.%@", fineText]; float fineValue = [secondDec floatValue]; fineEntryLabel.text = [NSString stringWithFormat:@"%.2f", fineValue]; } else { int decimalPlace = [fineText length] - 2; NSString *fineDollarAmt = [fineText substringToIndex:decimalPlace]; NSString *fineCentsAmt = [fineText substringFromIndex:decimalPlace]; NSString *finalFineValue = [NSString stringWithFormat:@"%@.%@", fineDollarAmt, fineCentsAmt]; float fineValue = [finalFineValue floatValue]; fineEntryLabel.text = [NSString stringWithFormat:@"%.2f", fineValue]; } //fineEntryLabel.text = [NSString stringWithFormat:@"%.2f", fineValue]; return YES; } }

No es exactamente lo mejor, pero realmente hizo el trabajo. La declaración if inicial era solo para asegurarse de que esto solo ocurría para este campo de texto en particular (ya que hay varios en la misma página). Este código estaba destinado a la entrada de dinero (la cantidad de una multa pagada) y yo quería es simple y fácil de usar Simplemente configure su etiqueta para alinearla desde la derecha, y debería hacerlo.

Estoy un poco conectado con el café en este momento, pero responderé cualquier pregunta que pueda tener. :)


¡Aquí está mi solución!

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{ float valorUnit = [textField.text floatValue]; if( string.length > 0) { float incremento = [string floatValue]; valorUnit = valorUnit * 10.f + (incremento/100.f); NSString* strVal = [NSString stringWithFormat:@"%f", valorUnit]; if (valorUnit > 0.f && valorUnit < 10.f) { textField.text = [strVal substringToIndex:3]; } else if (valorUnit < 100.f && valorUnit >= 10.f) { textField.text = [strVal substringToIndex:4]; } else if (valorUnit >=100.f && valorUnit <1000.f) { textField.text = [strVal substringToIndex:5]; } else { return NO; } } else { valorUnit = (valorUnit/10.f); NSString* strVal = [NSString stringWithFormat:@"%f", valorUnit]; if (valorUnit > 0.f && valorUnit < 10.f) { textField.text = [strVal substringToIndex:5]; } else if (valorUnit < 100.f && valorUnit >= 10.f) { textField.text = [strVal substringToIndex:6]; } else if (valorUnit >=100.f && valorUnit <1000.f) { textField.text = [strVal substringToIndex:7]; } else { return NO; } } return YES;

}


Bueno, creo que esto es mejor:

- (void)viewWillDisappear:(BOOL)animated{ [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil]; } -(void)viewDidAppear:(BOOL)animated{ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChanged:) name:UITextFieldTextDidChangeNotification object:nil]; } -(void)textDidChanged:(NSNotification *)notification{ [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil]; UITextField * textField= [notification object]; NSString * sinPesos= [textField.text stringByReplacingOccurrencesOfString:@"$" withString:@""]; NSString * sinPuntos= [sinPesos stringByReplacingOccurrencesOfString:@"." withString:@""]; float monto = [sinPuntos floatValue]; monto= monto/100; NSString * cardText= [[self montoFormatter] stringFromNumber:[NSNumber numberWithDouble:monto]]; textField.text = ([cardText isEqualToString: @"0"] ? @"":cardText); [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChanged:) name:UITextFieldTextDidChangeNotification object:nil]; } -(NSNumberFormatter *)montoFormatter{ NSNumberFormatter* numberFormatter = [[NSNumberFormatter alloc] init]; [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle]; [numberFormatter setMaximumFractionDigits:2]; return [numberFormatter autorelease]; }

Pruébalo :)


Mi solución:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { // Clear all characters that are not numbers // (like currency symbols or dividers) NSString *cleanCentString = [[textField.text componentsSeparatedByCharactersInSet: [[NSCharacterSet decimalDigitCharacterSet] invertedSet]] componentsJoinedByString:@""]; // Parse final integer value NSInteger centAmount = cleanCentString.integerValue; // Check the user input if (string.length > 0) { // Digit added centAmount = centAmount * 10 + string.integerValue; } else { // Digit deleted centAmount = centAmount / 10; } // Update call amount value [_amount release]; _amount = [[NSNumber alloc] initWithFloat:(float)centAmount / 100.0f]; // Write amount with currency symbols to the textfield NSNumberFormatter *_currencyFormatter = [[NSNumberFormatter alloc] init]; [_currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle]; [_currencyFormatter setCurrencyCode:@"USD"]; [_currencyFormatter setNegativeFormat:@"-¤#,##0.00"]; textField.text = [_currencyFormatter stringFromNumber:_amount]; [_currencyFormatter release] // Since we already wrote our changes to the textfield // we don''t want to change the textfield again return NO; }


Como soy flojo y no soporto que mi información de entrada sea reformateada "para ayudarme" sobre la marcha, digo:

Solo déjalos ingresar un número decimal. Cuando abandonen el campo, vuelva a formatearlo.


Escribí una subclase UITextField código abierto para manejar esto, disponible aquí:

https://github.com/TomSwift/TSCurrencyTextField

El enfoque que tomé es similar a lo que sugiere Lars Schneider en su popular respuesta. Pero mi versión está completamente encapsulada en un componente reutilizable que puede usar en cualquier lugar, al igual que UITextField. Si elige implementar cualquier método UITextFieldDelegate, puede hacerlo, pero esto no es obligatorio.