NSTextField с Number Formatter не допускает десятичный ввод - PullRequest
1 голос
/ 26 января 2012

Я пытаюсь сделать простое приложение Какао, где число вводится в текстовое поле.Когда число вводится в одно текстовое поле, другое текстовое поле автоматически обновляется другим номером (и наоборот).Текстовое поле, которое я перетащил в окно, - это «Текстовое поле с средством форматирования чисел» из конструктора интерфейса.У меня есть текстовые поля, установленные в качестве делегата, что позволяет им автоматически обновлять.Однако форматирование, похоже, не работает.Я не могу ввести десятичные числа.Пожалуйста, помогите !!!

Заголовочный файл здесь:

#import <Cocoa/Cocoa.h>

@interface AppDelegate : NSObject <NSApplicationDelegate> {
    IBOutlet NSTextField *number1;
    IBOutlet NSTextField *number2;
}

@property (assign) IBOutlet NSWindow *window;

@end

Файл реализации здесь:

#import "AppDelegate.h"

@implementation AppDelegate

@synthesize window = _window;

-(void)controlTextDidChange:(NSNotification *) note {
    NSTextField *changedField = [note object];

    if (changedField == number1) {
        float num1 = [number1 floatValue];
        [number2 setFloatValue: (num1*2.0)];
    }

    if (changedField == number2) {
        float num2 = [number2 floatValue];
        [number1 setFloatValue: (num2/2.0)];
    }
}

@end

Ответы [ 3 ]

1 голос
/ 23 ноября 2014

Я знаю, что очень поздно отвечать, но я столкнулся с точно такой же проблемой и нашел хороший обходной путь.Опираясь на ответ @ CRD.

Как я справился с проблемой:

  • Сохраните форматер
  • Протрите форматер из текстового поля
  • readзначение из текстового поля
  • Повторно примените форматер к текстовому полю

Пример того, как я это сделал, приведен ниже:

-(void)controlTextDidChange:(NSNotification *)obj
{
    if ([obj object])
    {
        NSTextField *field = [obj object];
        NSNumberFormatter *formatter = [field formatter];
        [field setFormatter:nil];
        double data = [field doubleValue];
        [field setFormatter:formatter];
        // ...
        // Do other meaningful stuff now
    }
}

Не уверен, что этоправильный способ сделать это, но у меня это сработало.

1 голос
/ 27 января 2012

Это немного неясно, но то, что вы пытаетесь сделать, не может действительно работать, но есть альтернатива.

В вашем коде у вас есть:

float num1 = [number1 floatValue];
[number2 setFloatValue: (num1*2.0)];

Запросы первой строки текущее значение number1.Поскольку к number1 присоединен форматер чисел, он вызывается для форматирования текста ... и, если вы ввели, скажем, 123., на этом этапе отформатированный результат будет 123 ... и ваша десятичная точкаисчез.Вы заметите, что вы также не можете вводить запятые (разделители тысяч).

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

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

Чтобы сделать последнее, измените свой кодна:

- (IBAction) textDidChange:(id)sender
{
   if (sender == number1)
   {
      float num1 = [number1 floatValue];
      [number2 setFloatValue: (num1*2.0)];
   }
   else if (sender == number2)
   {
      float num2 = [number2 floatValue];
      [number1 setFloatValue: (num2/2.0)];
   }
}

и подключите его к элементу управления в качестве «селектора» и удалите соединение «делегат», которое у вас уже есть.

Это решение менее «динамично», чем то, что вы пытались, но это работает.Чтобы получить динамический ответ, вам нужно написать более сложный код, как указано выше.

0 голосов
/ 12 марта 2013

Немного опоздал на вечеринку, но я сам столкнулся с этой проблемой, и мне кажется, что я нашел краткое решение, которое поддерживает динамическое обновление, но избегает слишком раннего запуска форматера, что не позволяет пользователю вводить дроби:

- (void)controlTextDidChange:(NSNotification *)aNotification
{
    NSTextView *fieldEditor = [aNotification.userInfo valueForKey:@"NSFieldEditor"];
    CGFloat floatValue = fieldEditor.textStorage.string.floatValue;
    // Getting the new value from the field editor avoids the formatter kicking in here.
    // You can now use the value as you wish. Probably something like:
   if (sender == number1)
   {
      [number2 setFloatValue: (floatValue*2.0)];
   }
   else if (sender == number2)
   {
      [number1 setFloatValue: (floatValue/2.0)];
   }
}

(Я набрал это в браузере, поэтому оно может быть не совсем правильным, но должно быть достаточно близко. Основные части - это первые две строки: извлечь редактор поля и извлечь из него новое значение.

...