0

画像、タイトル、説明を持つ UITableViewCell サブクラスがあります。説明の内容の長さに応じてセルの高さのサイズを変更することになっています。つまり、セルが 5 行を超える場合は、それが続くまで拡張する必要があります (+ 画像などの他のサブビュー)。

次に来るセルは、その後にのみ開始する必要があります。

固定行の高さ = 160 を持つ xib からインスタンス化された UITableViewCell サブクラスがあります。

これはかなり標準的な要件であることはわかっていますが、ガイドラインが見つかりません。

私はすでに次のようにlayoutSubViewsを拡張しました:

- (void) layoutSubviews
{
    [self resizeCellImage];
}

- (void) resizeCellImage
{
    CGRect descriptionRect = self.cellDescriptionLabel.frame;
    CGRect imageRect = self.cellImageView.frame;

    float descriptionBottomEdgeY = descriptionRect.origin.y +  descriptionRect.size.height;
    float imageBottomEdgeY = imageRect.origin.y + imageRect.size.height;

    if (imageBottomEdgeY >= descriptionBottomEdgeY)
        return;

    //push the bottom of image to the bottom of description
    imageBottomEdgeY = descriptionBottomEdgeY;

    float newImageHeight = imageBottomEdgeY - imageRect.origin.y;
    imageRect.size.height = newImageHeight;
    self.cellImageView.frame = imageRect;

    CGRect cellFrame = self.frame;
    cellFrame.size.height = imageRect.size.height + imageRect.origin.y + 5;

    CGRect contentFrame = self.contentView.frame;
    contentFrame.size.height = cellFrame.size.height - 1;
    self.contentView.frame = contentFrame;

    self.frame = cellFrame;
}

説明が画像よりも高い場合は、画像とセルの高さを説明に合わせてサイズ変更する必要があることがわかります。

ただし、これを実行してこのコードを呼び出すと、次のようになります。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    cell.cellDescriptionLabel.text = @"Some long string";
    [cell.cellDescriptionLabel sizeToFit];
    [cell setNeedsLayout];

    return cell;    
}

呼び出しによりセル フレームが変更されている間layoutSubViews、他のセルはそれを尊重していないようです。つまり、前のセルのサイズが変更されていなければ、同じ位置に表示されます。

2 つの質問:

  • 私が望むものを可能にする方法は?
  • setNeedsLayout内で呼び出すことで、私は正しくやっていますcellForRowAtIndexPathか?

PS: セルの高さを変更する鍵を握っていることは知っていますが、高さを計算するためだけにheightForRowAtIndexPath行うデータ解析 (ここには示されていません) はやり過ぎだと感じています。コンテンツのニーズに応じてサイズを変更するように にcellForRowAtIndexPath直接指示できるものが必要です。UITableViewCell

4

3 に答える 3

3

-tableView:heightForRowAtIndexPath:可変サイズのセルがどのように計算されるかは仕様によるものです。セルの実際のフレームは重要ではなく、必要に応じてテーブル ビューによって変更されます。

あなたはこれを後ろ向きに考えているようなものです。デリゲートは、セルをどのように描画する必要があるかをテーブル ビューに伝え、テーブル ビューはセルをそれらの特性に適合させます。セルに提供する必要があるのは、保持する必要があるデータだけです。

これは、テーブル ビューでは、描画するセルが存在する前に、すべてのセルのすべての高さが計算されるためです。これは、テーブル ビューがスクロール ビューのサイズを正しく調整できるようにするために行われます。これにより、適切なサイズのスクロール バーと、テーブル ビューでのスムーズなクイック パンが可能になります。セルは、テーブル ビューがセルを画面に表示する必要があると判断した場合にのみ要求されます。


更新: セルの高さを取得するにはどうすればよいですか

私はこれを数回しなければなりませんでした。テーブルビューで使用されていないセルをビューコントローラーに保持させています。

@property (nonatomic) MyTableViewCell *standInCell;

次に、測定が必要なときにこのセルを代役として使用します。可変サイズのビューを使用せずに、セルのベースの高さを決定します。

@property (nonatomic) CGFloat standInCellBaseHeight;

次に、-tableView:heightForRowAtIndexPath:そのインデックス パスの実際のデータを使用して、すべての可変サイズ ビューの高さを取得します。可変サイズの高さをセル ベースの高さのスタンドに追加します。その新しく計算された高さを返します。

これはすべて自動レイアウトではないことに注意してください。アプローチは似ていると確信していますが、これと同一ではありませんが、私には経験がありません。

于 2014-01-28T19:32:45.490 に答える
1

-tableView:heightForRowAtIndexPath:テーブルビューにそのセルのサイズを伝えるための推奨される方法です。事前に計算して辞書にキャッシュして再利用するか、ios7 で-tableView:estimatedHeightForRowAtIndexPath:サイズを見積もることができます。

于 2014-01-28T22:24:09.577 に答える
1

このスレッドを見てください - https://stackoverflow.com/questions/18746929/using-auto-layout-in-uitableview-for-dynamic-cell-layouts-variable-row-heights、答えは非常に良いことを示していますサンプル プロジェクトはこちら - https://github.com/caoimghgin/TableViewCellWithAutoLayout

申し訳ありませんが、私が知る限り、実装する必要がありますtableView:heightForRowAtIndexPath:。警告、iOS 6 では、これは UITableView のすべての行ですぐに呼び出されます。スクロールバーを描画すると思います。iOS7 ではtableView:estimatedHeightForRowAtIndexPath:、これを実装すると、すべての計算を行う前に高さを推測できるようになります。これは、非常に大きなテーブルで非常に役立ちます。

私が見つけたのは、その行のセルを取得するためのtableView:heightForRowAtIndexPath:呼び出しcellForRowAtIndexPath:を行い、そのセルの高さを照会してそれcell.bounds.size.heightを返すことだけです。

これは、小さなテーブルや実装された iOS7 ではうまく機能しtableView:estimatedHeightForRowAtIndexPathます。

于 2014-01-29T03:00:38.527 に答える