如何以编程方式为我在容器视图中调用的 ViewController 设置约束?

How to put constraints for a ViewController programatically which I'm calling in a container view?

我用了一个 PageViewController 用于三个滚动类型的控制器。现在我在 containerView 中调用了这个 PageViewController,这里的问题是容器高度小于 PageViewController 的高度,我可以在 containerView 中调用 PageViewController 但底部超出了视图.我试图以编程方式放置自动布局,但它没有用。让我知道如何解决这个问题?

@IBOutlet weak var containerView: UIView!


    override func viewDidLoad() {
        super.viewDidLoad()
        let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
        let controller = storyboard.instantiateViewController(withIdentifier: "ViewController")
        self.setControllerFrame(controller: controller )
        addChild(controller)
        self.containerView.addSubview(controller.view)

    }

    func setControllerFrame(controller: UIViewController){
        //Validating frames according to orientation
        self.view.setNeedsDisplay()
        self.view.layoutIfNeeded()
        //*******temp fix:******** this is solutions for a single device not for all devices(screen sizes).
        if (self.view.frame.size.width < self.view.frame.size.height){
        controller.view.frame = CGRect.init(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)
        } else if (self.view.frame.size.width >= self.view.frame.size.height){
        controller.view.frame = CGRect.init(x: 0, y: 0, width: self.view.frame.size.height, height: self.view.frame.size.width)
        }
         //tried this but crashes at last line.
        controller.view.translatesAutoresizingMaskIntoConstraints = false
        let topConstraint = NSLayoutConstraint(item: controller.view!, attribute: NSLayoutConstraint.Attribute.top, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.containerView, attribute: NSLayoutConstraint.Attribute.top, multiplier: 1, constant: 0)
        let bottomConstraint = NSLayoutConstraint(item: controller.view!, attribute: NSLayoutConstraint.Attribute.bottom, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.containerView, attribute: NSLayoutConstraint.Attribute.bottom, multiplier: 1, constant: 0)
        let leadingConstraint = NSLayoutConstraint(item: controller.view!, attribute: NSLayoutConstraint.Attribute.leading, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.containerView, attribute: NSLayoutConstraint.Attribute.leading, multiplier: 1, constant: 0)
        let trailingConstraint = NSLayoutConstraint(item: controller.view!, attribute: NSLayoutConstraint.Attribute.trailing, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.containerView, attribute: NSLayoutConstraint.Attribute.trailing, multiplier: 1, constant: 0)
        view.addConstraints([topConstraint, bottomConstraint, leadingConstraint, trailingConstraint])
}

上面的代码 *******temp fix:******** 解决了我对单个设备屏幕的问题,但没有解决所有设备的问题。所以请告诉我一个合适的解决方案

1- 里面 viewDidLoad frame 还不正确所以设置里面 viewDidLayoutSubviews

controller.view.frame  = // value

2-这崩溃了

view.addConstraints([topConstraint, bottomConstraint, leadingConstraint, trailingConstraint])

因为你应该在设置约束之前添加子视图

self.containerView.addSubview(controller.view)

下面的代码解决了我的问题。

   var controller: ViewController!

   override func viewDidLoad() {
        super.viewDidLoad()
        let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
        controller = storyboard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
        addChild(controller)
        self.containerView.addSubview(controller.view)
        self.setControllerFrame(controller: controller )

    }

    func setControllerFrame(controller: UIViewController){
        self.view.setNeedsDisplay()
        self.view.setNeedsLayout()

        controller.view.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            controller.view.topAnchor.constraint(equalTo: self.containerView.topAnchor, constant: 0),
            controller.view.bottomAnchor.constraint(equalTo: self.containerView.bottomAnchor, constant: 0),
            controller.view.leadingAnchor.constraint(equalTo: self.containerView.leadingAnchor, constant: 0),
            controller.view.trailingAnchor.constraint(equalTo: self.containerView.trailingAnchor, constant: 0)
            ])
    }