在Landscape中自动调整UITableCells内容

时间:2011-05-24 03:49:16

标签: iphone objective-c ios

在UITableView中,我通过UILabels向我的单元格添加内容。

定义最佳大小(与单元宽度允许的一样大)我注意到只有tableView.contentSize.width是可靠的,因为cell.contentView.bounds总是给出纵向宽度,甚至在风景中

autoresizingMask结合使用效果非常好:当我从纵向切换到横向并再次切换到肖像时。

当我直接在Landscape中加载View时出现问题。我的UILabel的宽度大于屏幕,即使断点显示tableView.contentSize.width的正确宽度

在横向和肖像之间切换不会改变,宽度仍然大于屏幕。

如果我不使用autoresizingMask,宽度是正确的,如果我使用它,即使是短文本它也会离开屏幕(但我注意到它只是由于测试背景颜色或使用非常大的NSString )。

简而言之:

  • 肖像>风景>肖像>风景...... 很好(完全调整大小)
  • landscape>肖像>风景>肖像... 错误(宽度超出范围)

我的代码简化了:

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

    //[...]
    UIFont *font = [UIFont fontWithName:@"Helvetica-Bold" size:12.0];
    CGRect frame = CGRectMake(cell.contentView.bounds.origin.x + 20,
                                  cell.contentView.bounds.origin.y + 4,
                                  tableView.contentSize.width - 50,
                                  font.lineHeight);

      //at this point a breakpoint shows that frame is whatever I asked (ex: 200 for test)
      //but still the labels is wider than the screen
    UILabel *result = [[[UILabel alloc] initWithFrame:frame] autorelease];
    [result setText:@"bouh!"];
    result.lineBreakMode = UILineBreakModeWordWrap;
    result.numberOfLines = 1;
    result.font = font;

      //if I comment this line, the width is always what I want
    result.autoresizingMask = UIViewAutoresizingFlexibleWidth;

      //test to see the real size
    result.backgroundColor = [UIColor orangeColor];

    [cell.contentView addSubview:result];
    //[...]
    return cell;
}

我在这里问你的帮助,看看是否有更好的方法来做我想要的事情?如果没有,我做错了什么?

3 个答案:

答案 0 :(得分:3)

我找不到一个干净简单的通用解决方案(适用于每个屏幕)。

但这是我为使其发挥作用所做的事情:

    //in portrait cell width works fine with autoResize
    //in landscape tableView width works fine with autoResize
CGFloat cellWidth;

if ( [UIDevice currentDevice].orientation != UIDeviceOrientationLandscapeLeft
    && [UIDevice currentDevice].orientation != UIDeviceOrientationLandscapeRight)
  {
    cellWidth = tableView.contentSize.width;
  }
else
  {
    cellWidth = cell.contentView.bounds.size.width;
  }

所以,稍后在代码中我会这样使用它:

CGRect frame = CGRectMake(cell.contentView.bounds.origin.x + 20,
                                  cell.contentView.bounds.origin.y + 4,
                                  cellWidth - 50,
                                  font.lineHeight);
UILabel *result = [[[UILabel alloc] initWithFrame:frame] autorelease];

但有些奇怪:我需要始终使用tableView.contentSize.width作为我的活动指标的框架,因为cell.contentView.bounds.size.width即使在景观中也只有320

CGRect activityIndicatorRect =
CGRectMake(
           cell.contentView.bounds.origin.x + tableView.contentSize.width - 60 ,
           cell.contentView.bounds.origin.y + 17,
           30, 30);

答案 1 :(得分:1)

我倾向于做的是UITableViewCell的子类,然后覆盖initWithReuseIdentifier ......

- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier  {        
    self = [super initWithReuseIdentifier:reuseIdentifier];

    if (self != nil) {
        [self setFrame:CGRectMake(0.0, 0.0, kLayoutWidth, kLayoutHeight)];

        // Set up labels, buttons etc....
    }
}

kLayoutWidth和kLayoutHeight是可以设置为任意值的定义,您可以将值直接放在CGRect中,但我更喜欢在编译器定义的类顶部指定大小。

这样做的好处是,现在您可以使用固定大小布置单元格并为内容元素设置自动调整遮罩,并且当tableview调整单元格大小时,它将全部正确调整大小。

答案 2 :(得分:0)

您还可以为Portrait / Landscape / iPhone / iPad使用不同的笔尖并相应地加载它们。为您节省大量代码

static NSString *aCustomCellIdentifier = @"aCustomCell";

CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:aCustomCellIdentifier];

if (!cell)
{
    if (!IS_IPAD)
        cell = [[[UINib nibWithNibName:@"CustomCell" bundle:nil] instantiateWithOwner:self options:nil] lastObject];
    else
        cell = [[[UINib nibWithNibName:@"CustomCell_iPad" bundle:nil] instantiateWithOwner:self options:nil] lastObject];

}