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。

要指定我在做什么,在单元初始化上:

  • 我创建了我的所有标签,按钮等
  • 我将他们的translatesAutoresizingMaskIntoConstraints属性设置为NO
  • 我将它们添加为单元格的contentView的子视图
  • 我在contentView上添加了约束条件
  • 我也对理解为什么只发生在iOS7上感兴趣。


    我也遇到了这个问题。看起来contentView的框架没有被更新,直到layoutSubviews被调用,但是单元格的框架被更早的更新{0, 0, 320, 44}并且在当时将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上编译和运行

    标准动态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来说,这个想法都是一样的,就像在这个线程中评论的一样:在Storyboard原型单元(Xcode 6,iOS 8 SDK)中的UICollectionViewCell contentView框架的Autoresizing问题仅在iOS 7上运行时发生


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

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

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

    链接地址: http://www.djcxy.com/p/91589.html

    上一篇: Auto layout constraints issue on iOS7 in UITableViewCell

    下一篇: Is it possible to use AutoLayout with UITableView's tableHeaderView?