NSBrowser изображение не отображается в ячейке

Я использую представление NSBrowser, чтобы показать список файлов и папок в приложении типа поиска. Я использую новый API Item Base для NSBrowser.

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

Код:

// This is a utility method to find the parent item for a given column. The item based API eliminates the need for this method.
- (FileSystemNode *)parentNodeForColumn:(NSInteger)column {
    if (_rootNode == nil) {
        _rootNode = [[FileSystemNode alloc] initWithURL:[NSURL fileURLWithPath:@"/Users/kiritvaghela"]];
    }

    FileSystemNode *result = _rootNode;
    // Walk up to this column, finding the selected row in the column before it and using that in the children array
    for (NSInteger i = 0; i < column; i++) {
        NSInteger selectedRowInColumn = [_browser selectedRowInColumn:i];
        FileSystemNode *selectedChildNode = [result.children objectAtIndex:selectedRowInColumn];
        result = selectedChildNode;
    }

    return result;
}

- (void)browser:(NSBrowser *)browser willDisplayCell:(NSBrowserCell *)cell atRow:(NSInteger)row column:(NSInteger)column {
    FileSystemNode *parentNode = [self parentNodeForColumn:column];
    FileSystemNode *childNode = [parentNode.children objectAtIndex:row];

    [cell setTitle:childNode.displayName];

    cell.image = node.icon;

}

Пример Apple SimpleCocoaBrowser

0 ответов

Хотя значением по умолчанию для cellPrototype является NSBrowserCell, оно, похоже, использует NSTextFieldCell. (macOS 10.14)

Чтобы это исправить, вам нужно создать подкласс NSBrowserCell и установить подкласс как cellClass: [_browser setCellClass:[BrowserCell class]];

@interface BrowserCell : NSBrowserCell
@end

@implementation BrowserCell
@end

Еще одна проблема - листовой индикатор. Он будет показан дважды, один раз из ячейки и один раз из браузера.

- (void)browser:(NSBrowser *)browser willDisplayCell:(NSBrowserCell *)cell atRow:(NSInteger)row column:(NSInteger)column {
    FileSystemNode *parentNode = [self parentNodeForColumn:column];
    FileSystemNode *childNode = [parentNode.children objectAtIndex:row];

    NSImage *image = node.icon;
    [image setSize:NSMakeSize(16, 16)];

    cell.image = cell.image;
    cell.leaf = YES;
}

радар://47175910

Использование NSBrowserCell, описанное в ответе catlan, работает, но NSTextField ведет себя иначе при рисовании фона выбранной ячейки, чем NSBrowserCell. Пока мышь щелкает / перетаскивается в другой столбец, NSBrowserCell будет рисовать фон выбранной ячейки, который вместо этого был синим как серый (Finder тоже это делает). Однако NSTextFieldCell остается синим при щелчке мыши и становится серым при отпускании. Поскольку NSBrowserCell не рисует листовой индикатор, эта область ячейки по-прежнему будет иметь синюю подсветку, поэтому ячейка имеет синий и серый цвет фона одновременно. Это кратко, так как это только при нажатии, но это выглядит неправильно.

Чтобы заставить NSBrowserCell вести себя как NSTextFieldCell, потребовались некоторые обратные разработки и частные API, поэтому я решил, что правильнее всего было бы просто создать подкласс NSTextFieldCell и нарисовать в нем значок. Код выглядит примерно так,

@implementation BrowserTextFieldCell
- (void)drawInteriorWithFrame:(NSRect)cellFrame controlView:(NSView *)controlView
{
    __auto_type textFrame = cellFrame;
    __auto_type inset = kIconHorizontalPadding * 2 + kIconSize;

    textFrame.origin.x += inset;
    textFrame.size.width -= inset;
    [super drawInteriorWithFrame:textFrame inView:controlView];

    [self drawIconWithFrame:cellFrame];
}

- (void)drawIconWithWithFrame:(NSRect)cellFrame
{
    NSRect iconFrame = cellFrame;
    iconFrame.origin.x += kIconPadding;
    iconFrame.size = NSMakeSize(kIconSize, kIconSize);
    [self.iconImage drawInRect:iconFrame];
}
@end
Другие вопросы по тегам