UITableViewCell中的iOS7自动布局约束问题

我以编程方式使用自动布局约束来布局我的自定义UITableView单元格,并正确定义tableView:heightForRowAtIndexPath:的单元格大小tableView:heightForRowAtIndexPath:

它在iOS6上工作得很好,而且在iOS7中看起来也不错

但是当我在iOS7上运行应用程序时,以下是我在控制台中看到的那种消息:

 Break on objc_exception_throw to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful. 2013-10-02 09:56:44.847 Vente-Exclusive[76306:a0b] Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) ( "<NSLayoutConstraint:0xac4c5f0 V:|-(15)-[UIImageView:0xac47f50] (Names: '|':UITableViewCellContentView:0xd93e850 )>", "<NSLayoutConstraint:0xac43620 V:[UIImageView:0xac47f50(62)]>", "<NSLayoutConstraint:0xac43650 V:[UIImageView:0xac47f50]-(>=0)-[UIView:0xac4d0f0]>", "<NSLayoutConstraint:0xac43680 V:[UIView:0xac4d0f0(1)]>", "<NSLayoutConstraint:0xac436b0 V:[UIView:0xac4d0f0]-(0)-| (Names: '|':UITableViewCellContentView:0xd93e850 )>", "<NSAutoresizingMaskLayoutConstraint:0xac6b120 h=--& v=--& V:[UITableViewCellContentView:0xd93e850(44)]>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0xac43650 V:[UIImageView:0xac47f50]-(>=0)-[UIView:0xac4d0f0]> 

事实上 ,这个列表中的一个限制是我不想要的:

 "<NSAutoresizingMaskLayoutConstraint:0xac6b120 h=--& v=--& V:[UITableViewCellContentView:0xd93e850(44)]>" 

我不能将contentViewtranslatesAutoresizingMaskIntoConstraints属性设置为NO =>它会弄乱整个单元格。

44是默认的单元格高度,但我在表视图委托中定义了自定义高度,为什么单元格contentView有这个约束? 什么可能导致这个?

在iOS6中,iOS6和iOS7都没有发生,一切看起来都很好。

我的代码是相当大的,所以我不会在这里发布,但如果你需要,可以随时索取一个pastebin。

要指定我在做什么,在细胞初始化:

  • 我创build了我所有的标签,button等
  • 我将它们的translatesAutoresizingMaskIntoConstraints属性设置为NO
  • 我将它们添加为单元格的contentView的子视图
  • 我在contentView上添加约束条件

我也对理解为什么只发生在iOS7上感兴趣。

我也遇到了这个问题。看起来contentView的框架没有被更新,直到layoutSubviews被调用,但是单元格的框架被更早的更新了,在此时,contentView的框架被设置为{0, 0, 320, 44} 0,0,320,44 {0, 0, 320, 44}当约束被评估时。

在更详细地查看contentView之后,似乎不再设置autoresizingMasks。

在约束视图之前设置autoresizingMask可以解决这个问题:

 - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier]; if (self) { self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth; [self loadViews]; [self constrainViews]; } return self; } 

显然,在使用iOS 8 SDK的iOS 7上,UITableViewCell和UICollectionViewCell存在问题。

你可以更新单元格的contentView,当单元格被重新使用时,像这样:

对于静态UITableViewController:

 #ifdef __IPHONE_OS_VERSION_MIN_REQUIRED #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath]; if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1) { cell.contentView.frame = cell.bounds; cell.contentView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin |UIViewAutoresizingFlexibleTopMargin |UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin; } //your code goes here return cell; } #endif #endif 

由于静态表格视图控制器是脆弱的,如果你实现一些数据源或deletegate方法很容易被破坏 – 有检查,将确保这个代码将只编译和运行在iOS 7

标准的dynamicUITableViewController类似:

 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellID = @"CellID"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID]; if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1) { cell.contentView.frame = cell.bounds; cell.contentView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin |UIViewAutoresizingFlexibleTopMargin |UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin; } //your code goes here return cell; } 

对于这种情况我们不需要编译额外的检查,因为实现这个方法是必需的。

对于这两种情况和对于UICollectionViewCell来说,这个想法都是一样的,就像在这个线程中注释: UICollectionViewCell的Autoresizing问题Storyboard原型单元(Xcode 6,iOS 8 SDK)中的contentView框架仅在iOS 7上运行

由于单元格正在被重用,高度可以根据内容而改变,所以我认为总的来说,将间距的优先级设置为低于要求会更好。

在你的情况下,UIImageView的顶部间距为15,底部的间距为0。 如果将这些约束的优先级设置为999(而不是1000),则应用程序不会崩溃,因为约束不是必需的。

一旦layoutSubviews方法被调用,单元格将具有正确的高度,并且可以正常满足约束条件。

我仍然没有find故事板的一个很好的解决scheme…一些信息也在这里: https : //github.com/Alex311/TableCellWithAutoLayout/commit/bde387b27e33605eeac3465475d2f2ff9775f163#commitcomment-4633188

从他们的build议:

 self.contentView.bounds = CGRectMake(0, 0, 99999, 99999); 

我已经诱导我的解决scheme:

  • 右键单击故事板
  • 打开为 – >源代码
  • 在那里searchstring“44”
  • 它会是这样的

 <tableView hidden="YES" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="none" allowsSelection="NO" rowHeight="44" ... <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="ChatMessageCell" id="bCG-aU-ivE" customClass="ChatMessageCell"> <rect key="frame" x="0.0" y="22" width="320" height="44"/> 

  • 用rowHeight =“9999”replacerowHeight =“44”,用height =“9999”replaceheight =“44”
  • 右键单击故事板
  • 打开为 – >界面生成器
  • 运行你的应用程序并检查输出

只需增加默认的单元高度。 看起来像问题是单元格的内容大于默认(初始)单元格大小,违反了一些非负性约束,直到单元格被调整为其实际大小。

也许设置视图的优先级大于750,小于1000可以解决。

 "<NSLayoutConstraint:0xac43620 V:[UIImageView:0xac47f50(62)]>", 

我有同样的问题。 我的解决scheme基于上述其他人:

 - (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { // initialize my stuff [self layoutSubviews]; // avoid debugger warnings regarding constraint conflicts } return self; } 

最好的,亚历山德罗

我也面临这个问题,没有任何build议帮助。 在我的情况下,我有大小select单元格,它包含collectionView里面(每个collectionView单元格包含完整大小的图像)。 现在,单元格大小比集合视图(50)和图像内部的图像(50)稍大一些(60)。 由于那个collectionView视图已经将bottom和superview约束的值设置为10.这种情况下,我警告,唯一的解决办法是使单元格的高度与其collectionView相同。

我最终没有在devise器中使用UITableViewCell …我创build了自定义视图,并以编程方式将其添加到单元格的内容视图…有了一些帮助类别,也没有代码样板…

如果它在iOS8中正常工作,并且在iOS7中得到警告,则可以search故事板源代码,并find正确的tableviewCell,然后在tableviewCell行之后附加rect属性。 感谢kuchumovn 。

 <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" .../> <rect key="frame" x="0.0" y="0.0" width="320" height="44"/>