【问题标题】:Restrict NSTextField to only allow numbers限制 NSTextField 只允许数字
【发布时间】:2022-01-05 12:47:13
【问题描述】:

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

【问题讨论】:

  • @giorashc 谢谢,我找到了,但没有帮助:(
  • 您需要说明为什么您发现的其他问题没有帮助。
  • 哦,对不起W'rkncacnter,我不知道把代码放在哪里,答案还不清楚......(至少对我来说)

标签: cocoa nstextfield


【解决方案1】:

[适用于 Swift 3.0.1]

正如其他人建议的那样,继承 NumberFormatter 并覆盖 isPartialStringValid 方法。最简单的方法是在 xib/storyboard 中的NSTextField 下放置一个NumberFormatter 对象并将其更新为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
    }
}

【讨论】:

  • 谢谢。用了一点你的逻辑!
【解决方案2】:

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

用途:

let onlyIntFormatter = OnlyIntegerValueFormatter()
myNsTextField.formatter = onlyIntFormatter

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      在 SWIFT 中,我是这样做的

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

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

        • string.utf16Count 在 swift 1.2 中不再可用。你应该把它改成count(partialString.utf16)
        • 实际上在很多层面上都是错误的。首先,数字不是布尔可转换的,其次,您要检查isEmpty。如果字符串的长度大于零,则必须通过
        【解决方案6】:

        这是一个过滤的解决方案。给文本字段一个委托和一个出口并设置 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);
        }
        

        【讨论】:

          【解决方案7】:

          这里是创建相同的步骤......

          只需创建带有子类 NSNumberFormatter 的 ANYCLASS(称为 SAMPLE)...

          在.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];
          

          你完成了!!!

          【讨论】:

            【解决方案8】:

            尝试创建自己的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];
            

            【讨论】:

            • 在 Interface Builder 中,将 NSObject 拖放到 xib 上并将其类设置为您的自定义格式化程序(如上)。然后将 NSTextFields“格式化程序”出口设置/拖动到该 NSObject。那么你不需要任何代码来应用格式化程序。
            • 一切正常......但是当我尝试输入多个零(0)......就像000000......它不接受......任何帮助请???
            【解决方案9】:

            试试这个 -

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

            【讨论】:

            • 感谢您的回答,但由于某种原因,它仍然不允许只允许数字 :( 但我会继续尝试......顺便说一句,代码应该在哪里?跨度>
            猜你喜欢
            • 1970-01-01
            • 2013-12-19
            • 1970-01-01
            • 2019-04-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-11-22
            相关资源
            最近更新 更多