自动版式多行的UILabel切断一些文本 [英] AutoLayout multiline UILabel cutting off some text

查看:150
本文介绍了自动版式多行的UILabel切断一些文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想学习汽车设计,终于想到我居然也得到了挂在它的时候发生的。我玩有关与原型细胞和标签。我想有一个

I'm trying to learn auto layout, finally thought I was getting the hang on it when this happened. I'm playing about with prototype cells and labels. I'm trying to have a


  • 标题, titleLbl - 画面中的蓝色框

  • 理财, moneyLbl - 画面中的绿框

  • 字幕/说明, subTitleLbl - 画面中的红色框

  • Title, titleLbl - blue box in picture
  • Money, moneyLbl - green box in picture
  • Subtitle / Description, subTitleLbl - red box in picture

到目前为止,我有这样的:

So far I have this:

我想实现的是:


  • 绿色框应始终在1行显示完全

  • 绿色方框内的值应该基于蓝色框为中心

  • 蓝盒子将采取(对2之间的横向约束-8px)的剩余空间,如有必要
  • 在多行显示
  • 红色框应该是下面,根据需要,显示为多行

正如你可以看到这是几乎所有的工作,用这个例子的最后一行中的例外。我试图研究这个,从我可以收集它是值得做的内在含量的大小。很多帖子在网上建议设置集preferredMaxLayoutWidth ,我已经在多个地方做这个的 titleLbl ,它已没有影响。它硬编码到 180 只有当没有我得到的结果,但它也增加了空白/填充其他蓝色框顶部/文字下面,大大增加之间的空间红色/蓝色框。

As you can see this is nearly all working, with the exception of the example in the last row. I've tried to research this and from what I can gather it is something to do with the intrinsic content size. Many posts online recommend setting setPreferredMaxLayoutWidth, i've done this in multiple places for the titleLbl and it has had no effect. Only when hardcoding it to 180 did I get the results, but it also added whitespace / padding to the other blue boxes on top / underneath the text, greatly increasing the space between the red / blue boxes.

下面是我的约束:

标题:

Title:

钱:

Money:

字幕:

Subtitle:

根据测试,我和其他文本样本运行它确实出现了要使用的宽度显示在故事板,但任何试图纠正它不工作。

Based on tests i've run with other text samples it does appear to be using the width as shown in the storyboard, but any attempt to correct it isn't working.

我创建了细胞的伊娃并用它来创建单元格的高度:

I have created an ivar of the cell and used it to create the height of the cell:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    [sizingCellTitleSubMoney.titleLbl setText:[[tableViewData objectAtIndex:indexPath.row] objectForKey:@"title"]];
    [sizingCellTitleSubMoney.subtitleLbl setText:[[tableViewData objectAtIndex:indexPath.row] objectForKey:@"subtitle"]];
    [sizingCellTitleSubMoney.moneyLbl setText:[[tableViewData objectAtIndex:indexPath.row] objectForKey:@"cost"]];

    [sizingCellTitleSubMoney layoutIfNeeded];

    CGSize size = [sizingCellTitleSubMoney.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
    return size.height+1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    MATitleSubtitleMoneyTableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifierTitleSubTitleMoney];

    if(!cell)
    {
        cell = [[MATitleSubtitleMoneyTableViewCell alloc] init];
    }


    cell.titleLbl.layer.borderColor = [UIColor blueColor].CGColor;
    cell.titleLbl.layer.borderWidth = 1;

    cell.subtitleLbl.layer.borderColor = [UIColor redColor].CGColor;
    cell.subtitleLbl.layer.borderWidth = 1;

    cell.moneyLbl.layer.borderColor = [UIColor greenColor].CGColor;
    cell.moneyLbl.layer.borderWidth = 1;


    [cell.titleLbl setText:[[tableViewData objectAtIndex:indexPath.row] objectForKey:@"title"]];
    [cell.subtitleLbl setText:[[tableViewData objectAtIndex:indexPath.row] objectForKey:@"subtitle"]];
    [cell.moneyLbl setText:[[tableViewData objectAtIndex:indexPath.row] objectForKey:@"cost"]];

    return cell;
}

