1

表のセルにラベルやボタンなどのいくつかのコントロールが含まれる UITableView を実装しています。セルの上部にあるラベルの 1 つはさまざまな量のテキストを持つことができるため、各セルの全体のサイズも同様に変える必要があります。つまり、基本的には、いたるところで見られる動的なテーブル セルの問題です。

私が見つけたと思われる事実上の解決策は、私が使用しているthis one ですが、メンテナンスの問題があるため、あまり気にしません。セルには他にも多くのものがあるため、セルの全体的なサイズを決定するとき、およびセルのサイズに基づいてすべてをレイアウトするときに考慮する必要がある他のすべてのコントロールを表すために、多くのハードコーディングされた高さが必要です。動的コンテンツ。

ここにいくつかのコードがあります:

- (CGFloat) tableView:(UITableView*)tableView
            heightForRowAtIndexPath:(NSIndexPath*)indexPath
{
    SomeDataItem* item = [self.myData objectAtIndex:indexPath.row];
    CGSize constraintSize = CGSizeMake(275, MAXFLOAT);
    CGSize labelSize = [item.message sizeWithFont:[UIFont systemFontOfSize:13]
                                constrainedToSize:constraintSize 
                                    lineBreakMode:UILineBreakModeWordWrap];

    return HEADER_HEIGHT + OUTER_MARGIN + labelSize.height +
           INNER_MARGIN + INNER_MARGIN + OUTER_MARGIN +
           BUTTON_HEIGHT + OUTER_MARGIN;
}

- (UITableViewCell*)tableView:(UITableView*)tableView
                    cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
    ...
    NSString* message = //some dynamic text
    CGSize constraintSize = CGSizeMake(275, MAXFLOAT);
    CGSize labelSize = [message sizeWithFont:[UIFont systemFontOfSize:13]
                           constrainedToSize:constraintSize
                               lineBreakMode:UILineBreakModeWordWrap];

    //resize label according to amount of text
    cell.messageLabel.frame = CGRectMake(cell.messageLabel.frame.origin.x,
                                         cell.messageLabel.frame.origin.y,
                                         cell.messageLabel.frame.size.width, 
                                         labelSize.height);

    //now move controls below the dynamic label down
    y = HEADER_HEIGHT + OUTER_MARGIN;
    [self setView:cell.messageTextBackground yCoord:y];

    y += INNER_MARGIN;
    [self setView:cell.messageLabel yCoord:y];

    y += labelSize.height;
    [self setView:cell.anotherLabel yCoord:y];

    y += OUTER_MARGIN;
    [self setView:cell.someButton yCoord:y];
}

- (void) setView:(UIView*)view yCoord:(NSInteger)y
{
    int x = view.frame.origin.x;
    int w = view.frame.size.width;
    int h = view.frame.size.height;
    view.frame = CGRectMake(x, y, w, h);
}

これは、私が何をしているのかを理解してもらうためのコードの近似値です。ご覧のとおり、それは一種の混乱です。動的ラベルの横にある他のすべてのコントロールの #define 値を保持する必要がある場合。これらのコントロールのいずれかのサイズを変更したい場合は、XIB ファイルでそれを行う必要があり、#define 値を更新することも忘れないでください。さらに悪いことに、新しいコントロールを導入したい場合は、これらのメソッドの両方を変更し、すべてが適切に計算され、オフセットされていることを確認する必要があります。

これは私にはかなりばかげているように思えますが、それ以外の方法は見つかりませんでした。tableView:heightForRowAtIndexPath 内のテーブル セルにアクセスできれば、すべてをハード コードするのではなく、実際のコントロールに基づいてすべてを計算できます。ただし、私が読んで経験したことから、セルが存在する前に tableView:heightForRowAtIndexPath が呼び出されるため、それを行うことはできません。

これをどのように処理しているか、それともこれが唯一の方法ですか?

4

2 に答える 2

3

これをよりきれいに処理する 1 つの可能な方法は、すべての非可変ビュー/コントロールを固定サイズの親ビューに配置し、そのビューにフレームを要求して高さを使用することです。そうすれば、ビューの静的部分を編集する場合、サイズ変更コードを変更する必要はありません。また、囲んでいるビューを移動するだけなので、静的アイテムを簡単に下に移動できます。

于 2012-05-31T21:41:27.047 に答える
1

あなたは正しいことをしていると思います。少なくとも、私はしばらくの間そうしてきました。メンテナンスは問題ないはずです。あなたが言及したことを実行するだけです。

#defineセルに XIB ファイルを使用し、xib ファイルをロードしてviewDidLoadそこにあるさまざまな要素のサイズを抽出することで、おそらくステートメントを削減できます。将来的には、XIB ファイルでそれらを変更するだけで済みます。

もちろん、変更されない要素を含むラッパー ビューは、追加の助けになる可能性があります。

于 2012-05-31T21:42:49.123 に答える