Кнопка в стиле переключения: как в этом случае переключать заголовок? - PullRequest
0 голосов
/ 01 сентября 2011

У меня есть приложение CoreData, представляющее данные с помощью TableView, текстовых полей, кнопок ... Оно работает с ситуациями людей, и одной из кнопок является кнопка в стиле переключения с заголовком «Закрыть». Когда мы считаем, что дело пользователя закрыто, мы нажимаем, и оно меняет состояние атрибута логического типа в сущности, представляющего закрытое / открытое состояние дела, используя простую привязку к значению атрибута. Название кнопки также становится «Открыть заново», так как дело может быть вновь открыто в будущем.

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

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

Итак, я вернулся со всеми изменениями, обработанными IBAction, и на этот раз я использую привязки заголовка / альтернативного заголовка вместо привязки значения. Теперь заголовок кнопки переключается, но вместо отображения слов «Закрыть» и «Открыть заново» отображаются логические значения «0» и «1».

Возможно, мне следует также обработать изменение заголовка кнопки в IBAction, используя setTitle, но затем я вижу, что возникает новая проблема. При запуске приложения, как оно выберет соответствующую запись объекта для справки? А что, если таблица находится в ситуации «Нет выбора»? Похоже, довольно обширный кусок кода для решения такой маленькой проблемы ...

Любой совет относительно краткого, более прямого способа справиться с этим приветствуется. Спасибо.

1 Ответ

0 голосов
/ 02 сентября 2011

Звучит так, как будто у вас есть несколько вариантов.

Этот первый вариант немного сложнее, чем другие, но все же полезно знать о нем. Эта опция в основном не будет использовать привязки для кнопки закрытия / повторного открытия, а вместо этого будет устанавливать заголовок и т. Д. Программно. Основной план игры будет следующим:

  • Первоначальный заголовок кнопки закрытия / повторного открытия при открытии документа задается в файле пера (например, Close).

  • При желании, когда документ открывается, вы можете отключить кнопку в -awakeFromNib, так как представление таблицы не будет иметь начального выбора.

  • Единственные действия, которые требуют изменения заголовка или включенного состояния кнопки, это 1) когда изменяется выбор таблицы и 2) когда вы нажимаете кнопку закрытия / повторного открытия, чтобы переключить случай состояние.

Чтобы достичь желаемого результата, вы должны создать IBOutlet для кнопки закрытия / повторного открытия, если у вас ее еще нет. Затем вы подключите выход delegate таблицы просмотра к вашему классу контроллера, который сообщит вашему классу контроллера об изменении выбора таблицы (с помощью метода протокола - (void)tableViewSelectionDidChange:(NSNotification *)notification <NSTableViewDelegate>). Вам также необходимо обновить метод close / reopen IBAction, чтобы убедиться, что он переключает заголовок кнопки после нажатия (так как выбор таблицы не изменился во время этой операции). Код класса контроллера может выглядеть примерно так:

// add this declaration to avoid compiler warnings:
@interface LHController (LHPrivate)
- (void)updateCloseReopenButtonTitle;
@end

- (void)awakeFromNib {
   [self updateCloseReopenButtonTitle];
}

- (void)tableViewSelectionDidChange:(NSNotification *)notification {
   [self updateCloseReopenButtonTitle];
}

- (IBAction)toggleCloseReopenButton:(id)sender {
    // do your existing code here and then add:
   [self updateCloseReopenButtonTitle];
}

- (void)updateCloseReopenButtonTitle {
    // assuming 'casesController' is an IBOutlet to your NSArrayController
    NSArray *selectedObjects = [casesController selectedObjects];
    // loop through the selected cases to determine whether
    // they're all closed, all open, or mixed to set
    // the title of the button appropriately
    BOOL allClosed = YES;
    for (LHCase *case in selectedCases) {
        if ([case isOpen]) {
           allClosed = NO;
           break;
        }
    }
    [closeReopenButton setTitle:(allClosed ? @"Reopen" : @"Close")];
    [closeReopenButton setEnabled:[selectedObjects count] > 0];
}

До того, как появились привязки, так мы привыкли делать вещи.

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

enter image description here

Тогда у вас может быть метод IBAction, который обрабатывает дополнительные вещи, которые требуют обработки. Вы можете спросить casesController о -selectedObjects и затем просмотреть их. Пока вы убедитесь, что флажок Allows Mixed указывает, он имеет дополнительное преимущество, заключающееся в лучшем представлении смешанных сценариев, в случае выбора случаев со смешанными открытыми / закрытыми состояниями (флажок тире вместо полной проверки) .

Другой вариант, если вы хотите придерживаться переключателя, - создать и указать custom NSValueTransformer для заголовка и альтернативных привязок заголовка. Этот преобразователь значений принимает булево закрытое / открытое состояние корпуса и превращает его в строку, более подходящую, чем просто 0 или 1 (что сейчас и отображается). Это может выглядеть примерно так:

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

+ (BOOL)allowsReverseTransformation {
    return NO;
}

- (id)transformedValue:(id)value {
    BOOL isClosed;

    if (value == nil) return nil;

    // Attempt to get a reasonable value from the
    // value object.
    if ([value respondsToSelector: @selector(boolValue)]) {
        isClosed = [value boolValue];
    } else {
        [NSException raise: NSInternalInconsistencyException
                    format: @"Value (%@) does not respond to -boolValue.",
        [value class]];
    }
    return (isClosed ? @"Reopen" : @"Close");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...