繁体   English   中英

不同宽度的UITableViewCell自动布局

[英]UITableViewCell Autolayout for Different Widths

我在有两个标签的情节提要中设置了UITableViewCell,设置如下:

-----------------------
| ------------------- |
| |     Label 1     | |
| ------------------- |
| ------------------- |
| |     Label 2     | |
| ------------------- |
-----------------------
  • 标签1的顶部,左侧和右侧边距都有固定的15px约束。 内容拥抱(H:251,V:25​​1)。 耐压缩性(H:750,V:750)。
  • 标签2的底部,左侧和右侧边距固定有15px约束。 内容拥抱(H:251,V:25​​1)。 耐压缩性(H:750,V:751)。
  • 标签1对标签2具有固定的1px约束。

像元的高度计算如下:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    int width = tableView.bounds.size.width - 30;

    NSString *label1Text = ....;
    NSString *label2Text = ....;

    int label1Height = ceilf([label1Text boundingRectWithSize:CGSizeMake(width, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17.0]} context:nil].size.height);
    int label1Height = ceilf([label2Text boundingRectWithSize:CGSizeMake(width, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17.0]} context:nil].size.height);

    return 15 + label1Height + 1 + label2Text + 15;
}

这对于情节提要模板的宽度(例如320px)非常有用。 当将UITableViewController的视图宽度变大(例如500px +)时,单元格采用正确的高度,但是,标签1对其内容而言太大(将1行文本跨越2行),标签2被压扁(跨越2行)文字排成1行)。

但是,如果我在情节提要中调整UITableViewController的大小(例如,调整为500px宽)并更新标签的框架(保持相同的约束),则在加载视图时,它在500px宽时看起来很完美,在320px时看起来很糟糕。

可以(对自动排版有更多了解的人)请解释一下吗?

我假设您打算为每个标签使用多行文本。 UILabels需要知道他们怎么宽,才能给出准确的高度时,它返回一个内在的内容大小。 可以通过设置preferredMaxLayoutWidth来实现预期的行为,它可能有一个明显的局限性:使用“自动布局”的全部目的是您不一定需要或不想知道确切的值是什么。

您可以手动计算(如果不是始终是固定值)在某个时候与标签一起使用。 这对我来说是个笨拙的解决方案。

我更喜欢创建一个UILabel子类,该子类仅覆盖layoutSubviews ,该子类可以在布局时自动配置其preferredMaxLayoutWidth

// EBTSmartWidthLabel.h

#import <UIKit/UIKit.h>

@interface EBTSmartWidthLabel : UILabel

@end

接着

// EBTSmartWidthLabel.m

#import "EBTSmartWidthLabel.h"

@implementation EBTSmartWidthLabel

- (void)layoutSubviews
{
    self.preferredMaxLayoutWidth = 0.0f;
    [super layoutSubviews];
    self.preferredMaxLayoutWidth = CGRectGetWidth(self.bounds);
    [super layoutSubviews];
}

@end

该代码首先将preferredMaxLayoutWidth设置为0.0f,这使UILabel尽可能宽。 然后,它执行实际的布局,并且宽度将受到“自动布局”约束的约束。 然后,它采用宽度(应该是您的情况下最大的宽度),并使它成为preferredMaxLayoutWidth ,然后再次执行布局。

这不一定是最有效的方法,在某些罕见/复杂/人为的情况下,可能会导致大量重新布局,但是我取得了很好的效果。

如果您使用的是Storyboard / Interface Bulder,则可以在UILabel上设置一个自定义类,这将允许它使用此自定义类。

接口生成器中的自定义类

如果您使用的是iOS7 +,请尝试

    - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath{
}

代替

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
}

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM