在视图坐标系之间转换框架

知道子视图的确切位置是一种可以在多种情况下派上用场的技术。 您可能想知道用户是否可以看到该视图,从视图的初始位置执行动画或将视图还原到其原始目的地。 有很多用例。 您可能还会想到更多。 但是,当您要执行此操作时,您不能仅仅依赖目标视图的框架,因为它只是其超级视图坐标系的一部分,这很快会引起问题,具体取决于您如何构成视图层次结构。 幸运的是, UIViewNSView都有一些方法可以为我们提供所需的结果。 如果您阅读我的上一篇有关框架如何在macOS上工作的文章,您可能还记得我们曾简要介绍过坐标系。

因此,让我们深入了解如何在不同的坐标系之间转换框架。

现在,我们已经设置了场景,让我们看一下整篇文章所涉及的方法, convert(CGRect,to:UIView?)方法。

如果我们检查从访问视图框架中获得的值。 它是视图坐标空间内的正确值,但是当尝试在扩展到视图坐标空间外部的上下文中组合这些类型的值时,这并不能使其普遍正确。

我们要实现的是知道视图在屏幕上的确切位置,而不是子视图内的位置。

因此,通过传递当前帧并将其指向所需的坐标空间,我们现在可以获得所需的测量值。 您可以切换到任何您喜欢的坐标系。 我选择了过去与我最相关的窗口。

在实现中执行此操作时,访问视图的窗口很简单。 所有UIView都有对其所属窗口的可选引用,如果该值为nil,则表示该视图尚未添加到窗口中。

附带说明,这只是冰山一角。 这些方法中有更多的是采用点而不是框架。 请查看UICoordinateSpace以获取更多信息。

https://developer.apple.com/documentation/uikit/uicoordinatespace

这些方法在UIWindow上也可用的原因是它继承自UIView ,后者又符合UICoordinateSpace

如您所见,这是直接但功能强大的,但是macOS呢? 让我们看一下带有一些macOS代码的另一个示例。

该技术本身以及转换时的结果保持不变。 这两个示例之间唯一明显的区别是,它使用NSView表示窗口。 原因是NSWindow不符合PlaygroundLiveViewable

即使这看起来很虚伪,但在思考如何解决特定情况时,该技术也具有巨大的价值。 我在优化滚动视图和集合视图的滚动性能时都使用了此方法,如果该视图在屏幕上不可见,则不执行布局操作。 我还使用了这些类型的值来定义核心动画的开始和结束位置。 我相信您可以提出更多方案,关键是要知道该技术可以扩展您的工具箱,并且您获得的工具箱越大,找到问题的最佳解决方案就越自然。

希望您觉得这有用,对我而言,这已经无数次挽救了生命。