在UITableViewCell中自动调整UILabel

时间:2011-02-23 15:00:53

标签: iphone cocoa-touch uikit uitableview

我将自己的UILabel添加到contentView的{​​{1}},因为我需要比默认的UITableViewCellStyles提供更多的布局控制权。本质上我希望detailLabel优先于textLabel,因此textLabel会被截断。

我的UITableViewCell中有以下代码:

UITableViewController

上面的代码会产生错误的结果。最初显示表格视图时,它看起来像{1}}中的图1)。

所有- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString * const kCellIdentifier = @"CustomCell"; UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier]; UILabel * titleLabel, * dateLabel; if(cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellIdentifier] autorelease]; cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; titleLabel = [[[UILabel alloc] init] autorelease]; titleLabel.tag = kTitleLabelTag; titleLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth; dateLabel = [[[UILabel alloc] init] autorelease]; dateLabel.tag = kDateLabelTag; dateLabel.textColor = [UIColor blueColor]; dateLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; [cell.contentView addSubview:titleLabel]; [cell.contentView addSubview:dateLabel]; } [self configureCell:cell atIndexPath:indexPath]; return cell; } - (void)configureCell:(UITableViewCell *)pCell atIndexPath:(NSIndexPath *)pIndexPath { const float kHeight = 44.0, kLeftIndent = 8.0, kOverallWidth = 293.0, kGap = 1.0; UILabel * titleLabel, * dateLabel; titleLabel = (UILabel *)[pCell.contentView viewWithTag:kTitleLabelTag]; dateLabel = (UILabel *)[pCell.contentView viewWithTag:kDateLabelTag]; NSString * dateText = @"9:39 AM"; // Calculate the size of dateLabel CGSize dateSize = [dateText sizeWithFont:[dateLabel font] constrainedToSize:CGSizeMake(kOverallWidth, kHeight)]; const float dateXPos = kOverallWidth - dateSize.width; dateLabel.frame = CGRectMake(dateXPos, 0.0, dateSize.width, kHeight); titleLabel.frame = CGRectMake(kLeftIndent, 0.0, dateXPos - kLeftIndent - kGap, kHeight); titleLabel.text = @"Some potentially very long text which will be wrapped."; dateLabel.text = dateText; pCell.contentView.backgroundColor = [UIColor purpleColor]; } 的右侧存在不需要的差距。 (紫色背景只是为了更好地了解正在发生的事情)

当在图像中向上拖动桌面视图时,它会反弹并看起来像3)。

第一行现在具有我想要的布局,并在dateLabel中计算。我想这种行为的发生是因为细胞被重新使用然后再次配置。

所以感觉我错过了某种初始化,我尝试调用configureCell:atIndexPath:setNeedsLayout的{​​{1}}和layoutSubviews,但从未实现过初始正确的渲染。

只有当我将pCell pCell.contentViewautoresizingMask titleLabel设置为dateLabel时才能获得正确的初始渲染,但是要删除的滑动不起作用,因为删除按钮在UIViewAutoresizingNone上呈现。

我需要更改代码,以便所有单元格最初呈现,就像第三张图片中的第一个单元格一样?

谢谢!

PS:我想在图片中插入图片,但遗憾的是我没有足够的声誉。

2 个答案:

答案 0 :(得分:3)

一个好的,也许更简单的方法是:

首先创建一个自定义UITableViewCell子类,您可以使用Interface Builder进行设置。如果“MyTableViewCell”是您的自定义单元格视图,则在CellForRowAtIndexPath中将其初始化为:

MyTableViewCellClass *cell = (MyTableViewCellClass *)[tableView dequeueReusableCellWithIdentifier:@"MyTableViewCellClass"] autorelease];

if (!cell)
cell = [[[MyTableViewCellClass alloc] initWithStyle:UITableViewCellStyleDefault   reuseIdentifier:@"MyTableViewCellClass"] autorelease];

// Call specific methods on your cell to pass information to it, not for display
[cell setProperties:...];

然后在自定义UITableViewCell子类中实现layoutSubviews方法。例如:

-(void) layoutSubviews
{
// You must call this first to make sure your cell gets current parent information
[super layoutSubviews];

// Retrieve the content view bounds. This will include the edit symbols when present (delete button and ordering symbol
float inset = 5.0;
CGRect bounds = [[self contentView] bounds];

// Keep on going here with your own view layout.

}

这样做基本上将细胞模型(CellForRowAtIndexPath)与细胞视图(细胞绘图的自定义实现)分开。如果稍后更改单元格的实现(布局),只需更改单元格布局即可轻松完成此操作,而无需担心CellForRowAtIndexPath方法。

答案 1 :(得分:1)

如果您使用情节提要,则应禁用"使用自动布局"在文件检查器中!

然后设置单元格的属性 autoresizesSubviews

- (void)awakeFromNib
{
    // Initialization code
    self.autoresizesSubviews=YES;

}

最后一步是配置Label的框架,覆盖UITableViewCell类的方法 layoutSubviews

-(void)layoutSubviews{

    [super layoutSubviews];
    CGFloat top=VerticalPadding;
    CGFloat left=HorizentalPadding;
    CGFloat width=CGRectGetWidth(self.frame)-2*HorizentalPadding;
    CGFloat height=CGRectGetHeight(self.frame)-2*VerticalPadding;
    CGRect rect=CGRectMake(left, top, width, height);
    self.Label.frame=rect;

}