我正在以编程方式使用自动布局约束来布局我的自定义UITableView单元格,并且我正确地在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)]>"
我无法将translatesAutoresizingMaskIntoConstraints
的{{1}}属性设置为NO =&gt;它会弄乱整个细胞。
44是默认的单元格高度,但我在表视图委托中定义了自定义高度,为什么单元格contentView有这个约束?什么可能导致这个?
在iOS6中它没有发生,iOS6和iOS7上的一切看起来都很好。
我的代码很大,所以我不会在这里发布,但如果你需要,可以随意索取一个pastebin。
要指定我是如何做的,请参阅单元初始化:
contentView
属性设置为NO translatesAutoresizingMaskIntoConstraints
的子视图contentView
我也非常有兴趣了解为什么只在iOS7上发生这种情况。
答案 0 :(得分:132)
我也有这个问题..看起来,在调用layoutSubviews
之前,contentView的框架不会更新,但是单元格的框架会更早更新,而contentView的框架设置为{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;
}
答案 1 :(得分:35)
显然使用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
由于静态表视图控制器很脆弱,如果你实现了一些数据源或删除门方法,很容易被破坏 - 有一些检查可以确保这些代码只能在iOS 7上编译和运行
标准动态UITableViewController类似:
-(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的想法是一样的,就像在这个帖子中评论的那样:Autoresizing issue of UICollectionViewCell contentView's frame in Storyboard prototype cell (Xcode 6, iOS 8 SDK) happens when running on iOS 7 only
答案 2 :(得分:13)
当细胞被重复使用并且高度可以根据内容而改变时,我认为通常最好将间距的优先级设置为低于要求。
在您的情况下,UIImageView与顶部的间距为15,底部视图的底部间距为0。如果将这些约束的优先级设置为999(而不是1000),则应用程序不会崩溃,因为不需要约束。
调用layoutSubviews方法后,单元格将具有正确的高度,并且可以正常满足约束。
答案 3 :(得分:9)
我仍然没有为故事板找到一个好的解决方案...... 一些信息也在这里: https://github.com/Alex311/TableCellWithAutoLayout/commit/bde387b27e33605eeac3465475d2f2ff9775f163#commitcomment-4633188
根据他们的建议:
self.contentView.bounds = CGRectMake(0, 0, 99999, 99999);
我已经引出了我的解决方案:
<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"/>
答案 4 :(得分:3)
只需增加默认的单元格高度即可。看起来问题是单元格的内容大于默认(初始)单元格大小,违反了一些非负面约束,直到将单元格调整为其实际大小。
答案 5 :(得分:3)
也许将视图的优先级设置为大于750且小于1000可以解决。
"<NSLayoutConstraint:0xac43620 V:[UIImageView:0xac47f50(62)]>",
答案 6 :(得分:1)
我遇到了同样的问题。我的解决方案基于以上其他人:
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
// initialize my stuff
[self layoutSubviews]; // avoid debugger warnings regarding constraint conflicts
}
return self;
}
最佳, 的Alessandro
答案 7 :(得分:0)
我也遇到了这个问题,没有一个建议有帮助。在我的情况下,我有大小选择单元格,它包含collectionView内部(每个collectionView单元格包含完整大小的图像)。现在,单元格大小的高度(60)比collectionView(50)和它内部的图像(50)大一点。因为collectionView视图已将底部与superview约束对齐,值为10.这种情况我是一个警告,解决这个问题的唯一方法是使单元格高度与其collectionView相同。
答案 8 :(得分:0)
我最终没有在设计器中使用UITableViewCell ...我创建了自定义视图并以编程方式将其添加到单元格的内容视图中...有些帮助类别也没有代码样板...
答案 9 :(得分:0)
如果它在iOS8中工作正常,并在iOS7中收到警告,您可以搜索故事板源代码,找到正确的tableviewCell,然后在tableviewCell行之后追加rect属性。感谢kuchumovn。
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" .../>
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>