使用自动布局以编程方式展示弹出式视图控制器

时间:2019-04-16 19:24:27

标签: ios swift

我正在通过代码构建UI,并且需要在当前控制器上方显示另一个视图控制器作为弹出窗口。弹出窗口将充当模式对话框,并使用屏幕大小的约50%。弹出窗口的内容必须限制在屏幕中心并支持设备旋转。

我的初始实现是在PopoverController类的viewDidLoad()中完成的,并且按预期方式工作。但是,我不想在控制器中查看代码。将弹出视图移到一个单独的文件后,乐趣开始了。自动布局和设备旋转不再按预期工作。

我已经制作了一个基本的应用程序来展示这一点。主控制器具有用于显示弹出窗口的按钮。弹出框的背景为黄色,中间应该显示为蓝色。

MainViewController ::用于显示弹出窗口的“测试”按钮

@objc func boxButtonTapped() {
        let vc = PopoverController()
        vc.modalPresentationStyle = .overCurrentContext
        vc.modalTransitionStyle = .crossDissolve
        present(vc, animated: true, completion: nil)
    }

Popover Controller

class PopoverController: UIViewController {

    var popoverView = PopoverView()

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func loadView() {
        view = popoverView
    }
}

全景视图

class PopoverView: UIView {

    let blueBox: UIView = {
        let bb = UIView()
        bb.backgroundColor = .blue
        //bb.frame.size = CGSize(width: 100, height: 100)
        bb.translatesAutoresizingMaskIntoConstraints = false
        return bb
    }()

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

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

    func createSubViews() {
        translatesAutoresizingMaskIntoConstraints = false
        backgroundColor = .yellow

        addSubview(blueBox)

        blueBox.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        blueBox.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
        blueBox.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 0.7).isActive = true
        blueBox.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 0.4).isActive = true
    }
}
  1. 运行上述代码时,甚至不会显示弹出窗口!这是我的第一个问题,有谁知道为什么?

  2. 如果更改,则将transformsAutoresizingMaskIntoConstraints = false转换为true。然后会显示弹出窗口,但是在设备旋转时不会调整大小。我不知道为什么,我也不明白为什么需要将transformsAutoresizingMaskIntoConstraints设置为true才能使视图首先显示。

对于这种琐碎的任务,必须有一个简单的解决方案。我尝试了很多不同的方法,将它们列出在这里是不可能的。我是IOS开发人员和Swift的新手,我真的很想开始使用干净的代码。谢谢您的时间!

更新 我在GitHub上发布了示例项目。因此,如果您有时间想要挑战/证明一个概念,那么这里就是:https://github.com/igunther/CleanController

2 个答案:

答案 0 :(得分:1)

如果您自己没有添加约束(在这种情况下不是),您仍然需要告诉视图如何运行。

将您的createSubviews()函数更改为此:

func createSubViews() {
    //translatesAutoresizingMaskIntoConstraints = false

    autoresizingMask = [.flexibleHeight, .flexibleWidth]

    backgroundColor = .yellow

    addSubview(blueBox)

    blueBox.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
    blueBox.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
    blueBox.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 0.7).isActive = true
    blueBox.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 0.4).isActive = true

}

这将允许自动布局在设备旋转时重新布局视图。

答案 1 :(得分:0)

根据Apple文档的translatesAutoresizingMaskIntoCon

  

如果此属性的值为true,则系统将创建一组约束,这些约束将复制视图的自动调整大小蒙版所指定的行为。

  

默认情况下,以编程方式创建的任何视图的属性都设置为true。如果在Interface Builder中添加视图,则系统会自动将此属性设置为false。

我的猜测是,当设置为false时,它将查找不存在的约束。

就旋转而言,您可以在VC中放置shouldAutorotate属性吗?

相关问题