我试过设置集preferredMaxLayoutWidth 单元的布局子视图里:

- (void)layoutSubviews
{
    [super layoutSubviews];

    NSLog(@"Money lbl: %@", NSStringFromCGRect(self.moneyLbl.frame));
    NSLog(@"prefferredMaxSize: %f \n\n", self.moneyLbl.frame.origin.x-8);

    [self.titleLbl setPreferredMaxLayoutWidth: self.moneyLbl.frame.origin.x-8];
}

日志:

2014-04-30 21:37:32.475 AutoLayoutTestBed[652:60b] Money lbl: {{209, 20}, {91, 61}}
2014-04-30 21:37:32.475 AutoLayoutTestBed[652:60b] prefferredMaxSize: 201.000000 

这是我所期待的。这是因为2个元素之间加上了8px和控制台验证这一点。它完美地工作的第一行上不管多少文字我加蓝盒子,里面是一样的故事板,但任何增加的绿色框抛出了宽度计算。我在的tableView尝试设置这样的:willDisplayCell 的tableView:heightForRowAtIndexPath:,以及基于其他答案的问题。但无论怎样,它只是不布局。

Which is what I would expect as there is 8px between the 2 elements and the console verifies this. It works perfectly on the first row no matter how much text I add to the blue box, which is the same as the storyboard, but any increase to the green box throws off the width calculation. I've tried setting this in the tableView:willDisplayCell and the tableView:heightForRowAtIndexPath: as well based on answers from other questions. But no matter what it just doesn't layout.

任何帮助,意见或建议,将大大AP preciated

Any help, ideas or comments would be greatly appreciated

推荐答案

找到看完这个一个更好的答案:<一href=\"http://johnszumski.com/blog/auto-layout-for-table-view-cells-with-dynamic-heights\">http://johnszumski.com/blog/auto-layout-for-table-view-cells-with-dynamic-heights

Found an even better answer after reading this: http://johnszumski.com/blog/auto-layout-for-table-view-cells-with-dynamic-heights

创建一个的UILabel 子类中重写 layoutSubviews 像这样:

creating a UILabel subclass to override layoutSubviews like so:

- (void)layoutSubviews
{
    [super layoutSubviews];

    self.preferredMaxLayoutWidth = CGRectGetWidth(self.bounds);

    [super layoutSubviews];
}

这确保了 preferredMaxLayoutWidth 是总是正确的。

This ensures the preferredMaxLayoutWidth is always correct.

更新:

在几个版本的iOS和测试更多的用例的我发现上面是不够的每一个案件。由于iOS 8的(我相信)的,在某些情况下仅 didSet 边界在屏幕加载之前调用时间。

After several more release's of iOS and testing more usecase's i've found the above to not be sufficient for every case. As of iOS 8 (I believe), under some circumstances only didSet bounds was called in time before the screen load.

在iOS的9最近我遇到另一个问题来使用模式的UIViewController 的UITableView ,既当 layoutSubviews 设置范围分别被称为 heightForRowAtIndexPath 。许多调试唯一的解决办法后,重写设置帧

In iOS 9 very recently I came across another issue when using a modal UIVIewController with a UITableView, that both layoutSubviews and set bounds were being called after heightForRowAtIndexPath. After much debugging the only solution was to override set frame.

下面code现在看来是必要的,以确保它可以跨所有iOS的,控制器,屏幕尺寸等。

The below code now seems to be necessary to ensure it works across all iOS's, controllers, screen sizes etc.

override public func layoutSubviews()
{
    super.layoutSubviews()
    self.preferredMaxLayoutWidth = self.bounds.width
    super.layoutSubviews()
}

override public var bounds: CGRect
{
    didSet
    {
        self.preferredMaxLayoutWidth = self.bounds.width
    }
}

override public var frame: CGRect
{
    didSet
    {
        self.preferredMaxLayoutWidth = self.frame.width
    }
}

这篇关于自动版式多行的UILabel切断一些文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