仅当屏幕外时,表格视图单元格才会自动布局。

3
我正在使用AutoLayout,但是当Table View加载时,屏幕上的前几个table view单元格不能正确布局,但是滚动到屏幕外的table view单元格可以正确布局。但是,当我向上滚动到最初未正确布局的table view单元格时,一旦它们离开屏幕并再次出现在屏幕上,所有的突然都能正确布局。希望有所帮助,谢谢! cellForRowAtIndexPath:
if ([model isKindOfClass:[FRSS self]]) {
        FRSS *fDan = (FRSS *)model;
        // configure cell
        MRWebListTableViewCell  *api1Cell = [tableView dequeueReusableCellWithIdentifier:@"YourAPI1Cell"];

        // RSS
        NSString *title = [NSString stringWithFormat:@"%@", fDan.title];

        // Get string from XML
        NSString *dateString = [self timeSincePublished:fDan.pubDate];

        // Get description without tags
        NSString *description = [self removeHTMLTags:fDan.description];

        NSString *link = [NSString stringWithFormat:@"%@", fDan.link];

        api1Cell.labelHeadline.text = title;
        api1Cell.labelDescription.text = description;
        api1Cell.labelPublished.text = dateString;

        // Top Image View
        UIImageView *imv = [[UIImageView alloc]initWithFrame:CGRectMake(15, 20, 50, 50)];
        imv.image=[UIImage imageNamed:@"e_r.png"];
        [api1Cell.contentView addSubview:imv];

        return api1Cell;

更新: 在尝试了很多不同的方法后,仍然遇到了很多与AutoLayout有关的问题。

这很大程度上与heightForRowAtIndexPath有关。最终需要通过将该函数添加到ViewController代码中来手动设置它。对于任何会比普通估计单元格要大得多的单元格(即如果其中包含任何图像),都需要手动设置其高度。


我在我的iOS 7/8应用程序中遇到了一些奇怪的问题,这些问题涉及我在Xcode 6中创建的新tableViewCells。如果有帮助,我已经在我的答案中添加了更多细节。 - Simon McLoughlin
发现了另一个问题并更新了我的答案。 - Simon McLoughlin
3个回答

4

看起来,自适应UITableView单元格仍然存在一些缺陷。

这是我们正在使用的解决方法。虽然我不知道确切的基本机制,但这是我们找到的最简单的hack。

@implemetation YourTableViewCell

- (void)setFrame:(CGRect)frame {
    if(frame.size.width != self.bounds.size.width) {
        [super setFrame:frame];
        self.contentView.bounds = CGRectMake(0, 0, frame.size.width, frame.size.height);
        [self.contentView layoutIfNeeded];
    }
    else {
        [super setFrame:frame];
    }
}

// .. any other methods

@end

如果您无法编辑UITableViewCell子类,请尝试在您的UITableViewDataSource中使用以下方法:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellIdentifier" forIndexPath:indexPath];

    // setup cell ...

    CGSize sysSize = [cell.contentView systemLayoutSizeFittingSize:CGSizeMake(tableView.bounds.size.width, CGFLOAT_MAX)];
    cell.contentView.bounds = CGRectMake(0,0, sysSize.width, sysSize.height);
    [cell.contentView layoutIfNeeded];
    return cell;
}

顺便说一下,在你的代码中,这是一个问题。
    // Top Image View
    UIImageView *imv = [[UIImageView alloc]initWithFrame:CGRectMake(15, 20, 50, 50)];
    imv.image=[UIImage imageNamed:@"e_r.png"];
    [api1Cell.contentView addSubview:imv];

不应该在 tableView:cellForRowAtIndexPath: 中创建/添加一个 View。你的 NIB 文件中已经有了 UIImageView,对吗?可以这样使用:

api1Cell.topImageView.image = [UIImage imageNamed:@"e_r.png"];

如果您的图像是动态的,最简单的解决方案是使用类似于SDWebImage的库。

#import <SDWebImage/UIImageView+WebCache.h>

