NSOutlineView: удалить раскрывающий треугольник и отступ - PullRequest
25 голосов
/ 23 ноября 2010

Я использую NSOutlineView для проекта и не могу понять две вещи:

  • Как убрать треугольник раскрытия для узлов дерева. Такие приложения, как iTunes, похоже, способны сделать это:

alt text

Существует ли какой-то метод делегата NSOutlineView, который используется для этого? Или это требует подкласса?

  • Как отключить отступ для элементов. Я попытался использовать setIndentationPerLevel: и установить его равным 0, а также изменить отступ столбца на 0 в Интерфейсном Разработчике, но, похоже, это не имеет никакого эффекта.

Ответы [ 6 ]

40 голосов
/ 23 ноября 2010

Вы столкнулись с нужным человеком здесь.Мне пришлось столкнуться с этим всего неделю назад.

Удаление треугольника раскрытия : внедрите метод frameOfOutlineCellAtRow: в своем подклассе NSOutlineView и верните NSZeroRect (только еслиВы, конечно, хотите скрыть треугольник этой конкретной строки.)

- (NSRect)frameOfOutlineCellAtRow:(NSInteger)row {
    return NSZeroRect;
}

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

- (NSRect)frameOfCellAtColumn:(NSInteger)column row:(NSInteger)row {
    NSRect superFrame = [super frameOfCellAtColumn:column row:row];


    if ((column == 0) /* && isGroupRow */) {
        return NSMakeRect(0, superFrame.origin.y, [self bounds].size.width, superFrame.size.height);
    }
    return superFrame;
}
36 голосов
/ 30 мая 2011

Для дальнейшего использования, самый чистый и простой способ скрыть треугольник раскрытия в расширяемых NSOutlineView элементах - это реализовать outlineView: shouldShowOutlineCellForItem: метод NSOutlineViewDelegate протокол вашего делегата:

-(BOOL)outlineView:(NSOutlineView *)outlineView shouldShowOutlineCellForItem:(id)item
{
    // replace this with your logic to determine whether the
    // disclosure triangle should be hidden for a particular item
    return [item hidesDisclosureTriangle];
}
8 голосов
/ 20 мая 2013

Мне пришлось объединить два подхода, описанных выше, потому что только outlineView:shouldShowOutlineCellForItem: не удаляет пространство, зарезервированное для треугольников раскрытия (оно само удаляет треугольники).

Делегат:

- (BOOL)outlineView:(NSOutlineView *)outlineView shouldShowOutlineCellForItem:(id)item {
    return NO;
}

Подкласс NSOutlineView:

@implementation ExpandedOutlineView

#define kOutlineCellWidth 11
#define kOutlineMinLeftMargin 6

- (NSRect)frameOfCellAtColumn:(NSInteger)column row:(NSInteger)row {
    NSRect superFrame = [super frameOfCellAtColumn:column row:row];
    if (column == 0) {
        // expand by kOutlineCellWidth to the left to cancel the indent
        CGFloat adjustment = kOutlineCellWidth;

        // ...but be extra defensive because we have no fucking clue what is going on here
        if (superFrame.origin.x - adjustment < kOutlineMinLeftMargin) {
            NSLog(@"%@ adjustment amount is incorrect: adjustment = %f, superFrame = %@, kOutlineMinLeftMargin = %f", NSStringFromClass([self class]), (float)adjustment, NSStringFromRect(superFrame), (float)kOutlineMinLeftMargin);
            adjustment = MAX(0, superFrame.origin.x - kOutlineMinLeftMargin);
        }

        return NSMakeRect(superFrame.origin.x - adjustment, superFrame.origin.y, superFrame.size.width + adjustment, superFrame.size.height);
    }
    return superFrame;
}

@end

Результат:

Screenshot of NSOutlineView with no top-level indentation

2 голосов
/ 23 ноября 2010

Использовать PXSourceList .Это стиль, который вы ищете с очень хорошим API.

0 голосов
/ 22 октября 2018

Правильный способ указать намерение для каждого уровня - переписать indentationPerLevel NSOutlineView.

class NoIndentOutlineView: NSOutlineView {
    override var indentationPerLevel: CGFloat {
        get {
            return 0;
        }
        set {
            // Do nothing
        }
    }
}

Это позволит убедиться, что у детей тот же отступ, что и у родителей.

0 голосов
/ 13 декабря 2017

Я попробовал это в Swift. Это просто работает. Я не знаю, правильно ли это. В Obj-C должен быть эквивалент:

extension NSTableRowView {
    override open func layout() {
        super.layout()
        if let cell = subviews.first as? NSTableCellView, cell.objectValue is <YourHeaderCellClass> {
            subviews.first?.setFrameOrigin(NSZeroPoint)
        }
    }
}

Убедитесь, что вы возвращаете элемент YourHeaderCellClass в методе источника данных.

func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...