Search code examples
swiftuiviewinitialization

Can i create constraints, from within a uiview's initialization, to its superview


Ive created many views, which is not a problem. However i have a lot of changes constraints code in VC which need refactoring.

QUESTION:

How (if possible) can i set up constraints inside the init method of the subView itself so i can refactor the code out of the VC.

I cant think of another way to frame my question for google, so here is what ive got:

VC

    func addCheckView() {
        let checkView = CheckView()
        checkView.frame = self.view.frame
        view.insertSubview(checkView, aboveSubview: mapView)
    }
import UIKit

class CheckView: UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }


    private func commonInit() {
        backgroundColor = .blue
//        addSubview(self)
        translatesAutoresizingMaskIntoConstraints = false
//        let margins = layoutMarginsGuide
        leadingAnchor.constraint(equalTo: leadingAnchor, constant: 40).isActive = true
        trailingAnchor.constraint(equalTo: trailingAnchor, constant: -40).isActive = true
        topAnchor.constraint(equalTo: topAnchor, constant: 40).isActive = true
        bottomAnchor.constraint(equalTo: bottomAnchor, constant: -40).isActive = true
//        layoutIfNeeded()
    }
}

Ive tried a huge number of variations, but to keep this short and readable (and as i think the solution is quite simple) i will leave it at this.

Obviously, i could simply do something like this and pass the touches through:

private func commonInit() {
let view = CheckView()
// add constraints here, etc.
}

This works, however is this not just adding a subview within a subview? This seems inelegant and verbose.


Solution

  • You cannot constrain a view to its superview until it has a superview. But init happens before there is a superview, so you can't move your constraint code into it. Instead, in your UIView subclass, implement didMoveToSuperview(). Now for the first time self.superview is not nil and the view can constrain itself to its superview.