cocoa - Restringir NSTextField para permitir solo números
(9)
¿Cómo restrinjo un campo NSTextfield
para permitir solo números / enteros? He encontrado preguntas como esta, ¡pero no me ayudaron!
Aquí están los pasos para crear lo mismo ....
Simplemente cree ANYCLASS (llamado SAMPLE) con una subclasificación de NSNumberFormatter ...
en el archivo .m escriba el siguiente código ...
- (BOOL)isPartialStringValid:(NSString *)partialString newEditingString:(NSString **)newString errorDescription:(NSString **)error {
// Make sure we clear newString and error to ensure old values aren''t being used
if (newString) { *newString = nil;}
if (error) {*error = nil;}
static NSCharacterSet *nonDecimalCharacters = nil;
if (nonDecimalCharacters == nil) {
nonDecimalCharacters = [[NSCharacterSet decimalDigitCharacterSet] invertedSet] ;
}
if ([partialString length] == 0) {
return YES; // The empty string is okay (the user might just be deleting everything and starting over)
} else if ([partialString rangeOfCharacterFromSet:nonDecimalCharacters].location != NSNotFound) {
return NO; // Non-decimal characters aren''t cool!
}
return YES;
}
Ahora ... en su clase real establezca el formateador en su objeto NSTextField como a continuación ...
NSTextField *mySampleTxtFld;
para esto se configura el formateador ...
SAMPLE* formatter=[[SAMPLE alloc]init];// create SAMPLE FORMATTER OBJECT
self.mySampleTxtFld.delegate=self;
[self.mySampleTxtFld setFormatter:formatter];
¡¡¡Terminaste!!!
Aquí hay una solución con el filtrado. Dé un delegado y una salida al campo de texto y configure el método controlTextDidChange.
- (void)controlTextDidChange:(NSNotification *)aNotification {
NSTextField *textfield = [notification object];
NSCharacterSet *charSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
char *stringResult = malloc([textfield.stringValue length]);
int cpt=0;
for (int i = 0; i < [textfield.stringValue length]; i++) {
unichar c = [textfield.stringValue characterAtIndex:i];
if ([charSet characterIsMember:c]) {
stringResult[cpt]=c;
cpt++;
}
}
stringResult[cpt]=''/0'';
textfield.stringValue = [NSString stringWithUTF8String:stringResult];
free(stringResult);
}
Aquí hay una versión Swift:
override func isPartialStringValid(partialString: String, newEditingString newString: AutoreleasingUnsafeMutablePointer<NSString?>, errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>) -> Bool {
if (count(partialString.utf16)) {
return true
}
if (partialString.rangeOfCharacterFromSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet) != nil) {
NSBeep()
return false
}
return true
}
En SWIFT, lo hago así.
- Convierta el valor del texto a Int con Int ()
- Compruebe que el valor convertido no es inferior a 0
Si es inferior a 0, muestra el mensaje de error y acepta el valor
if ((Int(txtField.stringValue)) < 0){ // Display error message }
Intente crear su propia subclase NSNumberFormatter
y verifique el valor de entrada en -isPartialStringValid:newEditingString:errorDescription:
method.
@interface OnlyIntegerValueFormatter : NSNumberFormatter
@end
@implementation OnlyIntegerValueFormatter
- (BOOL)isPartialStringValid:(NSString*)partialString newEditingString:(NSString**)newString errorDescription:(NSString**)error
{
if([partialString length] == 0) {
return YES;
}
NSScanner* scanner = [NSScanner scannerWithString:partialString];
if(!([scanner scanInt:0] && [scanner isAtEnd])) {
NSBeep();
return NO;
}
return YES;
}
@end
Y luego configure este formateador en su NSTextField
:
OnlyIntegerValueFormatter *formatter = [[[OnlyIntegerValueFormatter alloc] init] autorelease];
[textField setFormatter:formatter];
Prueba esto -
NSNumberFormatter *formatter = [[[NSNumberFormatter alloc] init] autorelease];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[textField setFormatter:formatter];
Swift 2.0 formateador personalizado con 0 en lugar de espacio vacío:
class OnlyIntegerValueFormatter: NSNumberFormatter {
override func isPartialStringValid(partialString: String, newEditingString newString: AutoreleasingUnsafeMutablePointer<NSString?>, errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>) -> Bool {
if partialString.isEmpty {
newString.memory = "0"
return false
}
if Int(partialString) < 0 {
NSBeep()
return false
} else {
return true
}
}
}
Versión Swift 3
import Foundation
class OnlyIntegerValueFormatter: NumberFormatter {
override func isPartialStringValid(_ partialString: String, newEditingString newString: AutoreleasingUnsafeMutablePointer<NSString?>?, errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>?) -> Bool {
// Ability to reset your field (otherwise you can''t delete the content)
// You can check if the field is empty later
if partialString.isEmpty {
return true
}
// Optional: limit input length
/*
if partialString.characters.count>3 {
return false
}
*/
// Actual check
return Int(partialString) != nil
}
}
Utilizar:
let onlyIntFormatter = OnlyIntegerValueFormatter()
myNsTextField.formatter = onlyIntFormatter
[Funciona con Swift 3.0.1]
Como otros sugirieron, la subclase NumberFormatter
y la anulación isPartialStringValid
método isPartialStringValid
. La forma más sencilla es colocar un objeto NumberFormatter
debajo de su NSTextField
en xib / storyboard y actualizar su Custom Class
. La siguiente implementación solo permite valores enteros o en blanco y emite un pitido si la cadena contiene caracteres no válidos.
class IntegerFormatter: NumberFormatter {
override func isPartialStringValid(_ partialString: String, newEditingString newString: AutoreleasingUnsafeMutablePointer<NSString?>?, errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>?) -> Bool {
// Allow blank value
if partialString.numberOfCharacters() == 0 {
return true
}
// Validate string if it''s an int
if partialString.isInt() {
return true
} else {
NSBeep()
return false
}
}
}
isInt()
numberOfCharacters()
y isInt()
son métodos agregados en una extensión.
extension String {
func isInt() -> Bool {
if let intValue = Int(self) {
if intValue >= 0 {
return true
}
}
return false
}
func numberOfCharacters() -> Int {
return self.characters.count
}
}