web-dev-qa-db-ja.com

動的なセルの高さを持つUITableViewCell内のUITableView

アイテムの動的リストがあります。各アイテムは異なるチームプレート/レイアウト(および高さ)を持つことができます。そして、それらのアイテムタイプの1つには、選択するアイテムの内部リストがあり、通常は5〜6行で、それぞれの高さが異なります。

さらに説明しようとすると、私のシナリオでは、別のテーブルビュー(#master)のテーブルビューセル(#master-cell)内に1つのテーブルビュー(#slave)があります。さらに、#slaveテーブルビューのセル(#slave-cell)の高さも異なる可能性があります。そのため、#masterが自動的に計算してサイズを更新するように、#slaveをレイアウトする必要があります。

enter image description here

内部テーブル(#slave)に問題があります。自動レイアウトの場合、すべてのセルスペースに合わせるために、UILabelや他のコントロールとは異なり、テーブルは折りたたまれます。したがって、ここで必要なのは、#slaveテーブルの投影サイズを取得し、#slaveの高さ=#slaveのコンテンツの高さを設定することです。

同様の投稿 が見つかりました。すべての行の高さが同じ場合は機能しますが、動的な高さのカスタム行を使用しているため、tableView.contentSize.Heightでは無効な結果が得られます(基本的にはrowNumbers * EstimatedRowHeight、スクリーンショットで確認できます。マスターアイテム#3には4つの内部セルがあります)。 #slave.reloadDataを呼び出した後でも、そのサイズを取得できませんでした。

そのようなUIを構築する適切な方法は何ですか?

ソースコード テストプロジェクトが添付されています(Xamarin.iOS)

8
Alexey Strakh

私は数日前に同じ問題に遭遇し、それを回避しようとしました。

#master-cellはchildViewControllerのように機能し、#slaveTableViewControllerのdelegatedatasourceですが、UITableViewcellにchildViewControllerを含めることはできません。

UITableViewCellをカスタマイズして、必要なプロパティを保持し、#slaveTableViewControllerのdelegatedatasourceとして機能し、#slave-cellの高さとデータを構成します。

本当の問題は#master-cellの高さです。

  1. データが単純で静的な場合は、事前に高さを計算して、ViewControllerのメソッドfunc tableView(_ tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloatに返すことができます。
  2. それ以外の場合は、プロパティが設定されているときにセル全体の高さを返すメソッドを#master-cellに追加し、高さを計算して返すプロキシ#master-cellを作成します。

    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
      let cell   = CustomUITableViewCell();
      let model  = self.getModel(indexPath)
      cell.model = model
      let height = cell.requiredHeight()
      return height;
    }    
    

    複雑で高価ですが、機能します。

4
wj2061

UITableViewの中にUITableViewを取る必要はないと思います。 UITableViewには複数のセクションを含めることができます。そして、異なるcellReuseIdentifierを使用します。このようにしてあなたの目標は達成されます。

3
Payal Maniyar

このようなレイアウトの場合、iOSはテーブルビューにセクションを提供します。マスターアイテムの場合はSectionViewを使用し(sectionViewのデリゲートメソッドがあります->セクションのビューを提供できます)。セクションが異なれば行のタイプも異なる可能性があるため、必要に応じて行を作成します。セクションに従ってそれらを返します。

プロジェクトの背景や何を達成しようとしているのかわからないためかもしれませんが、tableVIewセル内のtableViewsは不必要に些細なことに聞こえます。 #slave tableViewsでマスターtableViewを使用するよりも、前の回答で述べたように、単一のtableViewのセクションごとに分類する方がクリーンです。これを合理化するように設計されたUITableViewDelegateメソッドがあります!

1
pennyloaf

Xcode8.3.2とSwift3.1を使用しています。

私は同じ要件を持っていて、すべてを試しましたが、何もうまくいきませんでした。

最後に、UIStackViewは私のために働いたものです。

Tableviewcellに、UIStackView(Verticle)を追加し、そのUIStackViewにサブセルを追加し続けます。そしてそれは自動的にセルの高さを増やしました。

プログラムでUIStackViewを追加するには、以下を確認してください。

プログラムでUIStackViewにビューを追加

1
Ashok

最初に文字列の高さを取得する必要があり、次に高さをtableViewデリゲートの下に指定する必要があります

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return stringHeight;

}

それは私のために働いています。

異なるセクションと行を使用する場合は、以下の形式を使用してください。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0) {
        return 121;
    }
    if(indexPath.section==1)
    {
        return 81;
    }

    if (indexPath.section%2 == 0 && indexPath.row == 1) {
        return 161;
    }

    if (indexPath.section%2 != 0 && indexPath.row == 0) {
        return 81;
    }

    if (indexPath.section==16 && indexPath.row==0) {
        return 161;
    }
    else
    {
        return 44;
    }
}

私はテンプレートコード、異なるセクションと行を持っています、その各行は異なるサイズを持っているので、私はこのタイプのコードを与えました、あなたがアイデアを得るなら上記のコードを見てくださいそしてそれはあなたに役立ちます、

または

コンテンツテキストサイズの高さを変更する場合は、以下のコードを使用して、コンテンツサイズを計算してから、height(UILabel)サイズを変更してください。

-(CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    ListModel *model = [ListArray objectAtIndex:indexPath.row];

    CGRect labelRect = [model.content boundingRectWithSize:CGSizeMake(tableView.frame.size.width - 90 - 15, 0)
                        options:NSStringDrawingUsesLineFragmentOrigin
                        attributes:@{
                                     NSFontAttributeName : [UIFont fontWithName:@"Arial" size:14.0]
                                     }
                        context:nil];

    CGFloat heightOfCell = labelRect.size.height + 60;

    if(heightOfCell > 106)
        return heightOfCell;

    return 106;
}

お役に立てば幸いです

0
Iyyappan Ravi