iPhone正确的横屏窗口坐标

8
我正在尝试使用以下代码获取表视图的窗口坐标:
[self.tableView.superview convertRect:self.tableView.frame toView:nil]
在纵向模式下,它报告了正确的坐标,但是当我旋转到横向模式时,它不再报告正确的坐标。首先,它翻转了x、y坐标和宽度和高度,但这并不是真正的问题。真正的问题是坐标不正确。在纵向模式下,表视图框架的窗口坐标为{{0, 114}, {320, 322}},而在横向模式下,窗口坐标为{{32, 0}, {204, 480}}。很明显,这里的x值是不正确的,对吧?我正在寻找解决这个问题的方法,如果有人知道如何以横向模式获取视图的正确窗口坐标,我将非常感激您与我分享这些知识。
这里有一些屏幕截图,让您可以查看视图布局。
纵向模式:http://i.stack.imgur.com/IaKJc.png

风景:http://i.stack.imgur.com/JHUV6.png


我也遇到了同样的问题。有时它能正确计算坐标,有时却不能。 - Bob Spryn
5个回答

6
我找到了我认为是解决方案的开端。看起来,你和我看到的坐标是基于左下角或右上角,具体取决于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;
}

3
这是一个hack,但对我有效。
UIView *toView = [UIApplication sharedApplication].keyWindow.rootViewController.view;
[self.tableView convertRect:self.tableView.bounds toView:toView];

我不确定这是否是最佳解决方案。如果您的根视图控制器不支持与当前视图控制器相同的方向,则其可靠性可能不高。


0

你的代码应该是:

[tableView convertRect:tableView.bounds toView:[UIApplication sharedApplication].keyWindow];

这将为您提供窗口坐标系中视图的矩形。请确保使用“bounds”而不是“frame”。“frame”已经是父视图坐标系中视图的矩形了。“bounds”是视图在自己的系统中的矩形。因此,上面的代码要求表视图将其自己的矩形从自己的系统转换到窗口的系统。您以前的代码是要求表格的父视图将表格的矩形从父坐标系转换到没有什么。


实际上,convertRect:toView: 的文档中写道:“如果视图为 nil,则此方法将转换为窗口基础坐标。”我尝试了您的代码,它给出了与我的相同的结果。不过还是谢谢您的建议。 - EJV

0

你应该能够从self.tableView.bounds获取当前表格视图的坐标


0
尝试使用边界(bounds)而不是框架(frame),self.parentViewController.view.bounds根据当前方向给出已调整的坐标。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接