NSTextField постоянное обновление - PullRequest
4 голосов
/ 07 декабря 2011

Я не могу понять, как заставить 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

Итак, вот обновленный файл реализации для решения Джоша. Закомментировал 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 ]

7 голосов
/ 07 декабря 2011

Сделайте ваш контроллер делегатом текстовых полей; Вы можете установить это в Интерфейсном Разработчике, перетаскивая Ctrl от текстовых полей до контроллера.

В вашем контроллере реализуйте метод "NSControl Delegate" controlTextDidChange:, который будет вызываться (как предполагает его название) всякий раз, когда изменяется текст поля. В этом методе вы можете проверить текст и, если необходимо, обновить содержимое других полей.

Передаваемый аргумент может дать вам текстовое поле, которое изменилось; затем вы можете передать это существующему методу convert: для повторного использования кода:

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

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

В методах действия нет ничего особенного. Возвращаемый тип IBAction оценивается как void; это только используется XCode, чтобы выставить метод для использования в Интерфейсном Разработчике. Поэтому вы можете вызывать их так же, как и любой другой метод. Здесь вы получаете соответствующее поле и передаете его как параметр sender, как если бы поле вызвало сам метод действия.

0 голосов
/ 07 декабря 2011

В зависимости от сложности проблемы, привязки также могут быть жизнеспособным решением.

Вы можете определить свойства модели или объекта контроллера модели и подключить их к соответствующим текстовым полям. Затем изменения в текстовом поле немедленно отражаются в свойствах, которые затем могут инициировать изменения других свойств.

Текстовые поля, связанные с этими «производными» свойствами, затем автоматически обновляются.

Не забудьте заключить в скобки ваши изменения в производных свойствах с помощью willChangeValueForKey: и didChangeValueForKey:, чтобы изменения отправлялись наблюдателям. Подробнее здесь .

Конечно, если у вас есть циклы в зависимостях, это будет ужасно; в этом случае метод controlTextDidChange:, упомянутый в других ответах, вероятно, лучше.

...