简体   繁体   English

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

[英]Odd Padding Appears in Dynamic Table View Cells Using Auto Layout

I am building a very simple App.net client as a sort of test app. 我正在构建一个非常简单的App.net客户端作为一种测试应用程序。 It simply pulls the latest 20 posts from the App.net public timeline and displays the post, the user's name, and the user's avatar in a UITableView . 它只是从App.net公共时间轴中提取最新的20条帖子,并在UITableView显示该帖子,用户名和用户头像。 Simple enough. 很简单。

For the UI, I am using a storyboard and Auto Layout. 对于用户界面,我使用情节提要和自动版式。

UIImageView Constraints UIImageView约束

  • Height Equals: 69 身高等于:69
  • Width Equals: 69 宽度相等:69
  • Align Top to: Label - Name (the username label) 顶部对齐:标签-名称(用户名标签)
  • Leading Space to: Superview Equals: 3 领导空间:Superview等于:3
  • Trailing Space to: Label - Name Equals: 8 尾随空格到:标签-名称等于:8
  • Trailing Space to: Label - Text (the text of the post) Equals: 8 尾随空格到:标签-文本(帖子的文本)等于:8

Name Label Constraints 名称标签约束

  • Align Top to: Image View 将顶部对齐到:图像视图
  • Top Space to: Superview Equals: 5 最多观看次数:Superview等于:5
  • Trailing Space to: Superview Equals: 17 尾随空间到:Superview等于:17
  • Leading Space to: Image View Equals: 8 前导空间:图像视图等于:8
  • Bottom Space to: Label - Text Equals: 6 底部空间到:标签-文本等于:6

Text Label Constraints 文字标签约束

  • Bottom Space to: Superview Equals: 9 底部空间:Superview等于:9
  • Trailing Space to: Superview Equals: 17 尾随空间到:Superview等于:17
  • Top Space to: Label - Name Equals: 6 要显示的最大空格:标签-名称等于:6
  • Leading Space to: Image View Equals: 8 前导空间:图像视图等于:8

Finally, to set the height of each cell, I am using the following code in tableView:heightForRowAtIndexPath: : 最后,要设置每个单元格的高度,我在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
}

For Portrait, this works wonderfully. 对于Portrait而言,这非常有效。 I get the following: 我得到以下内容:

人像图像

For Landscape, however, a very peculiar padding appears (a large amount of whitespace in between the Name label and the Text label and in between the Text label and the bottom cell divider), and I have no idea how to figure out what constraint is causing this. 但是,对于“横向”而言,会出现非常特殊的填充(“名称”标签和“文本”标签之间以及“文本”标签和底部单元格分隔符之间存在大量空白),我不知道如何找出什么约束造成这个。 I've tried a wide variety of constraints, but I still can't seem to get rid of the padding. 我尝试了各种各样的约束,但似乎仍然无法摆脱这种局限性。

风景图片

Thanks in advance, and please let me know if there's anything else I can provide to assist in solving this problem! 在此先感谢您,如果可以提供其他帮助解决此问题的方法,请告诉我!

I think you need to put in a preferred maximum width for the textLabel. 我认为您需要为textLabel输入首选的最大宽度。 I don't know why the cell can't figure this out from the constraints and the width of the cell, but that seems to be the situation. 我不知道为什么单元无法从单元的约束和宽度中找出来,但这似乎是这种情况。 One other thing I noticed was that if you dequeue a cell in heightForRowAtIndexPath to do the calculations, you get a subtle error -- the cell looks fine in portrait, and the first time you rotate to landscape, but if you rotate back to portrait and then back to landscape again, the first row (or sometimes the first several rows depending on the string length) is too tall. 我注意到的另一件事是,如果您将heightForRowAtIndexPath中的单元出队以进行计算,则会收到一个细微的错误-该单元在纵向中看起来不错,并且第一次旋转为横向,但是如果您旋转回纵向并然后又回到风景,第一行(或有时前几行取决于字符串的长度)太高。 This only happened when I had enough rows that you couldn't see them all, and if you scrolled the first time you went to landscape, then the height was correct the second time you went to landscape, but not the third. 仅当我有足够多的行使您看不到所有行时才会发生这种情况,并且如果您第一次滚动查看景观,那么第二次访问景观的高度是正确的,但第三次却没有。 This seems to have something to do with cell reuse. 这似乎与单元重用有关。 This can be fixed by dequeuing just one cell in viewDidLoad, and using that. 可以通过仅在viewDidLoad中使一个单元出队并使用它来解决此问题。 You can also get the value you need to pass to preferredMaxLayoutWidth by getting the label's width there. 您还可以通过获取标签的宽度来获取传递给preferredMaxLayoutWidth所需的值。 One place I still needed a "magic" number was to add 2 to the height you return in heightForRowAtIndexPath. 我仍然需要一个“魔术”数字的地方是将您在heightForRowAtIndexPath中返回的高度加2。 I don't know why this is, but I've noticed it with other simple cells with just one label also. 我不知道为什么会这样,但是我也注意到其他带有一个标签的简单单元格也是如此。 Here is what worked for me (my RDCell was set up with the same constraints you posted in your question): 这是对我有用的方法(我的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;
}

You're not updating the width of cell when the the orientation changes. 方向更改时,您不会更新cell的宽度。 I assume all your sizes are being calculated around width = 320 . 我假设您的所有尺寸都是在width = 320附近计算的。 You should set the width before doing the calculation: 您应该在进行计算之前设置宽度:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用自动布局约束动态调整表视图单元格的大小 - Dynamically size Table View Cells using Auto Layout constraints 使用“自动布局”更新集合视图高度以适合表视图单元格中的所有单元格 - Update collection view height to fit all cells within a table view cell using Auto Layout 使用自动布局的具有动态高度的网格视图 - Grid view with dynamic height using auto layout 是否可以使用自动布局获取动态表格视图部分标题高度? - Is it possible to obtain a dynamic table view section header height using Auto Layout? iOS自动布局:表格视图单元格的动态高度 - iOS Auto-Layout: Dynamic height for table view cell 具有多个动态高度的表格视图上的Xcode自动布局垂直约束 - Xcode Auto Layout Vertical Constraints on Table View with Multiple Dynamic Heights 使用自动布局使用IB_DESIGNABLE自定义视图错位视图警告和奇怪行为 - Misplaced view warning and odd behavior with IB_DESIGNABLE custom view using auto layout Swiftui List Row Cells 在 View 出现后设置填充 - Swiftui List Row Cells set padding after View appears 动态视图的自动布局约束 - Auto layout constraints for dynamic view 如何使用自动布局从UITableViewCell动态删除视图? - How to dynamic delete a view from a UITableViewCell using Auto Layout?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM