iPhone正确的横向窗口坐标
Posted
技术标签:
【中文标题】iPhone正确的横向窗口坐标【英文标题】:iPhone correct landscape window coordinates 【发布时间】:2011-05-17 17:16:40 【问题描述】:我正在尝试使用以下代码获取表格视图的窗口坐标:
[self.tableView.superview convertRect:self.tableView.frame toView:nil]
它在纵向模式下报告正确的坐标,但是当我旋转到横向时,它不再报告正确的坐标。首先,它翻转 x、y 坐标以及宽度和高度。不过,这并不是真正的问题。真正的问题是坐标不正确。纵向的表格视图框架的窗口坐标是 0, 114, 320, 322,而横向的窗口坐标是 32, 0, 204, 480。显然这里的 x 值是不正确的,对吧?不应该是84吗?我正在寻找解决此问题的方法,如果有人知道如何在横向模式下获取正确的 window 视图坐标,如果您能与我分享这些知识,我将不胜感激。
这里有一些屏幕截图,您可以查看视图布局。
肖像:http://i.stack.imgur.com/IaKJc.png
横向:http://i.stack.imgur.com/JHUV6.png
【问题讨论】:
我遇到了同样的问题。有时它会正确计算坐标,有时却不能。 【参考方案1】:我已经找到了我认为是解决方案的开端。您和我看到的坐标似乎基于左下角或右上角,具体取决于方向是 UIInterfaceOrientationLandscapeRight 还是 UIInterfaceOrientationLandscapeLeft。
我还不知道为什么,但希望这会有所帮助。 :)
[更新] 所以我猜窗口的原点是正常人像模式下的 0,0,并随着 ipad/iphone 旋转。
这就是我解决这个问题的方法。
首先我在窗口中获取我的方向、窗口边界和视图的矩形(带有不稳定的坐标)
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
CGRect windowRect = appDelegate.window.bounds;
CGRect viewRectAbsolute = [self.guestEntryTableView convertRect:self.guestEntryTableView.bounds toView:nil];
然后如果方向是横向,我将x和y坐标以及宽度和高度反转
if (UIInterfaceOrientationLandscapeLeft == orientation ||UIInterfaceOrientationLandscapeRight == orientation )
windowRect = XYWidthHeightRectSwap(windowRect);
viewRectAbsolute = XYWidthHeightRectSwap(viewRectAbsolute);
然后,无论 ipad/iphone 旋转如何,我都会调用我的函数来将原点固定为基于左上角。 它根据 0,0 当前所在的位置(取决于方向)修复原点
viewRectAbsolute = FixOriginRotation(viewRectAbsolute, orientation, windowRect.size.width, windowRect.size.height);
这是我使用的两个函数
CGRect XYWidthHeightRectSwap(CGRect rect)
CGRect newRect;
newRect.origin.x = rect.origin.y;
newRect.origin.y = rect.origin.x;
newRect.size.width = rect.size.height;
newRect.size.height = rect.size.width;
return newRect;
CGRect FixOriginRotation(CGRect rect, UIInterfaceOrientation orientation, int parentWidth, int parentHeight)
CGRect newRect;
switch(orientation)
case UIInterfaceOrientationLandscapeLeft:
newRect = CGRectMake(parentWidth - (rect.size.width + rect.origin.x), rect.origin.y, rect.size.width, rect.size.height);
break;
case UIInterfaceOrientationLandscapeRight:
newRect = CGRectMake(rect.origin.x, parentHeight - (rect.size.height + rect.origin.y), rect.size.width, rect.size.height);
break;
case UIInterfaceOrientationPortrait:
newRect = rect;
break;
case UIInterfaceOrientationPortraitUpsideDown:
newRect = CGRectMake(parentWidth - (rect.size.width + rect.origin.x), parentHeight - (rect.size.height + rect.origin.y), rect.size.width, rect.size.height);
break;
return newRect;
【讨论】:
【参考方案2】:这是一个 hack,但它对我有用:
UIView *toView = [UIApplication sharedApplication].keyWindow.rootViewController.view;
[self.tableView convertRect:self.tableView.bounds toView:toView];
我不确定这是最好的解决方案。如果您的根视图控制器不支持与当前视图控制器相同的方向,它可能无法可靠地工作。
【讨论】:
【参考方案3】:你应该可以从 self.tableView.bounds 获取当前的表格视图坐标
【讨论】:
【参考方案4】:你的代码应该是:
[tableView convertRect:tableView.bounds toView:[UIApplication sharedApplication].keyWindow];
这将为您提供窗口坐标系中的视图矩形。一定要使用“边界”而不是“框架”。 frame 已经是其父视图坐标系中视图的矩形。 “bounds”是它自己系统中的视图矩形。所以上面的代码要求表格视图将自己的矩形从自己的系统转换为窗口的系统。您之前的代码要求表格的父视图将表格的矩形从父坐标系转换为空。
【讨论】:
实际上,convertRect:toView: 的文档说,“如果 view 为 nil,则此方法将转换为窗口基坐标。”我试过你的代码,结果和我的一样。不过还是谢谢你的建议。【参考方案5】:尝试使用边界而不是框架
self.parentViewController.view.bounds
因为它给了我根据当前方向调整的坐标
【讨论】:
以上是关于iPhone正确的横向窗口坐标的主要内容,如果未能解决你的问题,请参考以下文章
如果应用程序以 iPhone 横向启动,iOS 13 应用程序窗口会在 iPhone 上错误地旋转
JTRevealSideBar UI 在 iPhone 和 iPad 的横向模式下无法正确显示