2014-09-29 129 views
4

我似乎无法让AutoLayout在我的表格视图单元格上工作。iOS8中的表格视图单元格自动布局

在某些单元格上它似乎工作,而在其他单元上似乎不起作用。即使是完全相同种类的细胞。

例如,在某些细胞中的描述将超过1行文本价值的,它会正常工作......

... ...但是,对其他细胞的描述将超过1行价值文本,但只显示一行与一堆空的空间。

你能帮我弄清楚我失踪或做错了什么吗?谢谢!

我使用这个StackOverflow的问题,以指导自己的过程,第一个定时器这样做:Using Auto Layout in UITableView for dynamic cell layouts & variable row heights

1.设置&添加约束

这些大部分运作良好我相信。

2.确定唯一表视图单元复用标识符

我不能完全肯定,如果我需要担心这个部分,因为我将永远有一个标题,时间和说明。

对于iOS 8 - 自调整大小细胞 3.启用行高度估计

我说这viewDidLoad

self.tableView.rowHeight = UITableViewAutomaticDimension; 
self.tableView.estimatedRowHeight = 180.0; 

更新:增加每Acey更多信息 enter image description here

要清楚,我把约束:

  • 标题:15左右,85顶,15右
  • 垂直间距标题和时间之间,10
  • 垂直间隔的时间和说明之间,10
  • 我Cmd的点击所有三个标签,并添加解决012:前边和尾边
  • 我描述和表视图细胞

UPDATE 2的底部之间被钉扎下面的答案真的很好,但任何额外的间距是由于单元格的高度设置太大,所以Xcode会自动添加额外的空间来填充单元格的高度,因为文本标签没有填充表格的整个高度查看单元格。

如果您遇到此问题并且遇到同样的问题,请告诉我们您是否有任何问题或需要帮助。

谢谢大家!

+0

如果您试图仅针对iOS 8并且只能使用正确的约束,则可以省略'tableView:heightForRowAtIndexPath:'方法。您似乎可能在创建约束时遇到问题。你可以在IB的左侧张贴单元格的所有约束的屏幕截图吗? (我只能假设这是你需要帮助的地方 - 你没有真正问过任何具体问题)。 – Acey 2014-09-30 00:17:05

+0

感谢您的回应!我在底部更新了我的问题,以显示您想要查看的截图。让我知道,如果这是你正在寻找或不。我的主要问题是,我试图让这个单元格根据内容调整大小,但它不起作用,所以你能帮我弄清楚我错过了什么吗?谢谢! – Realinstomp 2014-09-30 00:27:47

+0

@Acey做了我张贴的截图帮助让它更清晰?谢谢您的帮助! – Realinstomp 2014-09-30 22:17:10

回答

3

我还没有尝试过使用新的iOS 8机制。但是当我使用iOS 6/7进行此操作时,我遇到了类似的问题。将应用更新到iOS 8后,它仍然可以正常工作,所以也许旧方法仍然是最好的方法?

我有我的代码的一些例子在这里: AutoLayout multiline UILabel cutting off some text

在这里: AutoLayout uitableviewcell in landscape and on iPad calculating height based on portrait iPhone

长话短说前的iOS参与维持细胞的复制只是为了计算内部tableView:heightForRowAtIndexPath:高度8路。但这不足以处理多行UILabel的问题。每次调用layoutSubviews时,我必须继承UILabel以更新preferredMaxLayoutWidth

preferredMaxLayoutWidth“修复”似乎是我失踪的神奇秘密。一旦我做到了这一点,我的大部分细胞都可以完美运作

第二个问题,我只需要我正确设置内容压缩抵抗和内容拥抱属性,例如告诉标签拥抱文本将意味着它不会扩大以填充将导致单元格的空白缩小。

一旦我做了这两件事情,我的单元格现在可以处理任何字体大小,或任何数量的文本没有任何凌乱的布局代码。学习了很多东西,但我认为它最终得到了回报,因为我的应用中有很多动态内容。

编辑

在我自己的几个问题来与iOS 8之后,我加入一些更多的细节来解决这些非常奇怪的autoLayout错误。

使用我提到的代码,当单元格“行高”未设置为自定义时,它似乎不起作用。通过选择单元格并单击autoLayout选项卡(其中所有内容压缩电阻设置等),可在IB中找到此设置。按复选框,它将填充临时高度。

其次,在我的代码中,我保留一个单元格的本地副本,然后在heightForRowAtIndexPath:方法中多次重复使用它。这似乎每次调用时都会增加单元格的高度。我已经通过调用重新初始化的本地副本:

localCopy = [self.tableView dequeueReusableCellWithIdentifier:@"mycell"]; 

它出现的新的Xcode 6/iOS 8的变化非常多所以不向下兼容与iOS 7,它似乎是完全不同的管理。

希望这会有所帮助。

编辑2

阅读这个问题后:iOS AutoLayout multi-line UILabel

我遇到的另一个问题与iOS 7/8的iOS支持自动布局!我为iOS 8压倒layoutSubviews我还需要重写setBounds以在调用超级后更新preferredMaxLayoutWidth。 WTF改变了苹果!

由于iOS 7不能使用自动功能,因此如果您在多个设备上使用相同的UILabel,它只能使用1的宽度,这似乎是IB在preferredMaxLayoutWidth中设置的问题。因此,iOS 8平板电脑上的UITableViewCell将更大,因为同一个单元需要iOS 8 iPhone上有2行。

