Objective c NSOutlineView设置最大列宽及其内容

Objective c NSOutlineView设置最大列宽及其内容,objective-c,cocoa,macos,nstableview,nsoutlineview,Objective C,Cocoa,Macos,Nstableview,Nsoutlineview,是否可以设置NSOutlineView的NSTableColumn最大宽度及其内容 提前谢谢。八个月后,我希望你能选择一些足够好的宽度。然而,如果有人需要这类东西,这里有一个工作方法。它仍然有很大的局限性,因此请密切关注评论 NSTableView和NSOutlineView背后的整个理念是,它们在需要之前不会实例化其内容。这有利于提高效率,但意味着它们会积极阻止读取每个单元格的属性。要根据列的内容调整列的大小,您确实需要查看每个单元格,并测量其大小。这永远无法很好地扩展 也就是说,如果您有一个

是否可以设置NSOutlineView的NSTableColumn最大宽度及其内容


提前谢谢。

八个月后,我希望你能选择一些足够好的宽度。然而,如果有人需要这类东西,这里有一个工作方法。它仍然有很大的局限性,因此请密切关注评论

NSTableView和NSOutlineView背后的整个理念是,它们在需要之前不会实例化其内容。这有利于提高效率,但意味着它们会积极阻止读取每个单元格的属性。要根据列的内容调整列的大小,您确实需要查看每个单元格,并测量其大小。这永远无法很好地扩展

也就是说,如果您有一个非常小的NSOutlineView,并且它都是文本,并且该文本来自数据源,那么这应该可以工作

