iPhone correct landscape window coordinates

百般思念 提交于 2019-12-12 07:55:00

问题


I am trying to get the window coordinates of a table view using the following code:

[self.tableView.superview convertRect:self.tableView.frame toView:nil]

It reports the correct coordinates while in portrait mode, but when I rotate to landscape it no longer reports correct coordinates. First off, it flips the x, y coordinates and the width and height. That's not really the problem though. The real problem is that the coordinates are incorrect. In portrait the window coordinates for the table view's frame are {{0, 114}, {320, 322}}, while in landscape the window coordinates are {{32, 0}, {204, 480}}. Obviously the x-value here is incorrect, right? Shouldn't it be 84? I'm looking for a fix to this problem, and if anybody knows how to get the correct window coordinates of a view in landscape mode, I would greatly appreciate it if you would share that knowledge with me.

Here are some screenshots so you can see the view layout.

Portrait: http://i.stack.imgur.com/IaKJc.png

Landscape: http://i.stack.imgur.com/JHUV6.png


回答1:


I've found what I believe to be the beginnings of the solution. It seems the coordinates you and I are seeing are being based on the bottom left or top right, depending on whether the orientation is UIInterfaceOrientationLandscapeRight or UIInterfaceOrientationLandscapeLeft.

I don't know why yet, but hopefully that helps. :)

[UPDATE] So I guess the origin of the window is 0,0 in normal portrait mode, and rotates with the ipad/iphone.

So here's how I solved this.

First I grab my orientation, window bounds and the rect of my view within the window (with the wonky coordinates)

UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
CGRect windowRect = appDelegate.window.bounds;
CGRect viewRectAbsolute = [self.guestEntryTableView convertRect:self.guestEntryTableView.bounds toView:nil];

Then if the orientation is landscape, I reverse the x and y coordinates and the width and height

if (UIInterfaceOrientationLandscapeLeft == orientation ||UIInterfaceOrientationLandscapeRight == orientation ) {
    windowRect = XYWidthHeightRectSwap(windowRect);
    viewRectAbsolute = XYWidthHeightRectSwap(viewRectAbsolute);
}

Then I call my function for fixing the origin to be based on the top left no matter the rotation of the ipad/iphone. It fixes the origin depending on where 0,0 currently lives (depending on the orientation)

viewRectAbsolute = FixOriginRotation(viewRectAbsolute, orientation, windowRect.size.width, windowRect.size.height);

Here are the two functions I use

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:


This is a hack, but it works for me:

UIView *toView = [UIApplication sharedApplication].keyWindow.rootViewController.view;
[self.tableView convertRect:self.tableView.bounds toView:toView];

I am not sure this is the best solution. It may not work reliably if your root view controller doesn't support the same orientations as the current view controller.




回答3:


You should be able to get the current table view coordinates from self.tableView.bounds




回答4:


Your code should be:

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

That will give you the view's rectangle in the window's coordinate system. Be sure to use "bounds" and not "frame". frame is the rectangle of the view in its parent view coordinate system already. "bounds" is the view rectangle in its own system. So the above code asks the table view to convert its own rectangle from its own system to the window's system. Your previous code was asking the table's parent view to convert the table's rectangle from the parent coordinate system to nothing.




回答5:


Try bounds instead of frame self.parentViewController.view.bounds for it gives me adjusted coords according to the current orientation



来源:https://stackoverflow.com/questions/6034584/iphone-correct-landscape-window-coordinates

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!