UIView绝对屏幕点

UIView absolute screen point

有没有简单的获取UIView绝对点的方法?绝对是指 UIView 相对于 iPad?

上 1024x768 的位置

我需要一个简单的方法,因为我在 viewcontroller 呈现的视图中的 UITableViewCell 中有一个 UIButton,它是另一个视图控制器的子项,重复到第五或第六个视图控制器。 由于这种复杂的设计,我需要 UIButton 的绝对矩形,这样我就可以在 "main" viewcontroller.

上显示一个 UIActionSheet

如果想得到CGPoint/CGRect在某个UIView的坐标可以使用UIView方法

- (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view

CGRect

- (CGRect)convertRect:(CGRect)rect toView:(UIView *)view

在第一个参数中输入要转换的 CGPoint/CGRect,在第二个参数中输入要转换为

UIView

您要找的是:

- (CGPoint)convertPoint:(CGPoint)point
                 toView:(UIView *)view

这会将点从接收器的坐标系(您的按钮)转换为指定视图(顶级视图)的坐标系。

Documentation

所以,我们有一个内部有特定点的小视图。该点相对于其父视图(小视图)具有 局部坐标 。 现在,我们想知道,那个点的坐标是什么 如果它留在屏幕上的同一位置,但它将成为根视图的一部分。 (这有效地为我们提供了相对于整个屏幕的坐标。)

您将计算该点的全局坐标

CGPoint globalCoordinates = [self.smallView convertPoint:localCoordinatesOfThePoint 
                                                  toView:self.view];

localCoordinatesOfThePoint也是一个CGPoint结构

另一种情况

是当你用根视图覆盖整个屏幕时,它有一个大视图,(虽然仍然比根视图小),这个大视图有一个小视图作为它里面的子视图。

您将计算小视图的尖端​​位置

CGPoint originOnScreen = [self.smallView convertPoint:self.smallview.origin 
                                               toView:self.view];

self.smallview.origin是相对于Large view的CGPoint。因此,我们计算,如果这个点(它实际上是小视图的左上角)在根视图内,它的坐标是多少。

赶上

如果根视图不是全屏,而不是根视图,我们需要获取对主视图的引用 window 因为这将是我们现在计算坐标的视图。

我们必须

#import "AppDelegate.h"

在我们的class里我们计算然后传递window属性作为参考视图。保证window覆盖屏幕,UIWindow是UIView的subclass。所以它才有效。

AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];

CGPoint originOnScreen = [self.smallView convertPoint:self.smallview.origin 
                                               toView:appDelegate.window];

所以我最终改用 UITapGestureRecognizer 并像这样计算位置:

    CGPoint gestureViewLocation = [gesture locationInView:gesture.view];
    CGPoint absoluteLocation = [gesture locationInView:self.parentViewController.view];
    CGRect fromRect = CGRectMake(absoluteLocation.x-gestureViewLocation.x, //subtract to we get point relative to gesture view
                                 absoluteLocation.y-gestureViewLocation.y, //subtract to we get point relative to gesture view
                                 gesture.view.frame.size.width,
                                 gesture.view.frame.size.height);

要将视图的本地框架或路径转换为屏幕坐标,请使用内置转换器:

UIAccessibilityConvertPathToScreenCoordinates

UIAccessibilityConvertFrameToScreenCoordinates

这 return 路径或矩形,但您可以从中提取点。

Swift 4 转换似乎适用于超过两层的子视图:

// given that myView is in hierarchy of rootView, either
// have rootView convert its origin from myView, or
// have myView convert rootView's origin to rootView

rootView.convert(rootView.origin, from: myView)
var absView = myView.convert(rootView.origin, to: rootView)

我发现转换例程有些混乱。所以,我用 5 个级别的视图蛮力测试了所有可能的组合。结果posted on github

[编辑] 当 rootView 为 UITableView 时,调整 contentOffset:

 if let tableView = rootView as? UITableView {
        absView.y -= tableView.contentOffset.y
 }

您可以使用以下方法实现任何视图的绝对框架:

func getAbsoluteFrame(of view: UIView, rootViewController: UIViewController) -> CGRect {
    guard let parentView = view.superview else {
        print("Super view of this view is nil")
        return view.frame
    }
    
    return rootViewController.view.convert(view.frame, from: parentView)
}

你可以这样获取rootViewController:

let rootViewController = UIApplication.shared.keyWindow!.rootViewController