SWIFT: Nstextfield allow only specified characters
First add a NSTextFieldDelegate to your class... and then
add this :
override func controlTextDidChange(obj: NSNotification) {
let characterSet: NSCharacterSet = NSCharacterSet(charactersInString: " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLKMNOPQRSTUVWXYZ0123456789-_").invertedSet
self.textField.stringValue = (self.textField.stringValue.componentsSeparatedByCharactersInSet(characterSet) as NSArray).componentsJoinedByString("")
}
you have to replace self.textfield with your own textfield which you want to control.
SWIFT 4 Edit
override func controlTextDidChange(_ obj: Notification) {
let characterSet: NSCharacterSet = NSCharacterSet(charactersIn: " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLKMNOPQRSTUVWXYZ0123456789-_").inverted as NSCharacterSet
self.textField.stringValue = (self.textField.stringValue.components(separatedBy: characterSet as CharacterSet) as NSArray).componentsJoined(by: "")
}
Restrict NSTextField to only allow numbers
Try to make your own NSNumberFormatter
subclass and check the input value in -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
And then set this formatter to your NSTextField
:
OnlyIntegerValueFormatter *formatter = [[[OnlyIntegerValueFormatter alloc] init] autorelease];
[textField setFormatter:formatter];
Restrict input on NSTextField
You have complete control with a subclass of NSFormatter
. I'm not sure why you think you don't.
Override isPartialStringValid(_:proposedSelectedRange:originalString:originalSelectedRange:errorDescription:)
and implement the desired logic. From the docs (with some minor edits by me):
In a subclass implementation, evaluate [the string pointed to by
*partialStringPtr
] according to the context. ReturnYES
ifpartialStringPtr
is acceptable andNO
ifpartialStringPtr
is unacceptable. Assign a new string topartialStringPtr
and a new range toproposedSelRangePtr
and returnNO
if you want to replace the string and change the selection range.
So, if the user tries to insert disallowed characters, you can either reject their edit in its entirety or modify it to strip those disallowed characters. (Remember that user changes can include pasting, so it's not necessarily just a single typed character.) To reject the change entirely, assign origString
to *partialStringPtr
and origSelRange
to *proposedSelRangePtr
.
How can I restrict special characters in UITextField except dot and underscores?
Try code block given below, it worked fine for me.
SWIFT 3.0
let ACCEPTABLE_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let cs = NSCharacterSet(charactersIn: ACCEPTABLE_CHARACTERS).inverted
let filtered = string.components(separatedBy: cs).joined(separator: "")
return (string == filtered)
}
Objective C
#define ACCEPTABLE_CHARACTERS @" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_."
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:ACCEPTABLE_CHARACTERS] invertedSet];
NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
return [string isEqualToString:filtered];
}
Hope it will work for you as well.
Force a NStextField to only accept Hex values
See this answer for a much better explanation, but it would be something like:
- (void)controlTextDidChange:(NSNotification *)aNotification {
NSError *outError;
NSControl *textField = [aNotification object];
NSString *myText = [textField stringValue];
// check if myText is 0-9 or a-f, do something with it if its not hex.
// update the NSNextField with the validated text
[postingObject setStringValue:myText];
}
Allow only alphanumeric characters for a UITextField
Use the UITextFieldDelegate method -textField:shouldChangeCharactersInRange:replacementString:
with an NSCharacterSet containing the inverse of the characters you want to allow. For example:
// in -init, -initWithNibName:bundle:, or similar
NSCharacterSet *blockedCharacters = [[[NSCharacterSet alphanumericCharacterSet] invertedSet] retain];
- (BOOL)textField:(UITextField *)field shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)characters
{
return ([characters rangeOfCharacterFromSet:blockedCharacters].location == NSNotFound);
}
// in -dealloc
[blockedCharacters release];
Note that you’ll need to declare that your class implements the protocol (i.e. @interface MyClass : SomeSuperclass <UITextFieldDelegate>
) and set the text field’s delegate
to the instance of your class.
How to limit NSTextField text length and keep it always upper case?
I did as Graham Lee suggested and it works fine, here's the custom formatter code:
UPDATED: Added fix reported by Dave Gallagher. Thanks!
@interface CustomTextFieldFormatter : NSFormatter {
int maxLength;
}
- (void)setMaximumLength:(int)len;
- (int)maximumLength;
@end
@implementation CustomTextFieldFormatter
- (id)init {
if(self = [super init]){
maxLength = INT_MAX;
}
return self;
}
- (void)setMaximumLength:(int)len {
maxLength = len;
}
- (int)maximumLength {
return maxLength;
}
- (NSString *)stringForObjectValue:(id)object {
return (NSString *)object;
}
- (BOOL)getObjectValue:(id *)object forString:(NSString *)string errorDescription:(NSString **)error {
*object = string;
return YES;
}
- (BOOL)isPartialStringValid:(NSString **)partialStringPtr
proposedSelectedRange:(NSRangePointer)proposedSelRangePtr
originalString:(NSString *)origString
originalSelectedRange:(NSRange)origSelRange
errorDescription:(NSString **)error {
if ([*partialStringPtr length] > maxLength) {
return NO;
}
if (![*partialStringPtr isEqual:[*partialStringPtr uppercaseString]]) {
*partialStringPtr = [*partialStringPtr uppercaseString];
return NO;
}
return YES;
}
- (NSAttributedString *)attributedStringForObjectValue:(id)anObject withDefaultAttributes:(NSDictionary *)attributes {
return nil;
}
@end
Disable Alphabetic Characters in a Text Field (Part of my code will not execute)
The reason your function does not work is that it makes its decision early for both the positive and the negative case.
Defer returning true
to the very end of the function:
if existingTextHasDecimalSeparator != nil && replacementTextHasDecimalSeparator != nil {
// Do not allow multiple decimal separators
return false
}
if replacementTextHasLetter != nil {
// Do not allow letters
return false
}
return true
This reflects the all-or-nothing logic of the decision: all checks must succeed in order to all checks, while it takes only one failed check to reject the change.
Related Topics
Adding Animation to Tabviews in Swiftui When Switching Between Tabs
How to Capture Multiple Arguments Weakly in a Swift Closure
Firebase Crashlytics Not Showing Crash Report in Console Dashboard Swift
Manually Disposing a Disposebag in Rxswift
How to Trigger Xcode's 'Update to Latest Package Versions' from Command Line
Integer Literal Overflows When Stored into 'Int'
Swift Unit Testing with Xctassertthrows Analogue
Nssortdescriptor Sorting Using Nsdate in Swift
Convert String to Staticstring
Changing Tab Bar Color (Swift)
Xcode 7 Run on MAC Osx 10.10 Yosemite
Bringing iOS Frameworks Through Carthage in Xcode 12.0
Convert Optional String to Int in Swift
How to Insert a Sublayer in Swift