3

我创建了一个子类NSTextField,它根据它包含的文本改变它的高度。我现在想将它插入另一个视图(an NSTableCellView)并根据文本字段的高度调整视图大小。

我想使用的-(NSSize)fittingSize方法,NSView但不幸的是它似乎没有调用fittingSize它的子视图的方法,也没有调用它们的intrinsicContentSize方法。

这是我用于NSTableCellView子类的代码:

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setTranslatesAutoresizingMaskIntoConstraints:NO];
        self.expandingTextField = [[JSExpandingTextField alloc] init];
        [self addSubview:self.expandingTextField];
        [self removeConstraints:self.constraints];
        NSDictionary *row = NSDictionaryOfVariableBindings(expandingTextField);
        [self addConstraints:[NSLayoutConstraint
                              constraintsWithVisualFormat:@"V:|-20-[expandingTextField]-28-|"
                              options:0 metrics:nil views:row]];
    }

    return self;
}

- (NSSize)fittingSize
{
    return [super fittingSize];
}

我在这里重写该fittingSize方法只是为了放置一个断点或一个NSLog.

这是提供表格单元格高度的表格视图委托的代码:

- (JSDynamicTableCellView *)dummyCell
{
    if (!_dummyCell) {
        _dummyCell = [[JSDynamicTableCellView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 100, 100)];
    }
    return _dummyCell;
}

- (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row
{
    self.dummyCell.expandingTextField.stringValue = @"Test";
    NSLog(@"Cell size %@",NSStringFromSize([self.dummyCell fittingSize]));
    return [self.dummyCell fittingSize].height;
}

所有这些总是返回 69 的 dummyCell 高度,与单元格中扩展文本字段的大小无关。

问题是:“fittingSize”方法如何计算出其子视图的大小?它应该调用他们的“fittingSize”或“ntrinsicContentSize”方法还是别的什么?

4

2 回答 2

10

fittingSize概念上很简单。它收集已添加到您的视图或其子视图之一(递归)的所有约束,然后仅根据这些约束确定视图的大小。您可以将其视为确定足够大以显示该视图层次结构的内容的最小尺寸。

编辑:我们需要在这里非常清楚。fittingSize返回最小值,对于未完全指定的任何维度,将返回 0。例如,如果省略了将视图绑定到其父视图底部的垂直约束,则拟合高度将为 0。

编辑:我刚刚意识到您可能会遇到什么:fittingSize正在计算文本字段,就好像它只是一根长线,不会换行。您可以通过给它一个带有一个或多个换行符的字符串值来确认这一点:现在高度应该更大!

那么如何解决这个问题呢?好吧,你有一个文本字段,你给它内容,你想知道它的高度。但如果文本字段换行,高度将取决于宽度:使其更窄,文本字段将换行更多行,因此会消耗更多高度。因此,为了测量换行文本字段的首选高度,您必须告诉它要换行的宽度。

在 OS X Mountain Lion 和 iOS 6 上,您可以使用该[NSTextField setPreferredMaxLayoutWidth:]方法执行此操作。例如,如果您想根据宽度 100 计算高度,您可以调用[textField setPreferredMaxLayoutWidth:100]; 现在fittingSize将报告文本字段的高度,基于它以 100 的宽度换行。

顺便说一句,这是一个坏主意:

[self removeConstraints:self.constraints];

因为它消除了系统其他部分添加的约束。您应该只删除您在代码或 IB 中创建的约束。

于 2012-12-29T04:38:25.960 回答
-6

试试这个(点击xib或storyboard的背景)

在此处输入图像描述

于 2012-12-28T10:54:07.797 回答