swift 为什么一个UIView的框架在一个UIViewController控制下在旋转屏幕上正确调整大小?

jecbmhm3  于 2023-09-30  发布在  Swift
关注(0)|答案(1)|浏览(137)

举个例子:
当我以编程方式添加视图并设置其框架时…

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let subview = UIView()
        subview.backgroundColor = .red
        subview.frame = view.frame
        view.addSubview(subview)
    }
}

当我旋转屏幕时,它不会调整大小

然而,当我添加一个由视图控制器生成的视图时,如下所示:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let subview = UIViewController().view!
        subview.backgroundColor = .red
        subview.frame = view.frame
        view.addSubview(subview)
    }
}

当我旋转屏幕时,它会调整大小。

这是怎么回事?为什么这两个视图处理trait集合变化的方式不同?
这是否意味着我应该使用约束,无论什么(即使在自定义演示模式转换和推送导航转换,苹果的文档似乎建议使用框架?)

qhhrdooz

qhhrdooz1#

这很奇怪...

let subviewFromVC = UIViewController().view!

您正在创建UIViewController()示例(* 与 * 当前 * 视图控制器无关 *),并获取对其.view的引用。
然后将该视图添加为子视图,并设置其框架。
UIViewController的“基本”视图包含:

.autoresizingMask = [.flexibleWidth, .flexibleHeight]

所以它会自动调整大小
但是,当您执行此操作时:

let subview = UIView()
subview.backgroundColor = .red
subview.frame = view.frame
view.addSubview(subview)

默认情况下,创建subview时使用:

.autoresizingMask = []

所以它不会自动调整大小
如果你想让subview根据你设置的帧自动调整大小,你需要设置这个蒙版:

let subview = UIView()
subview.backgroundColor = .red
subview.frame = view.frame

subview.autoresizingMask = [.flexibleWidth, .flexibleHeight]

view.addSubview(subview)

如果你正在创建一个新的子视图,或者可能是多个子视图,这些子视图会自动调整大小和位置,你将需要各种.autoresizingMask标志的组合:

.flexibleWidth, .flexibleHeight,
.flexibleTopMargin, .flexibleBottomMargin,
.flexibleLeftMargin, .flexibleRightMargin,

如果没有看到您想要的UI布局,就不能提供更多的东西--但这至少应该让您走上正轨。

编辑- * 混合frame和约束... *

我们在定制的UIPresentationController中看到类似viewToPresent.frame.origin.x =的东西的原因是因为那个视图是用.autoresizingMask = [.flexibleWidth, .flexibleHeight]示例化的。所以,以“从左边滑进去”为例,我们会沿着这些线条制作动画:

viewToPresent.frame.origin.x = -viewToPresent.frame.width

UIView.animate(withDuration: 0.3, animations: {
    viewToPresent.frame.origin.x = 0.0
})

这也可以通过约束来完成,但是对于这个用例,设置帧值(也许)更容易。
不过,对于“变暗视图”,使用约束似乎更有意义,因为它的大小/位置不会被动画化。
通常不明显的是:

someView.translatesAutoresizingMaskIntoConstraints = true
  • 非 * 是否表示未使用自动布局...这意味着视图的.autoresizingMask * 被转换为约束 *。

相关问题