NSTextField持续更新

时间:2011-12-07 05:25:42

标签: objective-c macos cocoa nstextfield

我无法弄清楚如何让NSTextfield自动更新,而无需按“返回”或点击其他文字字段。

我的目标是在一个字段中输入一个数字,并同时更新其他字段。我尝试在文本字段属性中单击“连续”但它似乎没有做任何事情。

这是我的界面文件:

#import <Foundation/Foundation.h>

@interface InchController : NSObject {
    IBOutlet NSTextField *centimetersTextField;
    IBOutlet NSTextField *inchesTextField;
    IBOutlet NSTextField *feetTextField;
}

-(IBAction)convert:(id)sender;

@end

这是我的实施文件:

#import "InchController.h"

@implementation InchController

- (IBAction)convert:(id)sender {

    if (sender == inchesTextField) {
        float inches = [inchesTextField floatValue];
        [feetTextField setFloatValue:(inches * 0.0833)];
        [centimetersTextField setFloatValue:(inches * 2.54)];
    }
    else if (sender == feetTextField) {
        float feet = [feetTextField floatValue];
        [inchesTextField setFloatValue:(feet * 12)];
        [centimetersTextField setFloatValue:(feet * 30.48)];
    }
    else if (sender == centimetersTextField) {
        float centimeters = [centimetersTextField floatValue];
        [inchesTextField setFloatValue:(centimeters * 0.394)];
        [feetTextField setFloatValue:(centimeters * 0.033)];
    }

}

@end

所以这是根据Josh的解决方案更新的实现文件。注释掉IBAction,因为实现和接口文件中不再需要它。

#import "LengthController.h"

@implementation LengthController

//- (IBAction) convert: (id)sender {
//}

-(void) controlTextDidChange:(NSNotification *) note {

    NSTextField *changedField = [note object];

    if (changedField == inchesTextField) {
        float inches = [inchesTextField floatValue];
        [feetTextField setFloatValue: (inches * 0.0833)];
        [centimetersTextField setFloatValue: (inches * 2.54)];
    }

    if (changedField == centimetersTextField) {
        float centimeters = [centimetersTextField floatValue];
        [inchesTextField setFloatValue:(centimeters * 0.394)];
        [feetTextField setFloatValue:(centimeters * 0.033)];
    }

    if (changedField == feetTextField) {
        float feet = [feetTextField floatValue];
        [inchesTextField setFloatValue:(feet * 12)];
        [centimetersTextField setFloatValue:(feet * 30.48)];
    }
}

@end

2 个答案:

答案 0 :(得分:7)

使控制器成为文本字段的delegate;您可以在Interface Builder中通过Ctrl键从文本字段拖动到控制器来设置它。

在你的控制器中,实现"NSControl Delegate"方法controlTextDidChange:,只要字段的文本发生变化,就会调用它(顾名思义)。在该方法中,您可以验证文本,并在适当的情况下更新其他字段的内容。

传入的参数可以为您提供更改的文本字段;然后,您可以将其传递给现有的convert:方法以重用代码:

- (void) controlTextDidChange: (NSNotification *)note {

    NSTextField * changedField = [note object];
    [self convert:changedField];
}

行动方法没什么特别之处。 IBAction返回类型的计算结果为void;它仅被Xcode用于公开在Interface Builder中使用的方法。因此,您可以像任何其他方法一样调用它们。在这里,您将获得相应的字段并将其作为sender参数传递,就好像该字段已调用操作方法本身一样。

答案 1 :(得分:0)

根据问题的复杂程度,绑定也可能是一个可行的解决方案。

您可以在模型或模型控制器对象上定义属性,并将它们连接到相应的文本字段。然后,文本字段中的更改会立即反映在属性中,然后可以触发对其他属性的更改。

然后会自动更新绑定到这些“派生”属性的文本字段。

请记住使用willChangeValueForKey:didChangeValueForKey:将更改“括起”到派生属性,以便将更改发送给观察者。更多here

当然,如果你在依赖项中有循环,它会变得丑陋;在这种情况下,其他答案中提到的controlTextDidChange:方法可能更好。