Ios 视图层次结构即使在添加子视图后也未为约束做好准备

Ios 视图层次结构即使在添加子视图后也未为约束做好准备,ios,swift,autolayout,Ios,Swift,Autolayout,我正在尝试实现一个集合视图,其中每个单元格都有数量可变的UIButton实例,它们是水平端到端放置的 因为按钮的数量是动态的,所以我在运行时实例化按钮,并以编程方式添加自动布局约束(第一次尝试这样做) 这是我的代码: class MyCustomCell: UICollectionViewCell { var buttonTitles:[String]? var buttons = [UIButton]() override func didMoveToSupervi

我正在尝试实现一个集合视图,其中每个单元格都有数量可变的UIButton实例,它们是水平端到端放置的

因为按钮的数量是动态的,所以我在运行时实例化按钮,并以编程方式添加自动布局约束(第一次尝试这样做)

这是我的代码:

class MyCustomCell: UICollectionViewCell
{
    var buttonTitles:[String]?

    var buttons = [UIButton]()

    override func didMoveToSuperview()
    {
        super.didMoveToSuperview()

        guard let titles = buttonTitles else {
            return
        }

        for button in buttons {
            button.removeFromSuperview()
        }

        buttons.removeAll()


        self.translatesAutoresizingMaskIntoConstraints = false


        // FIRST LOOP: CREATE/ADD BUTTONS:

        for (index, title) in titles.enumerate(){

            let button = UIButton(type: UIButtonType.Custom)

            button.translatesAutoresizingMaskIntoConstraints = false

            button.setTitle(title, forState: .Normal)
            button.tag = index

            addSubview(button)
            buttons.append(button)
        }

        // SECOND LOOP: ADD CONSTRAINTS:

        for (index, button) in buttons.enumerate(){

            // Vertical Constaints (common to all buttons)

            button.addConstraint(
                NSLayoutConstraint(
                    item: self,
                    attribute: NSLayoutAttribute.TopMargin,
                    relatedBy: NSLayoutRelation.Equal,
                    toItem: button,
                    attribute: NSLayoutAttribute.Top,
                    multiplier: 1,
                    constant: 0
                )
            )

            button.addConstraint(
                NSLayoutConstraint(
                    item: self,
                    attribute: NSLayoutAttribute.BottomMargin,
                    relatedBy: NSLayoutRelation.Equal,
                    toItem: button,
                    attribute: NSLayoutAttribute.Bottom,
                    multiplier: 1,
                    constant: 0
                )
            )


            // Horizontal Constriants

            if index == 0 {

                // First - Constrain left to parent (self):

                button.addConstraint(
                    NSLayoutConstraint(
                        item: self,
                        attribute: NSLayoutAttribute.LeftMargin,
                        relatedBy: NSLayoutRelation.Equal,
                        toItem: button,
                        attribute: NSLayoutAttribute.Left,
                        multiplier: 1,
                        constant: 0
                    )
                )
            }
            else {
                // Not first - Constrain left to previous button:

                let previousButton = self.subviews[index - 1]

                button.addConstraint(
                    NSLayoutConstraint(
                        item: previousButton,
                        attribute: NSLayoutAttribute.LeftMargin,
                        relatedBy: NSLayoutRelation.Equal,
                        toItem: button,
                        attribute: NSLayoutAttribute.Left,
                        multiplier: 1,
                        constant: 0
                    )
                )

                if index == (titles.count - 1) {

                    // Last: Constrain right

                    button.addConstraint(
                        NSLayoutConstraint(
                            item: self,
                            attribute: NSLayoutAttribute.RightMargin,
                            relatedBy: NSLayoutRelation.Equal,
                            toItem: button,
                            attribute: NSLayoutAttribute.Right,
                            multiplier: 1,
                            constant: 0
                        )
                    )
                }
            }
        }
    }
}
当我尝试添加第一个约束时,会引发此异常:

The view hierarchy is not prepared for the constraint: <NSLayoutConstraint:0x7f9702d19610 MyAppName.MyCustomCell:0x7f9703a690e0.topMargin == UIView:0x7f9702d163e0.top>
    When added to a view, the constraint's items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled. Break on -[UIView(UIConstraintBasedLayout) _viewHierarchyUnpreparedForConstraint:] to debug.
2015-10-06 18:39:58.863 Meeting Notes[15219:1817298] View hierarchy unprepared for constraint.
    Constraint: <NSLayoutConstraint:0x7f9702d19610 MyAppName.MyCustomCell:0x7f9703a690e0.topMargin == UIView:0x7f9702d163e0.top>
    Container hierarchy: 
<UIView: 0x7f9702d163e0; frame = (0 0; 97 60); gestureRecognizers = <NSArray: 0x7f96fb64b5c0>; layer = <CALayer: 0x7f96fb606880>>
    View not found in container hierarchy: <MyAppName.MyCustomCell: 0x7f9703a690e0; baseClass = UICollectionViewCell; frame = (103 0; 97 60); clipsToBounds = YES; opaque = NO; layer = <CALayer: 0x7f96fb64bcd0>>
    That view's superview: <UICollectionView: 0x7f96fb8cc800; frame = (0 172; 1024 596); clipsToBounds = YES; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x7f9701f813f0>; layer = <CALayer: 0x7f9701f865c0>; contentOffset: {0, 0}; contentSize: {1024, 182}> collection view layout: <UICollectionViewFlowLayout: 0x7f9701f8df50>
(lldb)
未为约束准备视图层次结构:
添加到视图时,约束项必须是该视图(或视图本身)的后代。如果在装配视图层次之前需要解决约束,则此操作将崩溃。中断-[UIView(UIConstraintBasedLayout)\u viewHierarchyUnpreparedForConstraint:]以进行调试。
2015-10-06 18:39:58.863会议记录[15219:1817298]查看未准备好约束的层次结构。
约束条件:
容器层次结构:
在容器层次结构中找不到视图:
该视图的superview:集合视图布局:
(lldb)
如前所述和其他类似问题,当约束中涉及的视图不在父子关系中时,会发生这种情况;但是,在添加任何约束之前,我已经添加了所有子视图(我将循环拆分为两个)。另外,整个代码在单元格的
didMovetoSuperview
中运行,因此单元格本身不是孤立的

我遗漏了什么?

查看错误消息:

添加到视图时,约束项必须是该视图(或视图本身)的后代

在您的情况下,所有约束都应添加到
self

self.addConstraint( ...

除了这个参数项应该与to itemThank交换之外,我错误地理解为“一个必须是另一个的子视图”。那么,如何在按钮之间添加约束呢?
self.addConstraint(NSLayoutConstraint(项目:button1,…toItem:button2…)
应该可以工作。不再崩溃,谢谢。但由于某些原因,这些细胞没有显示出来。我现在会调查的。。。