Динамически обновлять номера в NSTextField - PullRequest
1 голос
/ 01 февраля 2012

У меня проблемы с созданием динамического конвертера.У меня есть два текстовых поля: одно для «дюймов» и другое для «футов».Моя цель - преобразовать дюймы в футы при вводе чисел и наоборот.Я хочу, чтобы действие происходило динамически, а не при нажатии кнопки «Enter» или «Tab».

Я использую NSTextField с Number Formatter.Поэтому мне нужно, чтобы форматировщик также работал во время расчета.Я пробовал - (void) метод controlTextDidChange, но форматер не работает с ним.

См. Мой текущий код, который не работает динамически.

#import <Foundation/Foundation.h>

@interface Convert : NSObject {
    IBOutlet NSTextField *inches;
    IBOutlet NSTextField *feet;
}

- (IBAction)textDidChange:(id)sender;

@end

и

#import "Convert.h"

@implementation Convert

- (IBAction)textDidChange:(id)sender {

    if (sender == inches) {
        float myInches = [inches floatValue];
        [feet setFloatValue: (myInches/12)];
    }
    else if (sender == feet) {
        float myFeet = [feet floatValue];
        [inches setFloatValue: (myFeet*12)];
    }
}

@end

Может кто-нибудь сказать мне, как сделать это, не нажимая клавишу «Ввод» или «Tab»?

... Теперь пробуем подход NSValueTransformer, используя NSForm вместо NSTextField ...

#import <Foundation/Foundation.h>

@interface LengthConverter : NSValueTransformer

+ (Class)transformedValueClass;
+ (BOOL)allowsReverseTransformation;

- (id)transformedValue:(id)value;
- (id)reverseTransformedValue:(id)value;

@end

и

#import "LengthConverter.h"

@implementation LengthConverter

+ (Class)transformedValueClass {
    return [NSNumber class];
}

+ (BOOL)allowsReverseTransformation {
    return YES;   
}

- (id)transformedValue:(id)value {
    if (value == nil) return nil;

    if (![value respondsToSelector: @selector(doubleValue)]) {
        [NSException raise:NSInternalInconsistencyException format:@"Value does not respond",[value class]];
    }

    CGFloat inchesInputValue = [value doubleValue]; // handles NSString and NSNumber
    CGFloat feetOutputValue = inchesInputValue / 12;

    return [NSNumber numberWithDouble: feetOutputValue];
}

- (id)reverseTransformedValue:(id)value {
    if (value == nil) return nil;

    if (![value respondsToSelector: @selector(doubleValue)]) {
        [NSException raise:NSInternalInconsistencyException format:@"Value does not respond",[value class]];
    }

    CGFloat feetInputValue = [value doubleValue]; // handles NSString and NSNumber
    CGFloat inchesOutputValue = feetInputValue * 12;

    return [NSNumber numberWithDouble: inchesOutputValue];
}

@end

1 Ответ

2 голосов
/ 01 февраля 2012

Вы можете связать значения, используя NSValueTransformer s.

NSValueTransformer предлагает преобразования объектов в объекты, которые также можно использовать в XIB и привязках. Система определяет несколько, и вы можете определить свой собственный довольно легко. Образец температурного преобразователя от Apple станет хорошей отправной точкой для ознакомления с NSValueTransformer.

Обновление в ответ на образец

В + [ApplicationDelegate initialize] вы увидите, как программа регистрирует все необходимые трансформаторы. Они регистрируются на имя, такое как @"centrigradeFromKelvin".

Как только необходимые вам трафик будут зарегистрированы, вы можете использовать трансформатор в NIB. В примере TemperatureConvertoer вы можете:

  1. перейти к ячейкам формы
  2. выберите форму ячейки - по Цельсию
  3. Нажмите cmd + opt + 7, чтобы просмотреть привязки полей
  4. Значение привязано к значению в SharedDefaults - преобразователь значения установлен как "centrigradeFromKelvin".
...