7

可変の高さのカスタムテーブルセルを使用してUITableViewを作成しています。その高さは、含まれている複数行のUILabelのサイズによって決まります。デリゲートメソッドを接続し、を使用してtableView:heightForRowAtIndexPath:最終的な高さを正しく計算しましたsizeWithFont:constrainedToSize:

奇妙な問題に遭遇しました。データソースメソッドtableView:cellForRowAtIndexPath:が呼び出されるまでに、行ごとの正しい高さは上記のようにすでに決定されていますが、セルのフレームがその高さと一致していません。代わりに、frame.size.heightセルのプロパティは、高さではなく、テーブルビューのデフォルトのセルの高さ(86 px、Interface Builderで設定したように、含まれているUILabelにテキストが1行しかない場合の正しい高さ)です。そのtableView:heightForRowAtIndexPath:インデックスパスに対して正しいと判断されました。

私はcellForRowAtIndexPath:デキューを使用してセルを生成しています。つまり、

// Using storyboards, this never returns nil, no need to check for it
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:@"SomeIdentifier"];
NSLog(@"%f", cell.frame.size.height); // 86, not correct if the cell contains a multi-line UILabel

したがって、iOSが舞台裏で何をしていても、デキューはセルのフレームプロパティを計算された高さに一致するように設定していないようです。これ自体はそれほど驚くべきことではなく、デキューはセルインスタンスのジオメトリではなく、セルインスタンスに関係します。ただし、セルは正しくレンダリングされるため、heightプロパティはどこかに設定されていますが、その後に発生しcellForRowAtIndexPath:ます。

つまり、最初にテーブルビューにデータを入力するcell.frame.size.heightと、リストを下にスクロールしたときに初めて表示されるすべてのセルで86になります。正しいジオメトリは、cellForRowAtIndexPath:表示される前に各行の最初の後に設定されるため、上にスクロールすると、再利用後に表示される各セルの高さプロパティが正しくなります。

この後、テーブルビューを自由に前後にスクロールでき、その時点以降、各セルの高さプロパティは正しいままです。

デキューベースの再利用が発生する前に、最初に正しいセルの高さを取得する正しい方法は何ですか?テーブルセルのサブビューの位置を少し変更するには、これが必要です。手動で呼び出してから、新しく作成したCustomCellインスタンスのフレームをその高さに一致するように手動で設定する必要がありheightForRowAtIndexPath:ますcellForRowAtIndexPath:か?これは冗長に思えます。この冗長性を回避するために、セルが間違ったフレーム高で初めて作成されたときと、後で正しいフレーム高でデキューされたときを検出するメカニズムを作成する必要があります。

ですから、誰かがこの背後にある論理に光を当てることができれば、私はそれを感謝します。

4

3 に答える 3

5

Flexoが示唆しているように、これに自分で答える方が、質問に編集を追加するよりも明らかに優れています。だから、これが答えとしての前の編集です:


気にしないでください、私はドキュメントをもっとよく読むべきです。tableView:willDisplayCell:forRowAtIndexPath:のメソッドで正しいフレームを取得できるUITableViewDelegateので、ではなく、設定されている正しいフレームに依存するサブビューのカスタマイズを行うための正しい場所ですcellForRowAtIndexPath:

ただし、ドキュメントがこれを言っているのは興味深いことです。

戻り後delegate、テーブルビューは、プロパティalphaframeプロパティのみを設定し、行をスライドインまたはスライドアウトするときに行をアニメーション化する場合にのみ設定します。

...このデリゲートメソッドが呼び出されたときに正しいフレームがすでに存在するため。しかしとにかく、問題は解決しました。

于 2012-08-10T13:12:04.700 に答える
0

セルがであることに注意してくださいUIView。したがって、オーバーライドlayoutSubviewsは、正しいフレームを取得し、サブビューのサイズ/位置を調整するための有効な方法でもあります。を呼び出すことを忘れないでください[super layoutSubviews]

于 2014-04-15T07:20:24.957 に答える
0

私が見つけた最も簡単な方法はcell.layoutIfNeeded()、セルでセットアップを行う前に電話をかけることでした。これにより、すべてのレイアウト制約が計算され、フレームが設定されます。

于 2017-04-05T08:19:30.757 に答える