繁体   English   中英

在代码中设置自动布局约束时出现奇怪的问题

[英]Weird issue when setting up auto-layout constraints in code

我想在静态单元格UITableView上有一个页脚视图,该表具有三个等距间隔的标签,就像这样(来自模拟器): 在此处输入图片说明

我可以使用此委托调用从表视图控制器提供页脚视图:

override func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
    // construct view here
    return view
}

我可以通过两种方式构造视图:

  • 在代码中创建标签和间隔符,并添加适当的约束
  • 在XIB文件中完成所有操作,然后从文件中加载视图

我的问题是第一种方法行不通,第二种方法行不通。

这是我的第一种方法的代码:

override func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {

    if section == 0 {

        // Create footer view
        let view = UIView()
        view.backgroundColor = UIColor.yellowColor()
        view.clipsToBounds = false
        view.layer.borderColor = UIColor.greenColor().CGColor
        view.layer.borderWidth = 2
        view.setTranslatesAutoresizingMaskIntoConstraints(false)

        // Create labels
        var labels: [UIView] = []
        for name in ["Label 1", "AAAAAABBB", "Last label"] {
            let v = UILabel()

            v.font = UIFont.preferredFontForTextStyle(UIFontTextStyleFootnote)
            v.textColor = UIColor.darkTextColor()
            v.textAlignment = .Center
            v.text = name
            v.setTranslatesAutoresizingMaskIntoConstraints(false)

            view.addSubview(v)
            labels += [v]
        }

        // Create spacers
        var spacers: [UIView] = []
        for i in 1...4 {
            let v = UIView()

            v.backgroundColor = UIColor.blueColor() // Background color is just so we can see where the view is and what size it has
            v.setTranslatesAutoresizingMaskIntoConstraints(false)

            view.addSubview(v)
            spacers += [v]
        }

        // Constrain all views to top and bottom of superview
        for i in labels + spacers {
            view.addConstraint(NSLayoutConstraint(item: i, attribute: .Top, relatedBy: .Equal, toItem: view, attribute: .Top, multiplier: 1, constant: 0))
            view.addConstraint(NSLayoutConstraint(item: i, attribute: .Bottom, relatedBy: .Equal, toItem: view, attribute: .Bottom, multiplier: 1, constant: 0))
        }

        // Equal width for labels
        labels.pairs {
            view.addConstraint(NSLayoutConstraint(item: $0, attribute: .Width, relatedBy: .Equal, toItem: $1, attribute: .Width, multiplier: 1, constant: 0))
        }

        // Equal width for spacers
        spacers.pairs {
            view.addConstraint(NSLayoutConstraint(item: $0, attribute: .Width, relatedBy: .Equal, toItem: $1, attribute: .Width, multiplier: 1, constant: 0))
        }

        view.addConstraint(NSLayoutConstraint(item: view, attribute: .Left, relatedBy: .Equal, toItem: spacers[0], attribute: .Left, multiplier: 1, constant: 0))
        view.addConstraint(NSLayoutConstraint(item: spacers[0], attribute: .Right, relatedBy: .Equal, toItem: labels[0], attribute: .Left, multiplier: 1, constant: 0))
        view.addConstraint(NSLayoutConstraint(item: labels[0], attribute: .Right, relatedBy: .Equal, toItem: spacers[1], attribute: .Left, multiplier: 1, constant: 0))
        view.addConstraint(NSLayoutConstraint(item: spacers[1], attribute: .Right, relatedBy: .Equal, toItem: labels[1], attribute: .Left, multiplier: 1, constant: 0))
        view.addConstraint(NSLayoutConstraint(item: labels[1], attribute: .Right, relatedBy: .Equal, toItem: spacers[2], attribute: .Left, multiplier: 1, constant: 0))
        view.addConstraint(NSLayoutConstraint(item: spacers[2], attribute: .Right, relatedBy: .Equal, toItem: labels[2], attribute: .Left, multiplier: 1, constant: 0))
        view.addConstraint(NSLayoutConstraint(item: labels[2], attribute: .Right, relatedBy: .Equal, toItem: spacers[3], attribute: .Left, multiplier: 1, constant: 0))
        view.addConstraint(NSLayoutConstraint(item: spacers[3], attribute: .Right, relatedBy: .Equal, toItem: view, attribute: .Right, multiplier: 1, constant: 0))

        return view
    }
    else {
        return nil
    }
}

extension Array {
    func pairs(block: (Element, Element?)->()) {
        if count == 0 { return }
        if count == 1 { block(self.first!, nil) }

        var last = self[0]
        for i in self[1..<count] {
            block(last, i)
            last = i
        }
    }
}

结果如下:

在此处输入图片说明

完全不符合我的期望,对吧?

现在,继续第二种方法。 我没有从Interface Builder中发布一堆屏幕截图,而是创建了一个示例项目,可在此处专门用于测试此问题。 如果打开它,文件FooterView.xib包含在IB中构造的页脚视图, 据我所知FooterView.xib脚视图具有完全相同的视图结构和自动布局约束。

使用该视图,如下所示:

return (NSBundle.mainBundle().loadNibNamed("FooterView", owner: self, options: nil).first as UIView)

产生您在第一个屏幕截图中看到的结果,这正是我想要的。

因此,使用Interface Builder,约束将按预期工作。 在代码中创建视图和约束时,为什么它不起作用? 我想念什么?

该视图的大小在创建时是未知的,因此将其setTranslatesAutoresizingMaskIntoConstraints设置为true可以解决这个问题:

view.setTranslatesAutoresizingMaskIntoConstraints(true)

结果:

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM