以编程方式添加约束会导致崩溃

Posted

技术标签:

【中文标题】以编程方式添加约束会导致崩溃【英文标题】:Adding constraints programmatically makes crash 【发布时间】:2017-04-27 08:21:14 【问题描述】:

当我从底部的新表视图滑动时,我想以编程方式添加一些约束,但到目前为止我无法理解我做错了什么。在我的super view 中,我有map view 必须更改bottom constraint,以便在单击按钮时为新的tableView 腾出空间。

基本上,对于我的表格视图,我需要 4 个约束:

地图底部的顶部约束 标签栏顶部约束的底部约束 从超级视图开始和拖尾

我总是崩溃:

不可能在未准备好约束的视图层次结构中设置布局。

基于设置约束:here

这是一个代码:

@IBAction func test(_ sender: UIButton) 
        let tableView = UITableView()
        tableView.backgroundColor = UIColor.red
        tableView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(tableView)

        let topConstraint = NSLayoutConstraint(item: tableView, attribute: .top, relatedBy: .equal, toItem: self.mapView, attribute: .bottom, multiplier: 1, constant: 0)
        let bottomConstraint = NSLayoutConstraint(item: tableView, attribute: .bottom, relatedBy: .equal, toItem: self.tabBarController?.tabBar, attribute: .top, multiplier: 1, constant: 0)
        let leadingConstraint = NSLayoutConstraint(item: tableView, attribute: .leading, relatedBy: .equal, toItem: self.view, attribute: .leading, multiplier: 1, constant: 0)
        let trailingConstraint = NSLayoutConstraint(item: tableView, attribute: .trailing, relatedBy: .equal, toItem: self.view, attribute: .trailing, multiplier: 1, constant: 0)

        view.addConstraints([topConstraint, bottomConstraint, leadingConstraint, trailingConstraint])
//        tableView.addConstraint(NSLayoutConstraint(item: tableView, attribute: .top, relatedBy: .equal, toItem: self.mapView, attribute: .bottom, multiplier: 1, constant: 0))
//        tableView.addConstraint(NSLayoutConstraint(item: tableView, attribute: .bottom, relatedBy: .equal, toItem: self.tabBarController?.tabBar, attribute: .top, multiplier: 1, constant: 0))
//        tableView.addConstraint(NSLayoutConstraint(item: tableView, attribute: .leading, relatedBy: .equal, toItem: self.view, attribute: .leading, multiplier: 1, constant: 0))
//        tableView.addConstraint(NSLayoutConstraint(item: tableView, attribute: .trailing, relatedBy: .equal, toItem: self.view, attribute: .trailing, multiplier: 1, constant: 0))

        self.view.layoutIfNeeded()
        UIView.animate(withDuration: 0.5, animations: 
            self.mapBottomConstaint.constant = 200
            self.centerButtonBottomConstaint.constant = 208
            self.view.layoutIfNeeded()
        )
    

【问题讨论】:

为什么要提供表格视图的框架?我认为这不是必需的。 @PremaJanoti 你是对的,他们不是! 现在工作了吗? 不。同样的东西。 尝试用self.bottomLayoutGuide替换self.tabBarController?.tabBar 【参考方案1】:

您正在尝试为视图层次结构之外的视图设置约束。自动布局系统提供布局指南,帮助您将视图与导航栏和标签栏对齐。

在您的底部约束中,将 self.tabBarController?.tabBar 替换为 bottomLayoutGuide

附带说明一下,新的布局语法(适用于 ios 9+)使得在没有第三方库的情况下创建编程约束变得更加容易:

let topConstraint = tableView.topAnchor.constraint(equalTo: mapView.bottomAnchor)
let bottomConstraint = tableView.bottomAnchor.constraint(equalTo: bottomLayoutGuide.topAnchor)
let leadingConstraint = tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor)
let trailingConstraint = tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor)

更多关于创建编程约束here的信息。

【讨论】:

以上是关于以编程方式添加约束会导致崩溃的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式添加 UICollectionView 时应用程序崩溃

尝试以编程方式添加视图时应用程序崩溃

UISlider 约束以编程方式:“约束项必须每个都是 UIView 或子类的实例”

iOS:以编程方式更改从 Interface Builder 设置的约束

关闭视图控制器后约束崩溃

在看到视图之前添加约束?