使用带有绑定和reverseTransformedValue方法的自定义NSValueTransformer子类

时间:2015-06-16 16:54:35

标签: objective-c cocoa

我正在使用Bindings编写Cocoa App。我有一个NSSlider和一个NSTextField。

Slider的值绑定到transformedValue方法返回的值,而TextBox应该绑定到reverseTransformedValue方法。

我怎么能实现这个目标?对于Slider,我将NSValueTransformer子类的名称输入到Bindings选项卡的Value / Value Transformer部分。但是,如何告诉TextFields Value Transformer部分使用该类的reverseTransformedValue?

我的类实现如下所示:     @implementation IntegerBy1002FloatTransformer

-(BOOL)allowsReverseTransformation{
    return YES;
}

-(id)transformedValue:(id)value{
    float floatValue;
    int integerValue;

    /* sanity checks omitted */
    integerValue=(int)[value integerValue];
    floatValue=(float)integerValue/100.0;
    return [NSNumber numberWithFloat: floatValue];
}

-(id)reverseTransformedValue:(id)value{
    float floatValue;
    int integerValue;

    /* sanity checks omitted */
    floatValue=[value floatValue];
    integerValue=(int)(floatValue*100.0);
    return [NSNumber numberWithInt: integerValue];
}
@end

1 个答案:

答案 0 :(得分:2)

考虑到您提到的目标以及一般情况,您的代码会涉及一些问题。您可以根据自己的整体方法重新考虑一些事项。

我看到的一个问题(与您的实际问题无关)是-[NSNumber integerValue]返回NSInteger,而不是int。事实上,在NSInteger的任何时候使用int,因为系统在编译时“做正确的事情”有关32/64位和其他平台问题。 unsigned intNSUInteger相同。如果您关心精确度,那么您最近也可能只是使用double-[NSNumber doubleValue]而不是float / -floatValue

我看到的另一个令人困惑的问题是,您要求数字对象获取浮点值,执行算术,然后将结果转换为整数以创建带有结果的新数字,反之亦然。你为什么不首先要求目标基元类型?为什么要求它的整数值,然后在你可以直接询问float时将其转换为-floatValue进行浮点运算?例如:

return [NSNumber numberWithFloat:([value floatValue] / 100.0)];

......反之亦然:

return [NSNumber numberWithInteger:([value floatValue] * 100.0)];

由于NSNumber将为您进行转换(您可以放入任何类型的号码并轻松获取任何类型的号码),因此不需要所有这些额外的内容。

但这让我想到了你的整体方法。据我了解,您希望滑块和文本字段影响相同的值,但您的文本字段应显示该值乘以100,可能格式化为整数。如果我误解了你的目标(你没有真正描述过 - 你只问了一个关于更广泛问题的非常狭隘的问题),请告诉我,我会修改我的答案。

如果这是你想要完成的事情,我有几点:

  1. 值变换器是他们正在转换的值的双向,对于他们绑定的属性。也就是说,它们采取一些价值并转换(如果你愿意的话,“翻译”)它是一种显示方式和内部存储/设置的相反方式。在您的情况下,您只希望将内部存储的值乘以100以进行显示,但是如果更改,用户键入的任何值(在该大小)应该被转换回(除以100)以进行存储。由于滑块直接反映实际存储的值,因此不需要值变换器。

  2. 此处的值绑定处理NSNumber个实例,正如我上面所说,它在内部是类型无关的。这意味着“数字是数字是数字”。您可以存储和检索您喜欢的任何基本类型。没有理由投。我在上面说过这个但是需要重复。

  3. 如果要使用值的内部存储处理浮点但仅允许文本字段的显示和输入中的整数,请使用NSNumberFormatter(将其附加到文本字段并进行配置)仅显示整数 - 在Interface Builder中轻松完成。由于上面的数字2(即,它是NSNumber),根本不需要担心你从你的价值中得到什么原始类型。控件(带有数字格式器)为您完成这项工作。顺便说一下,它还在编辑期间对用户输入强制执行此操作。

  4. 考虑到上述情况,您的价值变换器方法可以大大简化(特别是使用ObjC 2.0甜度,如自动数字装箱和点符号):

    - (id)transformedValue:(id)value {
        /* sanity checks omitted */
        return @( value.doubleValue / 100.0 );
    }
    
    - (id)reverseTransformedValue:(id)value {
        /* sanity checks omitted */
        return @( value.doubleValue * 100.0 )
    }
    

    我希望这会有所帮助。