旋转视图是不是与自动布局兼容?

Posted

技术标签:

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

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

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

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

(我只学过 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 一样在情节提要中设置约束。 另见Rotating a view in layoutSubviews 谢谢!它似乎有效,就我而言,我不支持多个布局,因此设备旋转不是问题。 【参考方案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 太好了,检查它是否适合你,如果它有效,你可以根据你的要求编辑我的答案 很遗憾,我无法让您的方法发挥作用。我用尝试您的解决方案的结果更新了我的问题。

以上是关于旋转视图是不是与自动布局兼容?的主要内容,如果未能解决你的问题,请参考以下文章

Xcode 自动布局和旋转

视图控制器和自动布局旋转问题

如何使用自动布局以编程方式快速设置旋转时 UICollectionView 的宽度

iOS 中的自动布局

自动布局正在改变 UIScrollView 的 contentOffset 旋转

自动布局视图不会对手机的旋转做出反应