3

NSTextField含まれるテキストに応じて高さが変わるサブクラスを作成しました。別のビュー ( NSTableCellView) に挿入し、テキスト フィールドの高さに応じてビューのサイズを変更したいと考えています。

-(NSSize)fittingSizeのメソッドを使用したいのですが、残念ながら、そのサブビューのメソッドもそのメソッドもNSView呼び出していないようです。fittingSizeintrinsicContentSize

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 のダミーセルの高さを返します。

問題は、「fittingSize」メソッドがそのサブビューのサイズをどのように把握するかです。「fittingSize」または「ntrinsicContentSize」メソッドを呼び出す必要がありますか、それとも別のものですか?

4

2 に答える 2

10

fittingSize概念的に単純です。ビューまたはそのサブビューの 1 つに (再帰的に) 追加されたすべての制約を収集し、それらの制約のみに基づいてビューのサイズを決定します。これは、そのビュー階層の内容を表示するのに十分な大きさの最小サイズを決定するものと考えることができます。

編集:ここで明確にする必要があります。fittingSize最小値を返し、完全に指定されていない次元については 0 を返します。たとえば、ビューをそのスーパービューの下部に結び付ける垂直方向の制約が省略されている場合、適合した高さは 0 になります。

編集:おそらくあなたが遭遇していることに気付きました:fittingSizeテキストフィールドを単なる1行のように計算していて、それは折り返されていません。これは、1 つ以上の改行を含む文字列値を指定することで確認できます。これで、高さが大きくなるはずです!

では、これを修正する方法は?さて、あなたはテキスト フィールドを持っていて、それにコンテンツを与え、その高さを知りたいと思っています。しかし、テキスト フィールドが折り返される場合、高さは幅に依存します。幅を狭くすると、テキスト フィールドはより多くの行に折り返されるため、より多くの高さを消費します。そのため、折り返しテキスト フィールドの適切な高さを測定するには、折り返しの幅を指定する必要があります。

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 またはストーリーボードの背景をクリックします)

ここに画像の説明を入力

于 2012-12-28T10:54:07.797 に答える