Добавление опции «Не выбран» для привязки NSPopupButton - PullRequest
1 голос
/ 07 апреля 2011

У меня есть NSPopupButton, который связан с базовыми данными, поддерживаемыми NSArrayController.Выбор NSPopupButton также привязан к базовому элементу данных.Привязки выглядят примерно так:

NSArray 'A' of core data entities --> Array Controller
Array Controller --> NSPopupButton.contentValues.arrangedObjects.name

NSArray 'B' of core data entities --> Array Controller
Array Controller --> NSPopupButton.selectedObject.methodOnObject.name

В выбранном объекте есть метод, который ищет идентификатор, который находит объект и возвращает этот объект следующим образом:

-(MyWidget *)selectedWidget {

    return [MyCunningLookupMethod widgetForID:[[self widgetID] intValue]];
}

И устанавливаетОбъект с другой стороны так же прост:

-(void)setSWidget:(MyWidget *)anObj {

    [self setWidgetID:[anObj uid]];
}

Большую часть времени объект соответствует объекту в списке доступных значений contentValues.Однако бывают случаи, когда идентификатор выбранного объекта равен 0, и в этом случае я хочу отобразить опцию в доступном списке под названием «Не выбран».Я мог бы легко выполнить отправку назад другого объекта (или ничего), если идентификатор объекта равен 0.

Я могу обработать это с помощью «Заполнителя без выбора», но как только пользователь выбирает один из других элементовместозаполнитель для невыбранных удален из списка.

Я хочу предоставить пользователю возможность выбрать элемент или не выбирать элемент (т. е. установить его обратно на "Не выбран").Если не считать создания всего NSPopupMenu программно путем обхода массива, получаемого из базовых данных при каждом изменении выбора, есть ли способ вставить элемент меню в список, представляющий невыбранное состояние, которое всегда будет доступно пользователю?

Я рассмотрел возможность добавления объекта сущности в основное хранилище данных, которое имеет все 0-значные значения, за исключением имени, которое будет называться «Не выбрано».Это, однако, просто не кажется правильным способом сделать что-то и фактически представляет некоторые другие проблемы с наличием пустых объектов в хранилище, которые на самом деле не имеют никакого отношения к данным.

Как всегда, любой илюбая помощь будет принята с благодарностью.

РЕШЕНИЕ

Ну, я точно не следовал тому, что опубликовал Hobbes the Tige, но это в значительной степени поставило меня туда, где я должен был быть,Вместо привязки в IB я в итоге создал метод, который позволяет мне отправлять в моем массиве объектов при изменении выбора родительский массив или пользовательскую активность, инициирующую изменение.Затем метод просто обновляет NSPopupButton соответствующей информацией об основном объекте данных и все еще позволяет нам IB связать selectedTag соответствующего объекта.

Вот метод

+(void)createContentsForPopup:(NSPopUpButton *)aPopupButton
                withArray:(NSArray *)anObjectArray 
           addNotSelected:(BOOL)aFlag {

    [aPopupButton removeAllItems];

    if (aFlag) {    

        if (!anObjectArray || [anObjectArray count] == 0) {

           [aPopupButton addItemWithTitle:@"--- Not available ---"];
           [[aPopupButton itemAtIndex:0] setTag:0];

           return;
        }

        [aPopupButton addItemWithTitle:@"--- Not selected ---"];
        [[aPopupButton itemAtIndex:0] setTag:0];
    }

    NSSortDescriptor * sd = [NSSortDescriptor sortDescriptorWithKey:@"name"
                                                          ascending:YES];

    [anObjectArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:sd]];

    for (id anObject in anObjectArray) {

        [aPopupButton addItemWithTitle:[anObject name]];

        int thisItem = [aPopupButton indexOfItemWithTitle:[anObject name]];

        [[aPopupButton itemAtIndex:thisItem] setTag:[[anObject uid] intValue]];
    }
}

Очевидно, этозависит от того, какой массив объектов будет передан в соответствии с наличием name для описательного поля и uid для уникального идентификатора.

Работа выполнена.: -)

1 Ответ

2 голосов
/ 08 апреля 2011

Не сказать, что это лучшее решение, но это идея (вам, вероятно, придется его настроить).

Добавьте пункт меню с заголовком:

- (void)insertItemWithTitle:(NSString *)title atIndex:(NSInteger)index

Итак,как это:

[popupButton inserItemWithTitle:@"No selection" atIndex:0];

Помещение в индекс 0 поместит его наверх.Если вы хотите, чтобы оно было внизу списка, используйте этот метод:

- (void)addItemWithTitle:(NSString *)title

Затем, когда вы получите событие действия, вы можете проверить наличие элемента с индексом 0. Если он с индексом 0, вы знаете,это «Нет выбора».

-(IBAction)popupSelectionAction:(id)sender {
     if (sender == popupButton) {
          //Check for "No selection"
          if ([popupButton indexOfSelectedItem] != 0) {
               //Update core data managed object value
          }
     }
}

Или, если вы используете addItemWithTitle, проверьте, является ли он последним элементом в массиве элементов.

-(IBAction)popupSelectionAction:(id)sender {
     if (sender == popupButton) {
          //Check for "No selection"
          if ([popupButton indexOfSelectedItem] != ([popupButton numberOfItems]-1)) {
               //Update core data managed object value
          }
     }
}

Ссылка на класс:

http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSPopUpButton_Class/Reference/Reference.html

...