UIView 绝对屏幕点

Posted

技术标签:

【中文标题】UIView 绝对屏幕点【英文标题】:UIView absolute screen point 【发布时间】:2015-03-04 20:02:53 【问题描述】:

有没有一种简单的方法可以获取 UIView 的绝对点?绝对是指 UIView 在 iPad 上相对于 1024x768 的位置?

我需要一个简单的方法,因为我在 UITableView 内的 UITableViewCell 内有一个 UIButton,该 UIButton 在一个视图控制器呈现的视图内,该视图控制器是另一个视图控制器的子级,重复到第五个或第六个视图控制器。 由于这种复杂的设计,我需要 UIButton 的绝对矩形,这样我就可以在“主”视图控制器上显示 UIActionSheet。

【问题讨论】:

绝对是什么意思?你的例子不清楚。 屏幕上的原点。格雷伯爵做对了:) 【参考方案1】:

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

您将计算该点的全局坐标

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

localCoordinatesOfThePoint也是一个CGPoint结构。

另一种情况

当你用根视图覆盖整个屏幕时,它有一个大视图,(尽管仍然比根视图小),这个大视图有一个小视图作为其中的子视图。

你会计算小视图的tip的位置

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

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

捕捉

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

我们必须

#import "AppDelegate.h"

在我们计算的类中,然后将窗口属性作为参考视图传递。保证窗口覆盖屏幕,UIWindow 是 UIView 的子类。所以它只是工作。

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

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

【讨论】:

我似乎无法让它工作。我已经尝试了上述各种情况,但没有运气。我肯定遗漏了一些东西,我无法将整个代码作为示例发布,但我找到了解决方案。看我的回答 嗯,有点。 “appDelegate.window”似乎可以解决问题,但不知何故,我以 origin.x 退出屏幕而告终。我只是需要一些调整。对我来说最简单和最准确的最终成为我的答案。感谢您的帮助! 您是在纵向还是横向上运行您的 ipad 版本?我相信偏移量是屏幕宽度和高度之间的增量。 Besically他们被交换了。是这样吗?【参考方案2】:

你要找的是:

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

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

Documentation

【讨论】:

我的问题是按钮不知道顶层视图(这也是一个糟糕的设计) 看这个:***.com/questions/1465394/… 感谢您的建议 - 请参阅我对 Earl Grays 帖子的评论【参考方案3】:

如果你想在某个UIView 中获取CGPoint/ CGRect 的坐标,可以使用UIView 方法

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

CGRect

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

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

【讨论】:

我的问题是按钮不知道顶层视图(这也是一个糟糕的设计) 你是从 UIButton 的子类转换 CGRect 还是什么? 我基本上只是想从 UIButton 显示一个操作表【参考方案4】:

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
 

【讨论】:

【参考方案5】:

所以我最终改用 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);

【讨论】:

【参考方案6】:

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

UIAccessibilityConvertPathToScreenCoordinates

UIAccessibilityConvertFrameToScreenCoordinates

这确实会返回路径或矩形,但您可以从中提取点。

【讨论】:

不幸的是,这只适用于获取相对于超级视图的框架。【参考方案7】:

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

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

【讨论】:

以上是关于UIView 绝对屏幕点的主要内容,如果未能解决你的问题,请参考以下文章

动画调整全屏 UIView 的大小以在屏幕底部显示另一个 UIView

UIView详解

视图鼻祖之UIView详解

呈现 UIView 的最少代码

将 MPMoviePlayerController 视图置于 UIview 的中心(相同位置)

在 UIView 中查找特定点