+0

真棒,感谢演练,会尝试实施它! – Realinstomp 2014-10-08 01:01:48

+0

@Reez没有问题,让我知道它是怎么回事,我有我的眼睛在那个赏金;-) – 2014-10-08 08:44:17

+0

仍在工作实施,但给你的赏金! – Realinstomp 2014-10-08 12:17:18

1

这是我的尝试。

你可以创建一个方法/函数来获得你所需要的cellview。像这样:

- (UIView *) getCellView { 

    UIView *cellView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.view.frame.size.width, 0.0f)]; 
    cellView.tag = 1; 
    cellView.backgroundColor = [UIColor clearColor]; 

    UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(15.0f, 10.0f, 15.0f, 15.0f)]; //I assumed that was the size of your imageView; 
    imgView.image = [UIImage imageNamed:@"whatever-your-image-is-called"]; 
    [cellView addSubview:imgView]; 

    CGFloat xPadding = 15.0f; 
    CGFloat yPadding = 15.0f; 
    UILabel *headlineLabel = [[UILabel alloc ]initWithFrame:CGRectMake(xPadding, 0.0f, self.view.frame.size.width - (xPadding*2), 0.0f)]; 
    headlineLabel.numberOfLines = 0; 
    headlineLabel.text = @"Red Sox season fell apart after World Series title (The Associated Press)"; 
    [headlineLabel sizeToFit]; 
    CGRect hFrame = headlineLabel.frame; 
    if(hFrame.size.width > self.view.frame.size.width - 31.0f) 
     hFrame.size.width = self.view.frame.size.width - 30.0f; 
    hFrame.origin.y = imgView.frame.size.height + yPadding; 
    headlineLabel.frame = hFrame; 

    UILabel *timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(xPadding, 0.0f, self.view.frame.size.height-(xPadding*2), 0.0f)]; 
    timeLabel.text = @"4h"; 
    //timeLabel.numberOfLines = 0; //uncomment if it will wrap on multiple lines; 
    [timeLabel sizeToFit]; 
    hFrame = timeLabel.frame; 
    if(hFrame.size.width > self.view.frame.size.width - 31.0f) 
     hFrame.size.width = self.view.frame.size.width - 30.0f; 
    hFrame.origin.y = headlineLabel.frame.size.height + yPadding; 
    timeLabel.frame = hFrame; 

    UILabel *descriptLabel = [[UILabel alloc] initWithFrame:CGRectMake(xPadding, 0.0f, self.view.frame.size.height - (xPadding*2), 0.0f)]; 
    descriptLabel.text = @"Boston (AP) -- To Boston Red Sox manager John Farrel, it hardly seems possible that just 11 months ago his team was celebrating the World Series championship on the field at Fenway Park."; 
    descriptLabel.numberOfLines = 0; //I would suggest something like 4 or 5 if the description string vary from 1 line to more than 5 lines. 
    [descriptLabel sizeToFit]; 
    hFrame = descriptLabel.frame; 
    if(hFrame.size.width > self.view.frame.size.width - 31.0f) 
     hFrame.size.width = self.view.frame.size.width - 30.0f; 
    hFrame.origin.y = timeLabel.frame.size.height + yPadding; 
    descriptLabel.frame = hFrame; 

    cellView.frame = CGRectMake(0.0f, 0.0f, self.view.frame.size.width, descriptLabel.frame.origin.y + descriptLabel.frame.size.height + 15.0f /*some padding*/); 
    return cellView; 
} 

如果您正在使用indexPath.row,你可以只改变方法名是- (UIView *)getCellView:(NSIndex) *indexPath,它应该工作一样。

然后在你的heightForRowAtIndexPath你可以做

return [[self getCellView] frame].size.height;

return [[self getCellView:indexPath] frame].size.height

而在你的cellForRowAtIndexPath你可以只执行以下操作

static NSString *CellIdentifier = @"Cell"; 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if(cell == nil) { 

    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 
    cell.accessoryType = UITableViewCellAccessoryNone; 
    cell.textLabel.text = @""; 
    cell.detailTextLabel.text = @""; 
} 
[[cell viewWithTag:1] removeFromSuperview]; 
[cell addSubview:[self getCellView]; //or [cell addSubview:[self getCellView:indexPath]]; 
return cell; 

希望这有助于。让我知道,如果有什么不清楚或不工作。有些东西可能需要调整以适合您的使用情况,特别是在cellForRowAtIndexPath中,但这应该或多或少地成为您需要的一切。快乐的编码。

+0

谢谢你会尝试一下! – Realinstomp 2014-10-08 01:01:32

+0

你是否在使用iOS7和iOS8?只是想知道,因为我只是担心iOS8(即使我确定这显然适用于iOS8) – Realinstomp 2014-10-17 23:51:04

+0

对于iOS8和iOS7。对于像iPhone 6和iPhone 6 Plus这样的大型手机,很可能需要更大的图像和更大的文本,我添加了一些全局变量,其中包含文本/字体和矩形大小以便动态匹配特定设备。上面的代码应该处理任何字体大小,因为它使用sizetofit。 – Chris 2014-10-18 00:20:21

相关问题