xcode - Cocoa NSTextField NSNumberFormatter 和委托(delegate)

标签 xcode cocoa delegates nstextfield nsnumberformatter

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

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

这是我的代码:

在委托(delegate)文件中:

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

我怎样才能简化这个?

最佳答案

如果您实现 -isPartialStringValid:proposeSelectedRange: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;
}

关于xcode - Cocoa NSTextField NSNumberFormatter 和委托(delegate),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29502865/

相关文章:

xcode - 无法在 xcode 8 中构建模块 Cocoa

ios - 按顺序显示两个相同的警报 View 。如何区分警报 1 和警报 2 中的文本?

iphone - 从命令行确定代码签名身份?

iphone - 为什么我应该在应用程序退出之前释放(并因此释放)对象?

ios - Objective-C 委托(delegate)内存存储空问题

c# - 方法可以附加到具有预定义参数的委托(delegate)吗?

iphone - iPhone 上的自动化接口(interface)测试

objective-c - 帮助理解多 Controller Cocoa 应用程序

macos - 自动转换 slider 值

c# - 过度使用委托(delegate)对性能来说是个坏主意吗?