首页 > 解决方案 > UIKit 更改呈现的视图控制器相对于父视图的布局约束

问题描述

我正在使用 UIKit 开发一个项目,没有情节提要(仅编程布局约束),并且在之后,我有一个像这样的自定义视图控制器:


@objc public class testController: UIViewController, QLPreviewControllerDataSource {
    
    public override func viewDidAppear(_ animated: Bool) {
        
        let previewController = QLPreviewController()
        previewController.dataSource = self
        
        self.view.translatesAutoresizingMaskIntoConstraints = false
        previewController.view.widthAnchor.constraint(equalToConstant: 200).isActive = true
        present(previewController, animated: true, completion: nil)
    }

    
    public func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
        return 1
    }
    
    public func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
        guard let url = Bundle.main.url(forResource: String("beans"), withExtension: "pdf") else {
            fatalError("Could not load \(index).pdf")
        }

        return url as QLPreviewItem
    }
     
}

然后,在我的主视图控制器文件中,我将此 testController 添加为子视图,如下所示:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        let test = testController()
        self.view.addSubview(test.view)
        test.view.translatesAutoresizingMaskIntoConstraints = false
        
    }


}

这很好用,但我希望能够更改我的 testController相对于它的 parent view的编程布局约束。

我在主视图控制器(ViewController)中尝试过这样的东西:

       let test = testController()
        self.view.addSubview(test.view)
        test.view.translatesAutoresizingMaskIntoConstraints = false
        test.view.widthAnchor.constraint(equalTo: 200, constant: 0).isActive = true

但这根本不起作用/视图根本没有反映这些约束,而且似乎我可以成功修改 testController 约束的唯一方法是在viewDidAppeartestController 类的函数内。

但是,如果我尝试这样的事情:

    public override func viewDidAppear(_ animated: Bool) {

        let previewController = QLPreviewController()
        previewController.dataSource = self

        self.view.translatesAutoresizingMaskIntoConstraints = false
        previewController.view.widthAnchor.constraint(equalToConstant: 200).isActive = true //notice how this works since it's a hardcoded 200
        previewController.view.centerXAnchor.constraint(equalTo: self.view.centerXAnchor, constant: 0).isActive = true //this throws an error

        present(previewController, animated: true, completion: nil)
    }

我收到一个错误。

所以我想以某种方式访问​​我猜想的 testViewController 的级,并将其用于视图的约束。我尝试使用presentingViewControllerand失败parent,但它们要么返回 nil,要么抛出错误。

这里的任何帮助将不胜感激。

标签: iosswiftuiviewcontrolleruikitnslayoutconstraint

解决方案


这是添加视图和更改约束的示例,在您的示例中,您必须向测试视图添加更多约束。

class ViewController: UIViewController {

    let buttonTest: UIButton = {
       let button = UIButton()
        button.setTitle("go to ", for: .normal)
        button.backgroundColor = .green
        button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
        return button
    }()
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        self.view.addSubview(buttonTest)
        buttonTest.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            buttonTest.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
            buttonTest.centerXAnchor.constraint(equalTo: self.view.centerXAnchor)
        ])
    }

    @objc func buttonPressed() {
        let secondView = SecondViewController()
        self.view.addSubview(secondView.view)
        secondView.view.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            secondView.view.topAnchor.constraint(equalTo: self.view.topAnchor,constant: 100),
            secondView.view.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
            secondView.view.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
            secondView.view.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -100)
        ])
        
        
    }

}


class SecondViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .blue
    }
}

推荐阅读