自动版式的景观和iPad上的计算高度的UITableViewCell基于肖像iPhone [英] AutoLayout uitableviewcell in landscape and on iPad calculating height based on portrait iPhone

查看:119
本文介绍了自动版式的景观和iPad上的计算高度的UITableViewCell基于肖像iPhone的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在学习/自动版式与实验和的UITableViewCell 的。我问另外一个问题,前几天到我回答我自己的问题,我仍然使用相同的约束/ code。对于全code在这里看到:<一href=\"http://stackoverflow.com/questions/23398042/autolayout-multiline-uilabel-cutting-off-some-text\">AutoLayout多行的UILabel切断一些文本。

I'm learning / experimenting with autolayout and UITableViewCell's. I asked another question a few days ago to which I answered my own question, I'm still using the same constraints / code. For the full code see here: AutoLayout multiline UILabel cutting off some text .

要剪短内 heightForRowAtIndexPath 我使用的是自定义的一个实例的UITableViewCell 来计算高度的行需要是。这在人像完美,但是当我切换到横向模式, systemLayoutSizeFittingSize 将返回单元格的高度相同,如果它是在肖像。我打印出来的内容查看的框架和标签,似乎没有任何要更新。

To cut it short inside heightForRowAtIndexPath I am using an instance of a custom UITableViewCell to calculate the height the row needs to be. This works perfect in portrait, however when I switch to landscape mode, systemLayoutSizeFittingSize is returning the same height for the cell as if it was in portrait. I've printed out the frames of the contentView and the labels and nothing seems to be updating.

这样做的结果是约束迫使标签生长留下了巨大的空白量。标签在正确的宽度显示,在横向他们都摆出来,因为我所期望的,如果我硬code中的单元格的高度它完美的作品。

The result of this is the constraints are forcing the labels to grow leaving a huge amount of whitespace. The labels display in the correct width, in landscape they are laid out as I would expect, If I hardcode the height of the cell it works perfectly.

它看起来像这样:

It looks like this:

硬编码(我希望它看起来像)后:

After hardcoding (what I want it to look like):

更糟糕的是在iPad上,甚至纵向模式下运行时,我得到了相同的结果,这意味着我拿到iPhone的尺寸。从我所看到的,就好象 systemLayoutSizeFittingSize 无取向或设备为此事的概念。

Even worse I get the same result when running on iPad, even portrait mode, meaning I get the iPhone dimensions. From what I'm seeing it is as though systemLayoutSizeFittingSize has no concept of orientation or device for that matter.

我试过假装的细胞应该是,试图旋转的单元格,称 layoutSubviews ,重装在的tableView 的方向变化,似乎没有任何影响了。

I've tried faking the frame the cell should be, tried rotating the cell, calling layoutSubviews, reloading the tableView on orientation change and nothing seems to affect it.

我错过了一些基本的东西?​​

Have I missed something basic ?

推荐答案

@rdelmar有正确的方法。你肯定需要你打电话systemLayoutSizeFittingSize的内容查看之前重置每个标签上的preferredMaxLayoutWidth。我也用一个UILabel子类的layoutSubviews方法,因为他证明了。

@rdelmar has the right approach. You definitely need to reset the preferredMaxLayoutWidth on each label before you call systemLayoutSizeFittingSize on the contentView. I also use a UILabel subclass with the layoutSubviews method as he demonstrates.

主要缺点像这样的自动版式的做法是开销。我们有效地运行自动布局三次将显示每个单元:一旦到prepare上浆细胞为systemLayoutSizeFittingSize(大小,并在各子标签集合preferredMaxLayoutWidth),再以调用systemLayoutSizeFittingSize,并再次实际电池,我们从返回的cellForRowAtIndexPath。

The main downside to an autolayout approach like this is the overhead. We're effectively running autolayout three times for each cell that will be displayed: Once to prepare the sizing cell for systemLayoutSizeFittingSize (size it and set preferredMaxLayoutWidth on each sublabel), again with the call to systemLayoutSizeFittingSize, and again on the actual cell we return from cellForRowAtIndexPath.

我们为什么需要/想第一个自动版式通过?没有它,我们不知道是什么宽度来设置我们的孩子标签preferredMaxLayoutWidth值。我们可以硬code的值作为@rdelmars例如(这是罚款),但如果你改变你的单元布局还是有很多类型的细胞来对付它更脆弱。

Why do we need/want the first autolayout pass? Without it we don't know what width to set our child labels preferredMaxLayoutWidth values to. We could hardcode the values as in @rdelmars example (which is fine) but it's more fragile if you change your cell layout or have lots of cell types to deal with.

如果主要的问题是方向上的改变重新计算则低于code可能可以进行优化,以每个方向的变化只是一次运行的第一个布局传递。

If the main issue is recalculating on orientation change then the code below can likely be optimized to run the first layout pass just once per orientation change.

下面是我用的模式,它否定的需要来操纵视图控制器单元控制。这是多个封装但可以说更加昂贵。

Here's the pattern I use, which negates the need to manipulate the cell controls in the view controller. It's more encapsulated but arguably more expensive.

- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // assumes all cells are of the same type!
    static UITableViewCell* cell;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{

        cell = [tableView dequeueReusableCellWithIdentifier: @"label_cell"];
    });

    // size the cell for the current orientation.  assume's we're full screen width:
    cell.frame = CGRectMake(0, 0, tableView.bounds.size.width, cell.frame.size.height );

    // perform a cell layout - this runs autolayout and also updates any preferredMaxLayoutWidths via layoutSubviews in our subclassed UILabels
    [cell layoutIfNeeded];

    // finally calculate the required height:
    CGSize s = [cell.contentView systemLayoutSizeFittingSize: UILayoutFittingCompressedSize];

    return s.height + 1; // +1 because the contentView is 1pt shorter than the cell itself when there's a separator.  If no separator you shouldn't need +1
}

连同

@interface TSLabel : UILabel
@end

@implementation TSLabel

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

@end

这篇关于自动版式的景观和iPad上的计算高度的UITableViewCell基于肖像iPhone的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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