...

    if ([model isKindOfClass:[FRSS self]]) {
        FRSS *fDan = (FRSS *)model;
        // configure cell
        MRWebListTableViewCell  *api1Cell = [tableView dequeueReusableCellWithIdentifier:@"YourAPI1Cell"];

        ...

        // Top Image View
        // for example: fDan.imageURL is a image URL string
        [api1Cell.topImageView sd_setImageWithURL:[NSURLURLWithString: fDan.imageURL]
                                 placeholderImage:[UIImage imageNamed: @"e_r.png"]];

谢谢!我会尝试将这个加入到我的代码中,也感谢你关于ImageView的提示! - Realinstomp
另外,我的图像视图不是静态图像,它是从API返回的任何图像。你的建议对此仍然有效吗? - Realinstomp

2
似乎iOS 8的自动单元格高度不太好用。我在iOS 6/7中遇到了类似的问题,更新到iOS 8后仍然有效。因此,也许你应该暂时采用老方法。
我的一些代码示例在这里:AutoLayout multiline UILabel cutting off some textAutoLayout uitableviewcell in landscape and on iPad calculating height based on portrait iPhone 长话短说,iOS 8之前的方法涉及保留一个用于计算高度的单元格副本,位于tableView:heightForRowAtIndexPath:内。但是,这对于处理多行UILabel并不足够。我不得不子类化UILabel以在每次调用layoutSubviews时更新preferredMaxLayoutWidth。 preferredMaxLayoutWidth“修复”似乎是我缺少的魔法秘密。一旦我这样做,大多数单元格就完美地工作了。
我只需要正确设置内容压缩阻力和内容吸附属性,例如告诉标签贴住文本,这样它就不会扩展以填充空白区域,从而导致单元格缩小。一旦我做了这两件事,我的单元格现在可以处理任何字体大小或任何数量的文本,而无需任何混乱的布局代码。虽然学习起来很费劲,但最终我认为它是值得的,因为我的应用程序中有很多动态内容。
编辑
在遇到自己的iOS 8问题后,我添加了一些详细信息来解决这些非常奇怪的自动布局错误。使用我提到的代码时,当单元格“行高”未设置为自定义时,似乎无法正常工作。在IB中选择单元格并单击自动布局选项卡(其中包含所有内容压缩阻力设置等),然后勾选复选框,它将填充一个临时高度。
其次,在我的代码中,我保留了一个本地单元格副本,并在heightForRowAtIndexPath:方法中多次重复使用它。这似乎会每次调用时增加单元格高度很多。我必须通过调用以下方式重新初始化本地副本:
localCopy = [self.tableView dequeueReusableCellWithIdentifier:@"mycell"];

看起来新的 Xcode 6 / iOS 8 变化与 iOS 7 不兼容,并且似乎管理方式也有很大不同。
希望这可以帮到您。
编辑2
在阅读了这个问题之后:iOS AutoLayout multi-line UILabel 我遇到了另一个 iOS 7 / iOS 8 自动布局支持的问题!我正在重写 layoutSubviews,对于 iOS 8,我还需要重写 setBounds 来在调用 super 后更新 preferredMaxLayoutWidth。苹果到底改了什么!
似乎是 IB 中 preferredMaxLayoutWidth 的设置问题,因为 iOS 7 无法使用自动功能,如果在多个设备上使用相同的 UILabel,它只会使用 1 个宽度。因此,在 iOS 8 平板电脑上,UITableViewCell 会更大,因为同一单元格在 iOS 8 iPhone 上需要有 2 行。

谢谢,我会尝试一下! - Realinstomp
我只需要iOS8支持,这会减少你的回答吗?再次感谢Simon! - Realinstomp
@Reez 我不确定仅针对8是否会改善情况。由于我的当前应用程序无法进行测试,因此我还没有进行过测试。我只知道我第一次向苹果报告了一个错误,并且自那以后我发现了很多问题。昨天我放弃了,将我的基本SDK设置为7,这似乎解决了所有我的自动布局问题。我在8中发现另一个问题,对于一个具有7个标签的单元格,它将出现其中2个被压缩的情况,并且在6秒后它会随机调用setBounds来更新3并更新单元格。我没有运行任何代码,也没有触摸单元格。这只是无缘无故发生的。 - Simon McLoughlin
@Reez 我在开发者论坛上开了一个帖子,至少有一个人回复说他们发现8非常不稳定。下周我打算尝试一下能否在Xcode 6中针对7进行优化,并为iPhone 6 / 6+优化应用程序。如果可以的话,我会放弃支持8,直到苹果解决这些问题。 - Simon McLoughlin
太棒了Simon,感谢你提供的有用信息。如果8这么不稳定,那就有点疯狂了。 - Realinstomp
@Reez 刚刚下载了 8.1,似乎解决了我所有的问题。我强烈建议更新! - Simon McLoughlin

1

我相信如果你在使用AutoLayout为UITableViewCell添加子视图时,由于自动调整大小,你会得到不想要的结果。尝试在UITableViewCell的子视图上调用setTranslatesAutoresizingMaskINtoConstraints: NO


这只是针对iOS8的吗?希望是,因为我只需要支持iOS8。谢谢! - Realinstomp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接