Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding constraints programmatically makes crash

I would like to add programmatically few constraints while I slide from a bottom new table view, but so far I can not understand what am I doing wrong. In my super view I have map view which have to change bottom constraint to make a space for new tableView while the button is clicked.

Basically for my table view I need 4 constraints:

  • top constraint to the map bottom
  • bottom constraint to the tab bar top constraint
  • leading and trailing from super view

All the time I am getting crash:

Impossible to set up layout with view hierarchy unprepared for constraint.

Based on setting constraints from: here

Here is a code:

@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()
        })
    }
like image 944
yerpy Avatar asked Jul 30 '26 00:07

yerpy


1 Answers

You are trying to set a constraint to a view that is outside your view hierarchy. Auto Layout system provides layout guides to help you align your views with navigation bars and tab bars.

In your bottom constraint, replace self.tabBarController?.tabBar with bottomLayoutGuide.

As a side note, new layout syntax (available on iOS 9+) makes much easier creating programmatic constraints without third party libraries:

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)

More info for creating programmatic constraints here.

like image 149
redent84 Avatar answered Aug 01 '26 15:08

redent84



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!