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)]>"
我不能将contentView
的translatesAutoresizingMaskIntoConstraints
属性设置为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"/>