Подтвердить что ты не робот

Как настроить ячейку раскрытия в представлении NSOutlineView на основе представлений

Я пытаюсь настроить отображение стрелки раскрытия в моем NSOutlineView на основе представления. Я видел, что рекомендуется использовать

- (void)outlineView:(NSOutlineView *)outlineView willDisplayOutlineCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item

делегировать метод для его достижения. Проблема в том, что этот метод почему-то не вызван. У меня есть 2 пользовательских представления ячеек - один для элемента и второй для элемента заголовка. Может быть, этот метод не вызывается для представления на основе представления? Может быть, что-то сломалось во Льве?

Просветите свет.

4b9b3361

Ответ 1

Этот ответ написан с учетом OS X 10.7, для более новых версий OS X/macOS см. ответ WetFish

Этот метод не вызывается, потому что он применим только для контурных представлений на основе ячейки.

В представлении, основанном на представлении, треугольник раскрытия является регулярной кнопкой в ​​представлении строк расширяемых строк. Я не знаю, где он добавляется, но это так, и метод NSView didAddSubview: обрабатывает именно ту ситуацию, когда добавление в другое место добавляется.

Следовательно, подкласс NSTableRowView и переопределить didAddSubview:, например:

-(void)didAddSubview:(NSView *)subview
{
    // As noted in the comments, don't forget to call super:
    [super didAddSubview:subview];

    if ( [subview isKindOfClass:[NSButton class]] ) {
        // This is (presumably) the button holding the 
        // outline triangle button.
        // We set our own images here.
        [(NSButton *)subview setImage:[NSImage imageNamed:@"disclosure-closed"]];
        [(NSButton *)subview setAlternateImage:[NSImage imageNamed:@"disclosure-open"]];
    }
}

Конечно, вашему делегату в представлении плана придется реализовать outlineView:rowViewForItem:, чтобы вернуть новое представление строки.

Несмотря на название, frameOfOutlineCellAtRow: of NSOutlineView по-прежнему вызывается для представления на основе контура, поэтому для позиционирования вашего треугольника вы можете подклассифицировать представление схемы и переопределить этот метод.

Ответ 2

Решение 1:

Подкласс NSOutlineView и переопределить makeViewWithIdentifier:owner:

- (id)makeViewWithIdentifier:(NSString *)identifier owner:(id)owner {
    id view = [super makeViewWithIdentifier:identifier owner:owner];

    if ([identifier isEqualToString:NSOutlineViewDisclosureButtonKey]) {
        // Do your customization
    }

    return view;
}

Для списков источников используйте NSOutlineViewShowHideButtonKey.

Решение 2:

Конструктор интерфейсов

Кнопка добавляется в столбец, а идентификатор - NSOutlineViewDisclosureButtonKey.

введите описание изображения здесь

Официальная документация от NSOutlineView.h

/* The following NSOutlineView*Keys are used by the View Based NSOutlineView to create the "disclosure button" used to collapse and expand items. The NSOutlineView creates these buttons by calling [self makeViewWithIdentifier:owner:] passing in the key as the identifier and the delegate as the owner. Custom NSButtons (or subclasses thereof) can be provided for NSOutlineView to use in the following two ways:
 1. makeViewWithIdentifier:owner: can be overridden, and if the identifier is (for instance) NSOutlineViewDisclosureButtonKey, a custom NSButton can be configured and returned. Be sure to set the button.identifier to be NSOutlineViewDisclosureButtonKey.
 2. At design time, a button can be added to the outlineview which has this identifier, and it will be unarchived and used as needed.

 When a custom button is used, it is important to properly set up the target/action to do something (probably expand or collapse the rowForView: that the sender is located in). Or, one can call super to get the default button, and copy its target/action to get the normal default behavior.

 NOTE: These keys are backwards compatible to 10.7, however, the symbol is not exported prior to 10.9 and the regular string value must be used (i.e.: @"NSOutlineViewDisclosureButtonKey").
 */
APPKIT_EXTERN NSString *const NSOutlineViewDisclosureButtonKey NS_AVAILABLE_MAC(10_9); // The normal triangle disclosure button
APPKIT_EXTERN NSString *const NSOutlineViewShowHideButtonKey NS_AVAILABLE_MAC(10_9); // The show/hide button used in "Source Lists"

Ответ 3

Swift2 версия ответа @Monolo:

override func didAddSubview(subview: NSView) {
    super.didAddSubview(subview)
    if let sv = subview as? NSButton {
        sv.image = NSImage(named:"icnArwRight")
        sv.alternateImage = NSImage(named:"icnArwDown")
    }
}