2

tableView:heightOfRow:の理解を考え出そうとして、壁に頭をぶつけてきました。助けが必要だと思います。行内のtextViewに対して動的な行の高さを実行したいのですが、アプローチを理解できないようです。私は見つけることができるすべてを読みました、それは本当に多くはありません。このメソッドを使用して、行のサイズを希望どおりに設定できますが、テーブルのサイズが変更されている場合に限ります。表示されていない行は、表示されてテーブルのサイズが変更されるまで、適切なサイズになりません。

tableView:didAddRowView:forRowメソッドを追加しましたが、同じ基本的な考え方を使用すると、行サイズが1行になります。同じコードであっても、tableView:heightOfRow:と同じようには機能しません。textViewの境界を設定するtableView:didAddRowView:forRowメソッドがどういうわけかスケーリングされていると思います。

これが私の(うまくいけば関連する)コードです:

- (CGFloat)tableView:(NSTableView *)tv heightOfRow:(NSInteger)row {
    if (tv == dataTableView) {
        NSInteger valueCol = [tv columnWithIdentifier:@"value"];
        NSTableCellView *valueView = [tv viewAtColumn:valueCol row:row makeIfNecessary:NO];

        if (valueView) {
            // Working on the interesting column and this row is visible
            NSRect bounds = [[valueView textField] bounds];
            id value = [[valueView textField] stringValue];

            NSFont *fieldFont = [[valueView textField] font];
            CGFloat adjustedHeight = [value heightForWidth:bounds.size.width font:fieldFont];
            CGFloat rowHeight = [tv rowHeight];
            if (adjustedHeight <= rowHeight) adjustedHeight = rowHeight;

            return adjustedHeight;
        }
    }
    return [tv rowHeight];
}


- (void)tableView:(NSTableView *)tv didAddRowView:(NSTableRowView *)rowView forRow:(NSInteger)row {
    if (tv == dataTableView) {
        NSInteger valueCol = [tv columnWithIdentifier:@"value"];
        NSTableCellView *colView = [rowView viewAtColumn:valueCol];
        NSRect textFieldViewBounds = [[colView textField] bounds];
        NSTextField *colTextField = [colView textField];
        NSFont *colFont = [colTextField font];
        id value = [colTextField stringValue];
        CGFloat newHeight = [value heightForWidth:textFieldViewBounds.size.width font:colFont];
        NSSize colViewSize = colView.bounds.size;
        colViewSize.height = newHeight;
        textFieldViewBounds.size.height = newHeight;
        [colTextField setBounds:textFieldViewBounds];
    }
}

更新:新しいコードはより適切に機能していますが、初期ロード時および場合によってはスクロール時にグリッチがあります:

- (CGFloat)tableView:(NSTableView *)tv heightOfRow:(NSInteger)row {
    if (tv == dataTableView) {
        NSInteger valueCol = [tv columnWithIdentifier:@"value"];
        NSTableCellView *valueView = [tv viewAtColumn:valueCol row:row makeIfNecessary:NO];

        if (valueView) {
            // Working on the interesting column
            NSRect bounds = [[valueView textField] bounds];
            id value = [[valueView textField] stringValue];

            NSFont *fieldFont = [[valueView textField] font];
            CGFloat adjustedHeight = [value heightForWidth:bounds.size.width font:fieldFont];
            CGFloat rowHeight = [tv rowHeight];
            if (adjustedHeight <= rowHeight) adjustedHeight = rowHeight;

            return adjustedHeight;
        }
    }
    return [tv rowHeight];
}


- (void) tableView:(NSTableView *)tv didAddRowView:(NSTableRowView *)rowView forRow:(NSInteger)row {
    if (tv == dataTableView) {
        [dataTableView noteHeightOfRowsWithIndexesChanged:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(row, 1)]];
    }
}
4

1 に答える 1

0

あなたのコードから、テキストフィールドセルの行数に基づいて行の高さを変更したいと思いますよね?列やテーブルのサイズを変更したり、新しいテキストを入力したりすると、高さが変わるはずです...?

IMO -tableView:didAddRowViewForRow: で何もする必要はありません: それには遅すぎて、行ビューはすでに最終的な高さになっているはずです。そこにビュー フレームを変更しようとすると、バグの例外が発生する可能性があります。テキスト フィールドは NSTableCellView にあるため (適切なレイアウト制約があると仮定すると、デフォルトのもので問題ないはずです)、IB のデザインと -tableView:heigthOfRow によって返される行の高さを考慮して、意図したとおりに表示されるはずです。

-tableView:heigthOfRow: は、実際に行の高さを決定する必要がある方法です。ただし、 to メソッドが呼び出されるすべての行に対して適切な値を返す必要があります。そうしないと、スクロール中に表示されている四角形に入ったときに、行が適切な高さに表示されません。したがって、viewAtColumn メソッドの makeIfNecessary: 引数には YES を選択します。

次に、必要に応じてテーブルの行の高さを更新する必要があります (列のサイズ変更、ビューのサイズ変更、新しいテキストの入力など)。これは、たとえば -tableViewColumnDidResize (userinfo ディクショナリを使用してサイズ変更された列を取得する) で、またはテキスト フィールドが編集されたときに実行できます。そこで、テーブル ビューで -noteHeightOfRowsWithIndexesChanged: を呼び出す必要があります。列のサイズが変更された場合、すべての行に対してそれを呼び出すと、-tableView:heigthOfRow: はすべての高さを返します。テキスト フィールドが編集されている場合は、その行に対してのみ呼び出すことができます (ただし、すべての行に対してメソッドを呼び出すこともできます)。

お役に立てば幸いです。

于 2012-12-14T09:27:31.897 に答える