NSTableView:如何正确调整单元格中的文本大小

时间:2014-01-10 12:48:33

标签: cocoa nstableview nstablecellview

我需要在NSTableView(基于视图的模式)中增加字体大小,以便在我的应用程序的某种演示文稿中提供更好的可读性。

更改字体在- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row

中正常工作
    NSTableCellView *cellView = [tableView makeViewWithIdentifier:identifier owner:self];
    [cellView.textField setFont:self.tableFont];
    cellView.textField.stringValue = rowData[row];
    [cellView.textField setNeedsDisplay:YES];

我还使用- (CGFloat) tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row更新rowHeight,这也有效:

- (CGFloat) tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row {
    if (self.tableFont) {
        NSLog(@"Setting row height to %.1f", [self.tableFont pointSize]+8);
        return [self.tableFont pointSize] + 8;
    }
    return [NSFont systemFontSize] + 8;
}

(可能有更优雅的方法来确定正确的高度)

现在,这是我的问题: 我确实看到字体被更改了。我还看到rowHeight被更改(当我使用备用行着色时很好看)。但是单元格中的文本似乎被剪裁到它的旧高度(可能是17个像素),所以对于更大的字体大小我只看到写入的顶部,然后是一些空白区域,然后再看到下一行的上半部分

对我来说,看起来有些视图会将NSTableViewCell剪辑到旧的高度......我已经玩过将帧和边界设置为不同的值,但这并没有改变任何东西:

    NSRect rect = [cellView.textField frame];
    rect.origin.y = 1;
    rect.size.height = [self.tableFont pointSize] + 6;
    [[cellView.textField cell] setFrame:rect];
    [cellView.textField setFrame:rect];
    [cellView.textField setBounds:rect];
    [cellView.textField setNeedsDisplay:YES];
    [cellView setFrame:rect];
    [cellView setBounds:rect];
    [cellView setNeedsDisplay:YES];

我有点迷失在这里......我想我错过了一些简单的东西,但我不知道在哪里看......

谢谢, 扬

1 个答案:

答案 0 :(得分:2)

你必须确保你的约束被设置,这样你的NSTextField可以在自动布局传递被击中时自动增长 - 不应该对NSTextField的高度有任何约束,因为它的内在高度基于fontSize。

此外,在基于视图的模式中,还有一个错误,其中cellView的'textField'和'imageView'出口被特别处理:在NSTableCellView中实际上将框架DIRECTLY设置在其textField和imageView的-viewWillDraw中,忽略横向约束和打破自己的布局规则。 (这是作为雷达11713245和15359487提交的。)

这是我在10.8和10.9的自定义NSTableCellView类中用来解决这个错误的代码。请注意,在我的情况下,我只需要重置字段的x偏移量:

#pragma mark NSView

- (void)viewWillDraw;
{
    const NSRect imageViewFrame = self.imageView.frame, textFieldFrame = self.textField.frame;

    [super viewWillDraw]; // NSTableCellView in  source list-mode outline view will apply custom metrics and positioning here by calling -_doStandardRowSizeStyleLayout, which manually calls setFrame: on the textField and imageView, screwing up our autolayout...

    // ...so put the x offsets back the way we really wanted them, dammit (Radar 11713245, 15359487)
    if (imageViewFrame.origin.x != self.imageView.frame.origin.x)
        [self.imageView setFrameOrigin:(NSPoint){imageViewFrame.origin.x, self.imageView.frame.origin.y}];

    if (textFieldFrame.origin.x != self.textField.frame.origin.x)
        [self.textField setFrameOrigin:(NSPoint){textFieldFrame.origin.x, self.textField.frame.origin.y}];
    if (textFieldFrame.size.width != self.textField.frame.size.width)
        [self.textField setFrameSize:(NSSize){textFieldFrame.size.width, self.textField.frame.size.height}];
}