【问题标题】:UIView Position After Device Orientation设备方向后的 UIView 位置
【发布时间】:2020-07-25 09:45:41
【问题描述】:

考虑将一个视图作为子视图添加到主视图,如下所示:

override func viewDidLoad()
{
    super.viewDidLoad()
    let subview = UIView(frame: CGRect(x: 150, y: 350, width: 20, height: 20))
    subview.backgroundColor = UIColor.blue
    self.view.addSubview(subview)
}

当设备从纵向变为横向时,默认行为是子视图的移动方式使其与设备左上角的水平和垂直距离保持不变。我该如何更改它以使其与设备中心的水平和垂直距离保持不变?谢谢

【问题讨论】:

    标签: ios swift uiview position orientation


    【解决方案1】:

    最简单的方法是为您的视图使用约束而不是固定框架。 代码看起来像这样:

    override func viewDidLoad()
    {
        super.viewDidLoad()
        let subview = UIView()
    
        /// You do not need to refer to self and UIColor, Swift does that for you.
        subview.backgroundColor = .blue
        view.addSubview(subview)
    
        /// Do not forget the following line
        subview.translatesAutoresizingMaskIntoConstraints = false
    
        /// Create and activate your constraints in one step.
        NSLayoutConstraint.activate([
            /// Set the height and width of your subview
            subview.heightAnchor.constraint(equalToConstant: 20),
            subview.widthAnchor.constraint(equalToConstant: 20),
    
            /// This centers the subview vertically and horizontally in the parent view
            subview.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            subview.centerYAnchor.constraint(equalTo: view.centerYAnchor)
        ])
    }
    

    您还应该重构上面的代码,例如创建设置所有内容的方法并在 viewDidLoad 内部调用它。

    【讨论】:

    • 不客气,也可以设置为接受的答案,方便其他人更快找到。
    • 亲爱的 Iaka,我不能接受它作为正确答案,因为您的方法只是将子视图放在纵向和横向的超级视图的中心。我的问题如下:当子视图位于父视图中的任意位置(无论是否位于其中心)时,如果方向发生更改,系统会通过将子视图与上层的水平和垂直距离保持不变来设置新布局超级视图的左角。我希望通过保持与超级视图中心的水平和垂直距离保持不变来设置新布局。
    • 好的,抱歉。然后我真的不明白你想要达到什么目的。如果您不想让两个视图彼此居中,您可以传入一个常量。我建议在使用 UIView 时使用 AutoLayout。这比您自己进行像素计算要强大得多。
    • 目标是设备方向前后两个视图中心的距离保持不变。请注意,我将添加可能会更改子视图中心的手势(超级视图的中心将保持不变)。这可以用 AutoLayout 实现吗?
    • 您可以将约束保存到 let 并将其常量属性设置为“移动”它。例如:let constraint = subView.centerXAnchor.constraint(equalTo: superView.centerXAnchor) 然后你可以像这样抵消你的约束:constraint.constant = 123。不要忘记在之前激活你的约束(如我的示例所示)或者只是通过调用constraint.isActive = true
    【解决方案2】:

    我找到了答案:

     override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator)
    {
        super.willTransition(to: newCollection, with: coordinator)
        //here, the distance (just before the orientation) between the subview's center and superview's center can be derived
    }
    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?)
    {
        super.traitCollectionDidChange(previousTraitCollection)
        //here, the distance derived above can be used to set the subview to the desired position in it's superview
    }
    

    我在这篇文章中描述了这两个函数的工作原理:Swift - How to detect orientation changes

    【讨论】:

      猜你喜欢
      • 2014-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-14
      • 1970-01-01
      • 1970-01-01
      • 2015-04-30
      相关资源
      最近更新 更多