web-dev-qa-db-ja.com

静的コンテンツとプロトタイプコンテンツをテーブルビューで組み合わせる

ストーリーボードを使用して静的テーブルビューセル(静的コンテンツ)と動的テーブルビューセル(プロトタイプコンテンツ)を組み合わせる方法はありますか?

36
tazboy

テーブルを動的として扱うことをお勧めしますが、常に必要なセルを上部に含めます。ストーリーボードにUITableViewControllerを配置し、動的テーブルを使用するようにします。 UITableViewCellプロトタイプを必要なだけテーブルに追加します。たとえば、静的セルごとに1つと、可変セルを表すために1つ。

UITableViewDataSourceクラス:

#define NUMBER_OF_STATIC_CELLS  3

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.dynamicModel count] + NUMBER_OF_STATIC_CELLS;
}

その後

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    if (indexPath.row < NUMBER_OF_STATIC_CELLS) {
        // dequeue and configure my static cell for indexPath.row
        NSString *cellIdentifier = ... // id for one of my static cells
    } else {
        // normal dynamic logic here
        NSString *cellIdentifier = @"DynamicCellID"
        // dequeue and configure for [self.myDynamicModel objectAtIndex:indexPath.row]
    }
}
56
danh

これのわずかな変形でしたが、問題がありました。私は実際には動的セルと静的セルを混合したかったのですが、グループは異なりました。つまり、グループ1には静的なセルのみがあり、グループ2には動的なセルがあります。

私は、実際に静的セル値をハードコーディングすることでこれを達成しました(プロトタイプセル識別子に基づいて)。動的セクションには、動的に入力される通常のコンテンツが含まれます。他の誰かが同じ問題を抱えている場合のいくつかのサンプルコードは次のとおりです:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{    
    if (section == 1){
        return @"Dynamic Cells";
    }
    if (section == 0){
        return @"Static Cells";
    }
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (section == 0) {
        return 1; //However many static cells you want
    } else {
        return [_yourArray count];
    }
}

-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
    if (indexPath.section == 0) {
        NSString *cellIdentifier = @"staticCellType";   
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        }

        cell.textLabel.text = @"some static content";        
        return cell;

    } else if (indexPath.section == 1){

        NSString *cellIdentifier = @"dynamicCellType";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        }

        cell.textLabel.text = [_yourArray objectAtIndex:indexPath.row];
        return cell;

    } 
    return nil;

}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 2;
}
12
AbuZubair

この問題に対する実際の答えは実際には誰も提供していないため(同じテーブルビューで静的セルとプロトタイプセルの両方を使用)、私はそれを理解できると思いました。それは可能です!

必要に応じて静的セルを作成します。動的セルを必要とするセクションで、標準のUITableViewCellタイプを使用していない場合は、別のNibでカスタムを作成する必要があります。それ以外の場合は、標準のものを使用できます。次に、以下のデリゲートを実装します。基本的に、これらのデリゲートのそれぞれについて、スーパーと呼ぶ静的なものについては、動的なものについては、値を返します。

まず、動的セクションを選択的に表示する必要がある場合は、numberOfSectionsInTableViewを実装する必要があります(それ以外の場合は、このデリゲートを省略できます)。

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    int staticSections = 1;
    int dynamicSections = 1;
    if (SOME_BOOLEAN) {
        return staticSections + dynamicSections;
    } else {
        return staticSections;
    }
}

次に、numberOfRowsInSectionを実装する必要があります。

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (section == 1) {
        return A_COUNT;
    } else {
        return [super tableView:tableView numberOfRowsInSection:section];
    }
}

次に、heightForRowAtIndexPathを実装する必要があります。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 1) {
        return 44.0f;
    } else {
        return [super tableView:tableView heightForRowAtIndexPath:indexPath];
    }
}

次に、indentationLevelForRowAtIndexPath:

- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 1) {
        return 1; // or manually set in IB (Storyboard)
    } else {
        return [super tableView:tableView indentationLevelForRowAtIndexPath:indexPath]; // or 0
    }
}

最後に、cellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 1) {
        SomeObject *obj = self.someArray[indexPath.row];
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"DynamicCell" forIndexPath:indexPath];
        cell.textLabel.text = obj.textValue;
        return cell;
    } else {
        return [super tableView:tableView cellForRowAtIndexPath:indexPath];
    }
}
5
Sean

テーブルビューを静的テーブルのように見せることができますが、コードで定義することができます。デリゲートメソッドを使用して、セクション、セクションごとの数または行、ヘッダーなどを設定します。

3
Michael

残念ながら、静的テーブルビューmustはUITableViewControllerにあり、1つのテーブルビューしか許可しないため、これは不可能です。

必要なのは、さらに3つの動的UITableviewCellを作成し、静的コンテンツが必要な最初の3行に対して個別にロードすることです。

