Limit input to NSTextField
I want to restrict character input to NSTextField
, i.e. so that forbidden characters don't even appear. Most of what I have found on this topic are solutions that are only tested after completing text input or using NSFormatter
that still allows the character to be displayed.
So far I have come up with this solution, subclassing NSTextField
:
class RestrictedTextField : NSTextField
{
static let VALID_CHARACTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'-.& ";
override func textDidChange(notification:NSNotification)
{
for c in stringValue
{
if (RestrictedTextField.VALID_CHARACTERS.rangeOfString("\(c)") == nil)
{
stringValue = stringValue.stringByReplacingOccurrencesOfString("\(c)", withString: "", options: .LiteralSearch, range: nil);
break;
}
}
}
}
It works, but it's actually not optimal because the text cursor still moves one place if it tries to enter an invalid character. I also think that the loop is unnecessary, so I am wondering if anyone knows a more elegant solution for this?
source to share
You have complete control with the subclass NSFormatter
. I'm not sure why you think not.
Replace isPartialStringValid(_:proposedSelectedRange:originalString:originalSelectedRange:errorDescription:)
and implement the desired logic. From the docs (with some minor changes from me):
In the subclass implementation, evaluate [the pointed string
*partialStringPtr
] according to the context. ReturnYES
ifpartialStringPtr
applicable andNO
ifpartialStringPtr
not acceptable. Assign a new linepartialStringPtr
and a new range beforeproposedSelRangePtr
and returnNO
if you want to replace the line and change the selection range.
So, if a user tries to insert forbidden characters, you can either reject editing them entirely, or modify it to remove those forbidden characters. (Remember that custom changes can involve insertion, so it doesn't have to be just one typed character.) To reject the change entirely, assign origString
to *partialStringPtr
and origSelRange
to *proposedSelRangePtr
.
source to share