【问题标题】:Are rotated Views compatible with Auto Layout?旋转视图是否与自动布局兼容?
【发布时间】:2015-06-15 08:56:25
【问题描述】:

我已经学会了如何使用仿射变换旋转视图(请参阅here)。我还了解了自动布局(参见herehere),甚至还有程序化自动布局(参见herehere)。但是,我不知道如何让自动布局与旋转视图一起使用。

这张图片显示了我想做的事情:

我认为问题在于宽度和高度因旋转而发生变化。有没有办法让旋转视图填充它的超级视图?是否有一些技巧可以让自动布局工作,或者它只是在旋转后不兼容?

(我只学过 Swift,但如果你更熟悉的话,我很乐意学习 Objective-C 的答案。)

更新

按照@VinayJain 的建议,我做了以下事情:

  • 将子视图边缘固定到情节提要中的父视图。
  • created IBOutlets 用于子视图所有边的间距限制。

    @IBOutlet weak var rightSpace: NSLayoutConstraint!
    @IBOutlet weak var leftSpace: NSLayoutConstraint!
    @IBOutlet weak var topSpace: NSLayoutConstraint!
    @IBOutlet weak var bottomSpace: NSLayoutConstraint!
    
  • 旋转子视图

    subview.transform = CGAffineTransformMakeRotation(CGFloat(M_PI_2))
    
  • 改变了网点的约束

    self.rightSpace.constant = CGFloat(0)
    self.leftSpace.constant = CGFloat(0)
    self.topSpace.constant = CGFloat(0)
    self.bottomSpace.constant = CGFloat(0)
    

但正是在这一点上,我意识到我真的不需要更改间距值。我希望间距保持为 0。我只需要它自行调整。然而,旋转把这搞砸了。效果如下图所示:

【问题讨论】:

  • 您找到解决方案了吗?我尝试将子视图的顶部固定在父视图的右侧(等所有方面)无济于事。
  • @BFeher,是的,我自定义了UIView(上图黄色)。它由三个视图组成:父视图、子视图和孙视图。孙子视图是我要旋转显示的实际内容(文本视图等)。子视图是实际旋转的。 (孙视图位于子视图中并且不知道旋转。)子视图以编程方式设置为与父视图相同的大小。然后您可以在父视图上设置约束以将其排列在情节提要中(上图蓝色)。
  • 查看github project 了解我当前的实现。具体看layoutSubviews()方法。它还处理方向变化。它不是一个完美的解决方案,但它可以像任何其他 UIView 一样在情节提要中设置约束。
  • 谢谢!它似乎有效,就我而言,我不支持多个布局,因此设备旋转不是问题。

标签: ios rotation autolayout


【解决方案1】:

我在尝试通过 HDMI / AirPlay 将外部视频从 iOS 运行到旋转的电视屏幕时遇到了这个问题。

有时,电视会设置将信号“旋转”90 度或 180 度等,但通常它没有该选项。

使用这样的“包装”视图,我可以强制外部屏幕上的视图控制器旋转其内容,而内容实际上并不知道有什么不同。

let contentsView = SomeWildCustomViewUsingAutoLayoutEtc()
let wrapper = RotatingWrapperView(contentsView)
wrapper.translatesAutoresizingMaskIntoConstraints = false
parentView.addSubview(wrapper)
// ...
wrapper.rotation = .upsideDown

RotatingWrapperView的来源:https://github.com/quantcon/UIKit/blob/master/AutoLayoutRotationDemo/Views/RotatingWrapperView.swift

【讨论】:

    【解决方案2】:

    在使用自动布局设置我的 UI 后,我创建了一个标签,将其旋转,然后将边界设置为已布局的视图。

    let lbl = UILabel()
        lbl.text = Constants.UI.FlightRequest.flightRequest
        lbl.textColor = .white
        lbl.font = UIFont.systemFont(ofSize: 12)
        lbl.rotation = -90
        lbl.textAlignment = .center
        lbl.frame = blueSideBar.bounds //<--- here is where I set the frame
        blueSideBar.addSubview(lbl)
    
    var rotation: Int {
        get {
            return 0
        } set {
            let radians = ((CGFloat.pi) * CGFloat(newValue) / CGFloat(180.0))
            self.transform = CGAffineTransform(rotationAngle: radians)
        }
    }
    

    【讨论】:

      【解决方案3】:

      你可以很容易地使用自动布局来做到这一点,

      • 通过将边缘固定到超级视图来创建约束
      • 为这些约束创建 outlet(比如 leftSpace、rightSpace、topSpace、bottomSpace)

      • 检查旋转,并相应地更新这些值

      使用它来检查旋转:Check Rotation

      【讨论】:

      • 手动旋转的只是子视图,而不是整个设备的方向。但是,您的答案的逻辑仍然有效。我只是将您的“检查旋转”替换为我执行 AffineTransformRotate 的点。我会试试看,稍后更新。
      • @Suragch 太好了,检查它是否适合你,如果它有效,你可以根据你的要求编辑我的答案
      • 很遗憾,我无法让您的方法发挥作用。我用尝试您的解决方案的结果更新了我的问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多