1. ホーム
  2. objective-c

[解決済み] 動的な高さを持つ行を持つビューベースのNSTableView

2023-03-25 15:47:15

質問

アプリケーションで、ビューベースの NSTableView を持つアプリケーションがあります。 このテーブルビューの内部には、複数行からなるコンテンツを持つセルを持つ行があり、そのセルは NSTextField で構成されるセルがあり、ワードラップが有効になっています。 のテキスト内容によっては NSTextField のテキスト内容によって、セルを表示するために必要な行の大きさは異なります。

を実装できることは分かっているのですが NSTableViewDelegate メソッド - tableView:heightOfRow: を使って高さを返しますが、高さは、このメソッドで使用されている単語の折り返しに基づいて決定されます。 NSTextField . のワードラッピングは NSTextField がどの程度広いかに基づいています。 NSTextField の幅によって決まります。 NSTableView .

そこで質問なのですが、このための良いデザインパターンは何でしょうか? 私が試みるすべてが、複雑な混乱に終わるように思えます。TableViewはセルをレイアウトするためにセルの高さを知る必要があるので......そして NSTextField は単語の折り返しを決定するためにそのレイアウトの知識を必要とし... そしてセルはその高さを決定するために単語の折り返しの知識を必要とします... それは円形の混乱です... そしてそれは私を駆り立てています。 気が狂いそうです。 .

提案ですか?

もしそれが重要なら、最終結果には編集可能な NSTextFields があり、その中のテキストに合うようにサイズを変更します。 私はすでにこれをビューレベルで動作させていますが、テーブルビューはまだセルの高さを調整しません。 高さの問題を解決したら、テーブルビューで - noteHeightOfRowsWithIndexesChanged メソッドを使用して、テーブルビューに高さの変更を通知します... しかし、それはまだ高さのためにデリゲートに尋ねるつもりです... したがって、私の困惑。

事前にありがとうございます。

どのように解決するのですか?

これは、鶏と卵の問題です。テーブルが行の高さを知る必要があるのは、それが与えられたビューがどこに位置するかを決定するからです。しかし、あなたはビューがすでに存在し、それを使用して行の高さを把握できるようにしたいのです。では、どちらが先なのでしょうか?

答えは NSTableCellView (または、あなたが"セルビュー" として使用している任意のビュー) を、ビューの高さを測定するためだけに残しておくことです。その際 tableView:heightOfRow: デリゲートメソッドで、'row' のモデルにアクセスし、'row' の値を objectValue の上に NSTableCellView . そして、ビューの幅をテーブルの幅に設定し、(どのようにでも) そのビューに必要な高さを計算します。その値を返します。

を呼び出さないようにしましょう。 noteHeightOfRowsWithIndexesChanged: をデリゲートメソッド内から呼び出すことはできません。 tableView:heightOfRow: または viewForTableColumn:row: ! というのは良くないし、メガ・トラブルの原因になる。

高さを動的に更新するには、テキストの変更に反応し(ターゲット/アクションを介して)、そのビューの計算された高さを再計算する必要があります。さて、動的に変更しないように NSTableCellView の高さ(または、"セルビュー" として使用している任意のビュー)を動的に変更しないでください。テーブルの はそのビューのフレームを制御する必要があり、それを設定しようとすると、テーブルビューと戦うことになります。代わりに、高さを計算したテキスト フィールドのターゲット/アクションで noteHeightOfRowsWithIndexesChanged: を呼び出すと、テーブルがその個々の行のサイズを変更できるようになります。自動サイズ調整マスクがサブビューで正しく設定されていると仮定すると (すなわち、サブビューの NSTableCellView のサブビュー)、うまくリサイズされるはずです。そうでない場合は、まずサブビューのリサイズマスクに取り組み、可変の行の高さで物事を正しく行うようにします。

を忘れないでください。 noteHeightOfRowsWithIndexesChanged: はデフォルトでアニメーションします。これをアニメーションさせないようにするには

[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:0];
[tableView noteHeightOfRowsWithIndexesChanged:indexSet];
[NSAnimationContext endGrouping];

PS: 私はスタックオーバーフローよりもApple Dev Forumsに投稿された質問に多く応答しています。

PSS: NSTableViewをベースにしたビューを書きました。