表のセルにラベルやボタンなどのいくつかのコントロールが含まれる 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 が呼び出されるため、それを行うことはできません。
これをどのように処理しているか、それともこれが唯一の方法ですか?