【问题标题】:Cocoa NSTextField NSNumberFormatter and delegate可可 NSTextField NSNumberFormatter 和委托
【发布时间】:2015-04-07 22:59:28
【问题描述】:

我正在制作一个具有以下特征的 NSTextField:
1) 仅允许整数值 (0-9)
2) 长度为 1 或 2 位数字
3) 最小值为 1,最大值为 99
4) 如果输入 0,该值应该变回 1
5)如果按下删除并且单元格完全清空,该值应更改为 1 并自动选择(高亮),以便用户可以简单地输入新值

我可以通过创建自定义格式化程序和委托来获得这种行为,但我想仅在自定义格式化程序中实现这一点(我想保持事情“简单”)。

这是我的代码:

在委托文件中:

- (void)controlTextDidChange:(NSNotification *)aNotification
{
    if ([[txtfldSaveDuration stringValue] length]==0) {
        [txtfldSaveDuration setStringValue:@"1"];
    }
    if ([[txtfldSaveDuration stringValue] isEqualToString:@"0"]) {
        [txtfldSaveDuration setStringValue:@"1"];
    }
}

在自定义格式化程序文件中:

@implementation OnlyIntegerValueFormatter

- (BOOL)isPartialStringValid:(NSString*)partialString newEditingString:    (NSString**)newString errorDescription:(NSString**)error
{
    // necessary otherwise can't delete (to select) the first character
    if([partialString length] == 0) {
        return YES;
    }  
    // two integer max length (99)
    if([partialString length] > 2) {
        return NO;
    }
    // integers only
    NSScanner* scanner = [NSScanner scannerWithString:partialString];
    if(!([scanner scanInt:0] && [scanner isAtEnd])) {
        NSBeep();
        return NO;
    }    
    return YES;
}
@end

如何简化?

【问题讨论】:

    标签: xcode cocoa delegates nstextfield nsnumberformatter


    【解决方案1】:

    如果您改为实现-isPartialStringValid:proposedSelectedRange:originalString:originalSelectedRange:errorDescription:,您将获得更多控制权,包括对结果选定范围的控制。

    大概是这样的:

    - (BOOL)isPartialStringValid:(NSString **)partialStringPtr
           proposedSelectedRange:(NSRangePointer)proposedSelRangePtr
                  originalString:(NSString *)origString
           originalSelectedRange:(NSRange)origSelRange
                errorDescription:(NSString **)error
    {
        if ([*partialStringPtr length] == 0)
        {
            *partialStringPtr = @"1";
            *proposedSelRangePtr = NSMakeRange(0, [*partialStringPtr length]);
            return NO;
        }
    
        // two integer max length (99)
        if ([*partialStringPtr length] > 2)
        {
            NSRange changed = NSMakeRange(origSelRange.location, [*partialStringPtr length] - (origString.length - origSelRange.length));
            NSRange excess;
            excess.length = [*partialStringPtr length] - 2;
            excess.location = changed.location + (changed.length - excess.length);
            *partialStringPtr = [*partialStringPtr stringByReplacingCharactersInRange:excess withString:@""];
            *proposedSelRangePtr = NSMakeRange(excess.location, 0);
            return NO;
        }
        // integers only
        NSScanner* scanner = [NSScanner scannerWithString:*partialStringPtr];
        scanner.charactersToBeSkipped = nil;
        if(!([scanner scanInt:0] && [scanner isAtEnd])) {
            *partialStringPtr = origString;
            *proposedSelRangePtr = origSelRange;
            NSBeep();
            return NO;
        }    
        return YES;
    }
    

    【讨论】:

    • 感谢您的建议。但是,这允许输入字母(尽管它们已被选中,但光标键可以取消选择它们)并且 0 是有效输入。我会接受你的回答,因为它可能只需要一些调整。
    • 是的,修复这两个项目只需要几分钟。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多