これを行う方法がわからない場合は、お知らせください。コードを探します。

3
lnafziger

同じView Controllerで1つのテーブルビューを静的に、もう1つを動的にすることはできないため、両方を動的にする必要があります。最初のテーブルビューでは、View Controllerの初期化時にコードでセルを構成し、セルを更新しません。

  1. UIViewControllerをストーリーボードに追加します。
  2. 2つのテーブルビュー(TableViewControllersではない)をUIViewコントローラーに追加します。
  3. 各tableViewを選択し、動的セルに両方を構成します。
  4. View Controllerをビルドしてアタッチします。 1つのビューに2つのテーブルビュー はそのステップを説明します。

別のオプションとして、ステップ4のリンクと同様のビューの一部に動的テーブルビューを埋め込むことで同様の外観を実現し、残りのビューで必要なことをすべて実行して、静的セルで行う予定の設定を行うことができますスクロールビュー、ラベル、ボタンを使用する。

2
T.J.

静的テーブルビューに動的コンテンツを含める1つの方法は、追加の行が必要なセルを複製することです。

テーブルビューの動的セクションでは、Interface Builderで1つ以上のセルをレイアウトします。実行時に、NSCoderを使用してアーカイブしてからアーカイブ解除することで、これらのクローンを作成できます。

これは機能しますが、動的プロトタイプテーブルビューから開始してそこから静的行を作成するよりも、必ずしもきれいではありません。

標準のテーブルビューセルでは失敗します。遅延作成されたテキストラベルは正しくレイアウトされません。したがって、UITableViewCellサブクラスを使用して、サブビューのアーカイブとアーカイブ解除を処理しました。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == kContactsSection) {
        NSArray     *contacts   = self.contacts;
        Contact     *contact    = [contacts objectAtIndex:indexPath.row];
        NSString    *name       = contact.name;
        NSString    *role       = contact.role;

        if ([role length] == 0) {
            NNContactDefaultTableViewCell *cell = (id)[tableView dequeueReusableCellWithIdentifier : @"contactDefault"];

            if (cell == nil) {
                NNContactDefaultTableViewCell   *template   = (id)[super tableView : tableView
                                                         cellForRowAtIndexPath :[NSIndexPath indexPathForRow:0 inSection:kContactsSection]];

                NSData                          *data       = [NSKeyedArchiver archivedDataWithRootObject:template];

                cell = [NSKeyedUnarchiver unarchiveObjectWithData:data];
            }

            cell.contactTextLabel.text = name;

            return cell;
        }
        else {
            NNContactDetailTableViewCell *cell = (id)[tableView dequeueReusableCellWithIdentifier : @"contactDetail"];

            if (cell == nil) {
                NNContactDetailTableViewCell    *template   = (id)[super tableView : tableView
                                                        cellForRowAtIndexPath :[NSIndexPath indexPathForRow:1 inSection:kContactsSection]];

                NSData                          *data       = [NSKeyedArchiver archivedDataWithRootObject:template];

                cell = [NSKeyedUnarchiver unarchiveObjectWithData:data];
            }

            cell.contactTextLabel.text          = name;
            cell.contactDetailTextLabel.text    = role;

            return cell;
        }
    }

    return [super tableView:tableView cellForRowAtIndexPath:indexPath];
}

上記の例では、2つのセルタイプがあります。どちらもInterface Builderで静的テーブルビューの一部としてレイアウトされています。

1つのセクションで動的コンテンツを取得するには、次のメソッドもオーバーライドする必要があります。

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (section == kContactsSection) {
        NSArray     *contacts       = self.contacts;
        NSUInteger  contactCount    = [contacts count];

        return contactCount;
    }

    return [super tableView:tableView numberOfRowsInSection:section];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSInteger   section = indexPath.section;
    NSInteger   row     = indexPath.row;

    if (section == kContactsSection) {
        return [super tableView:tableView heightForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:kContactsSection]];
    }

    return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}

- (CGFloat)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSInteger   section     = indexPath.section;

    if (section == kContactsSection) {
        CGFloat indentation = [super tableView:tableView indentationLevelForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:kContactsSection]];

        return indentation;
    }

    CGFloat     indentation = [super tableView:tableView indentationLevelForRowAtIndexPath:indexPath];

    return indentation;
}
0
Pierre Bernard

セルのようにスタイル設定されたボタン(静的セルごとに1つ)を作成して、UITableViewのtableHeaderViewまたはtableFooterViewに配置することもできます。結局のところ、これらのボタンは単なるビューです。

ボタンとセルで選択を行うためのロジックを追加して、通常のルックアンドフィールを維持する必要があります。

もちろん、これは、静的セルをテーブルの上部または下部にあるテーブルビューに挿入することを前提としています。

0
BeckProduct