使用自动布局在动态表格视图单元格中出现奇数填充

时间:2013-12-01 03:52:19

标签: ios uitableview constraints padding autolayout

我正在构建一个非常简单的App.net客户端作为一种测试应用程序。它只是从App.net公共时间线中提取最新的20个帖子,并在UITableView中显示帖子,用户名和用户的头像。很简单。

对于UI,我使用的是故事板和自动布局。

UIImageView约束

  • 身高等于:69
  • 宽度等于:69
  • 将顶部对齐:标签 - 名称(用户名标签)
  • 领先空间:Superview Equals:3
  • 尾随空格:标签 - 名称等于:8
  • 尾随空格:标签 - 文字(帖子的文字)等于:8

名称标签约束

  • 将顶部对齐:图像视图
  • 顶级空间:Superview Equals:5
  • 追踪空间:Superview Equals:17
  • 领先空间:图像视图等于:8
  • 底部空间:标签 - 文本等于:6

文本标签约束

  • 底部空间:Superview Equals:9
  • 追踪空间:Superview Equals:17
  • 顶部空间:标签 - 名称等于:6
  • 领先空间:图像视图等于:8

最后,要设置每个单元格的高度,我在tableView:heightForRowAtIndexPath:中使用以下代码:

// Solution greatly helped by http://stackoverflow.com/questions/18746929/using-auto-layout-in-uitableview-for-dynamic-cell-layouts-heights
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    static ADNPostTableViewCell *cell;

    if (!cell) {
        cell = [tableView dequeueReusableCellWithIdentifier:@"PostCell"];
    }

    cell.post = self.posts[indexPath.row];

    return fmax([cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height, cell.avatarImageView.frame.size.height + kImageViewPadding); // kImageViewPadding = 5
}

对于肖像,这非常有用。我得到以下内容:

Portrait image

对于Landscape,然而,出现了一个非常奇特的填充(Name标签和Text标签之间以及Text标签和底部单元格分隔符之间的大量空格),我不知道如何弄清楚什么约束导致了这一点。我尝试了各种各样的约束,但我似乎仍然无法摆脱填充。

Landscape image

提前致谢,如果我能提供任何其他帮助解决此问题的信息,请告诉我!

2 个答案:

答案 0 :(得分:0)

我认为您需要为textLabel添加首选的最大宽度。我不知道为什么细胞无法从细胞的约束和宽度中弄清楚这一点,但这似乎就是这种情况。我注意到的另一件事是,如果你在heightForRowAtIndexPath中对一个单元格进行计算,你会得到一个微妙的错误 - 单元格在纵向上看起来很好,并且第一次旋转到横向,但如果你旋转回到肖像和然后再回到风景,第一行(或有时前几行取决于字符串长度)太高了。这只发生在我有足够的行你看不到它们的情况下,如果你第一次去景观时滚动,那么第二次去景观时高度是正确的,而不是第三次。这似乎与细胞再利用有关。这可以通过在viewDidLoad中只出一个单元格并使用它来解决。您还可以通过获取标签的宽度来获取传递给preferredMaxLayoutWidth所需的值。我还需要一个“魔术”数字的地方是在heightForRowAtIndexPath返回的高度上加2。我不知道为什么会这样,但我已经注意到它只有一个标签的其他简单单元格。这对我有用(我的RDCell设置了你在你的问题中发布的相同约束):

@interface TableController ()
@property (strong,nonatomic) NSArray *theData;
@property (strong,nonatomic) NSString *textString;
@property (nonatomic) CGFloat labelWidthAdjuster;
@property (strong,nonatomic) RDCell *measureCell;
@end

@implementation TableController 

- (void)viewDidLoad {
    [super viewDidLoad];
    self.measureCell = [self.tableView dequeueReusableCellWithIdentifier:@"Cell"];
    self.labelWidthAdjuster = self.tableView.bounds.size.width - self.measureCell.postLabel.bounds.size.width;
    self.textString = @"A pretty long sentence that will make the label in the custom cell in the table view have to expand to several lines long";
    self.theData = @[@"One",@"Two",@"Three",@"Four",@"Five",@"Six",@"Seven",@"Eight",@"Nine"];
    [self.tableView reloadData];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.theData.count;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    self.measureCell.postLabel.preferredMaxLayoutWidth = self.tableView.bounds.size.width - self.labelWidthAdjuster;
    self.measureCell.postLabel.text = self.textString;
    return [self.measureCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height + 2;
}

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

    RDCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
    cell.nameLabel.text = self.theData[indexPath.row];
    cell.postLabel.text = self.textString;
    return cell;
}

答案 1 :(得分:0)

当方向发生变化时,您不会更新cell的宽度。我假设您的所有尺寸都是围绕width = 320计算的。您应该在进行计算之前设置宽度:

CGRect frame = cell.contentView.frame;
frame.size.width = tableView.bounds.size.width;
cell.contentView.frame = frame;