// sizeOutlineViewToContents
// This looks at the cells in an NSOutlineView and shrinks its rows and columns to fit, with the following limitations:
// 1. The data must come from an NSOutlineViewDataSource.  If the NSOutlineView gets its data through bindings, it will throw an exception.
// 2. Text and images will be handled, but other cell types will shrink to the column minimum width.
// 3. Only visible cells will be measured.  Any collapsed cells will be ignored.
// 4. This function has to read the contents of every cell and measure the size of their text.  This will be slow, and scale badly.  Only use on small views, with a few thousand cells at most.
- (void) sizeOutlineViewToContents:(NSOutlineView*) outlineView;
{
    if (outlineView)
    {
        NSInteger rowCount = [outlineView numberOfRows];
        CGFloat maxHeight = 0;

        // This implementation doesn't work if the OutlineView data arrive via bindings.  If you want to make it work, be my guest.
        if (![outlineView dataSource])
        {
            @throw [NSException exceptionWithName:@"DataSourceMissingException" reason:@"autosizeColumnsOfOutlineView only works when the outlineView has a dataSource." userInfo:nil];
        }
        else
        {
            for (NSTableColumn *tableColumn in [outlineView tableColumns])
            {
                // Start with the minimum width already specified for the column.
                CGFloat maxWidth = [tableColumn minWidth];

                // Allow the space needed for the cell.
                if (maxWidth < [[tableColumn headerCell] cellSize].width)
                    maxWidth = [[tableColumn headerCell] cellSize].width;

                for (NSInteger rowIndex = 0; rowIndex<rowCount; rowIndex++)
                {
                    // Find the formatting information used for this cell.
                    // For most tables, the generic [tableColumn dataCell] would tell us the formatting for all cells, and be faster.
                    // Given the way we read the header size, it may be tempting to read the cell size, but this will often just return the size of the most recently displayed cell.
                    NSCell *cell = [tableColumn dataCellForRow:rowIndex];

                    // Obtain the actual data in this cell from the dataSource.
                    id rowItem = [outlineView itemAtRow:rowIndex];
                    id cellObject = [[outlineView dataSource] outlineView:outlineView objectValueForTableColumn:tableColumn byItem:rowItem];

                    // If the cell has a formatter, assume it knows what to do with the object.
                    NSFormatter *cellFormatter = [cell formatter];
                    if (cellFormatter)
                        cellObject = [cellFormatter stringForObjectValue:cellObject];

                    // Text is already the difficult one.
                    if ([cellObject isKindOfClass:[NSString class]])
                    {
                        NSDictionary *cellTextAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                                            [cell font], NSFontAttributeName,
                                                            nil];

                        NSString *cellText = cellObject;
                        // Find the space needed to display the cell text.
                        CGSize size = [cellText sizeWithAttributes:cellTextAttributes];

                        // If the current column contains the outline view disclosure arrows, allow for the space needed for indentation.
                        if (tableColumn == [outlineView outlineTableColumn])
                            size.width += ([outlineView levelForRow:rowIndex]+1)*[outlineView indentationPerLevel];

                        // Cells have a small amount of additional space between them, defined by the outline view.
                        size.width+=[outlineView intercellSpacing].width;
                        size.height+=[outlineView intercellSpacing].height;
                        // There seems to be one extra pixel needed to display the text at its full width.  I'm not sure where this comes from.
                        size.width+=1;

                        // Update the maxima found.
                        if (maxWidth < size.width)
                            maxWidth = size.width;
                        if (maxHeight < size.height)
                            maxHeight = size.height;
                    }
                    else if ([cellObject isKindOfClass:[NSImage class]])
                    {
                        // Images just need their exact size.
                        NSImage *cellImage = cellObject;
                        CGSize size = [cellImage size];

                        // Update the maxima found.
                        if (maxWidth < size.width)
                            maxWidth = size.width;
                        if (maxHeight < size.height)
                            maxHeight = size.height;
                    }
                }

                // Having found the widest cell, apply it to the column.
                [tableColumn setWidth:maxWidth];
            }
        }
        // Having found the highest cell overall, apply it to the table.
        [outlineView setRowHeight:maxHeight];
    }
}
//SizeOutlineViewToContent
//这将查看NSOutlineView中的单元格,并缩小其行和列以适应,但有以下限制:
// 1. 数据必须来自NSOutlineViewer数据源。如果NSOutlineView通过绑定获取数据,它将抛出异常。
// 2. 文本和图像将被处理,但其他单元格类型将缩小到列的最小宽度。
// 3. 只测量可见的单元格。任何折叠的单元格都将被忽略。
// 4. 此函数必须读取每个单元格的内容并测量其文本的大小。这将是缓慢的,规模严重。只能在小视图上使用,最多只有几千个单元格。
-(void)SizeOutlineViewToContent:(NSOutlineView*)outlineView;
{
如果(大纲视图)
{
NSInteger rowCount=[outlineView numberOfRows];
CGFloat maxHeight=0;
//如果OutlineView数据通过绑定到达,则此实现不起作用。如果您想让它起作用,请便。
如果(![outlineView数据源])
{
@抛出[NSException Exception With Name:@“DataSourceMissingException”原因:@“autosizeColumnsOfOutlineView仅在outlineView具有数据源时工作。”userInfo:nil];
}
其他的
{
对于(在[outlineView tableColumns]中的NSTableColumn*tableColumn)
{
//从已为列指定的最小宽度开始。
CGFloat maxWidth=[tableColumn minWidth];
//留出单元格所需的空间。
如果(maxWidth<[[tableColumn headerCell]cellSize].width)
maxWidth=[[tableColumn headerCell]单元格大小].width;

对于(NSInteger rowIndex=0;rowIndex关于选择足够好的宽度:我将我的
TableViewCell
的宽度设置为10000,这是XCode/Cocoa允许的最大值。这修复了在几个字符后用省略号截断项目的问题


我在导航器区域的
表格列
对象中的
表格单元格视图
项下选择了
表格视图单元格
。然后,在实用程序区域,我选择了大小检查器,并将视图窗格中的宽度字段设置为10000。

谢谢!我在为我的视图制作类似功能时缺少的键基于大纲的视图正在添加所需的缩进(levelForRow:*indentationPerLevel
部分)。我应该在委托方法中的何处调用此方法?