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