Kenny Wyland
Kenny Wyland

Reputation: 21870

iOS Swift Constraints not working, subview of UITableView disappears when translatesAutoresizingMaskIntoConstraints = false

I've dealt with programmatically creating constraints, but something isn't working this time and I can't figure out what it is.

override func viewDidLoad() {
    super.viewDidLoad()

    let imageview = UIImageView(image: UIImage(named: "dollarsign"))
    //imageview.translatesAutoresizingMaskIntoConstraints = false
    
    imageview.backgroundColor = UIColor(red: 0, green: 1, blue: 0, alpha: 0.10)
    self.view.addSubview(imageview)
    self.view.bringSubviewToFront(imageview)
    
    imageview.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 0).isActive = true
    imageview.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0).isActive = true
    
    imageview.widthAnchor.constraint(equalToConstant: 320).isActive = true
    imageview.heightAnchor.constraint(equalToConstant: 480).isActive = true

When imageview.translatesAutoresizingMaskIntoConstraints = false is commented out, the image view shows up and is just positioned at (0,0) with it's natural width,height.

view controller with image showing

but I don't want it to automatically create constraints for me, so when I uncomment imageview.translatesAutoresizingMaskIntoConstraints = false to let my programmatic constraints kick in... then the UIImageView disappears:

view controller but image has disappeared

What am I doing wrong?

EDIT: I don't understand it, but for some reason, when I let the constraints take control, it is positioning it at -320,-480 even though I've created constraints to connect it to the trailing and bottom anchors.

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    print("image view frame: \(imageview.frame)")
}

image view frame: (-320.0, -480.0, 320.0, 480.0)

Upvotes: 0

Views: 519

Answers (2)

Kenny Wyland
Kenny Wyland

Reputation: 21870

My original code would have worked if my self.view were just a UIView, but it was a UITableView and since a UITableView is a UIScrollView its layout anchors are different.

I needed to my constraint anchors to self.tableView.frameLayoutGuide.trailingAnchor and self.tableView.frameLayoutGuide.bottomAnchor and then it worked perfectly.

Upvotes: 1

Prajeet Shrestha
Prajeet Shrestha

Reputation: 8108

The code should work fine with

imageview.translatesAutoresizingMaskIntoConstraints = false.

That's what you should always do when creating constraints programmatically. Only reason it is not working must be because, some view is on top of your ImageView and you are not seeing it. May be you could debug view hierarchy.

If your base controller is UITableViewController it's another story.

You need to add a backgroundView to the tableview and then add UIImageView in it. Below is the example:

class ViewController: UITableViewController {
    var imageview:UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
      
        imageview = UIImageView(image: UIImage(named: "test"))
        imageview.backgroundColor = .systemPink
        
        imageview.translatesAutoresizingMaskIntoConstraints = false
        
        imageview.backgroundColor = UIColor(red: 0, green: 1, blue: 0, alpha: 0.10)
        let bgView = UIView(frame: self.tableView.bounds)
        self.tableView.backgroundView = bgView
        bgView.addSubview(imageview)
        bgView.bringSubviewToFront(imageview)
        
        imageview.trailingAnchor.constraint(equalTo: bgView.trailingAnchor, constant: 0).isActive = true
        imageview.bottomAnchor.constraint(equalTo: bgView.bottomAnchor, constant: 0).isActive = true
        
        imageview.widthAnchor.constraint(equalToConstant: 320).isActive = true
        imageview.heightAnchor.constraint(equalToConstant: 480).isActive = true
    }
}

Upvotes: 1

Related Questions