将 NSTextField 限制为仅允许数字



如何将NSTextField限制为仅允许数字/整数?我发现了这样的问题,但它们没有帮助!

尝试创建自己的NSNumberFormatter子类并检查-isPartialStringValid:newEditingString:errorDescription:方法中的输入值。

@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

然后将此格式化程序设置为您的NSTextField

OnlyIntegerValueFormatter *formatter = [[[OnlyIntegerValueFormatter alloc] init] autorelease];
[textField setFormatter:formatter];

斯威夫特 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
    }
}

用:

let onlyIntFormatter = OnlyIntegerValueFormatter()
myNsTextField.formatter = onlyIntFormatter

这是一个过滤解决方案。为文本字段提供一个委托和一个出口,并设置控件TextDidChange方法。

- (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]='';
    textfield.stringValue = [NSString stringWithUTF8String:stringResult];
    free(stringResult);
}

试试这个 -

NSNumberFormatter *formatter = [[[NSNumberFormatter alloc] init] autorelease];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[textField setFormatter:formatter];

下面是一个 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
}

在 SWIFT 中,我是这样做的

  1. 使用 Int(( 将文本值转换为 Int
  2. 检查转换后的值不小于0
  3. 如果小于 0,则显示错误消息,其他接受该值

    if ((Int(txtField.stringValue)) < 0){
        // Display error message
    }
    

[适用于 Swift 3.0.1]

正如其他人建议的那样,子类NumberFormatter并覆盖isPartialStringValid方法。最简单的方法是将NumberFormatter对象放在 xib/情节提要中的NSTextField下并更新其Custom Class。下一个实现仅允许整数或空白值,如果字符串包含非法字符,则播放哔哔声。

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
        }
    }
}

StringnumberOfCharacters()isInt()是添加到扩展中的方法。

extension String {
    func isInt() -> Bool {
        if let intValue = Int(self) {
            if intValue >= 0 {
                return true
            }
        }
        return false
    }
    func numberOfCharacters() -> Int {
        return self.characters.count
    }
}

以下是创建相同内容的步骤。

只需创建 ANYCLASS(称为 SAMPLE(,并对 NSNumberFormatter 进行子类化......

在 .m 文件中编写以下代码...

 - (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;

}

现在.. 在您的实际类中,将格式化程序设置为您的 NSTextField 对象,如下所示...

NSTextField *mySampleTxtFld;

对于这套格式化程序...

SAMPLE* formatter=[[SAMPLE alloc]init];// create SAMPLE FORMATTER OBJECT 
self.mySampleTxtFld.delegate=self;
[self.mySampleTxtFld setFormatter:formatter];

大功告成!!

Swift 2.0 自定义格式化程序,使用 0 而不是空格:

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
        }
    }
}

在 swift 5.7 中:

import Cocoa
class Main: NSViewController {
    @IBOutlet weak var textfield: NSTextField!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        textfield.delegate = self
    }
}
extension Main: NSTextFieldDelegate {
    func controlTextDidChange(_ obj: Notification) {
        let filtered = (obj.object as! NSTextField).stringValue.filter{"0123456789".contains($0)}
        if filtered != (obj.object as! NSTextField).stringValue {
            (obj.object as! NSTextField).stringValue = filtered
        }
    }
}

如果要仅允许输入指定的字符,可以更改筛选规则。 像这样:

let filtered = (obj.object as! NSTextField).stringValue.filter{"abcdefghijklmnopqrstuvwxyz".contains($0)}

希望这对你有帮助

//  NSTextFieldNumberFormatter+Extension.swift
import Foundation
class TextFieldIntegerValueFormatter: NumberFormatter {
var maxLength: Int
init(maxLength: Int) {
    self.maxLength = maxLength
    super.init()
}
required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}
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.count > maxLength {
        return false
    }
    
    // Actual check
    return Int(partialString) != nil
 }
}

需要像这样打电话:

myNsTextField.formatter = TextFieldIntegerValueFormatter(maxLength: 6)

最新更新