如何使用convertPoint:toView将视图坐标转换为旋转后的窗口坐标

3
我创建了一个新的Single View应用程序项目。在视图控制器中添加了代码,用于将视图坐标转换为窗口坐标:
- (void) dumpFrame
{
    CGRect bounds = self.view.bounds;

    // UIView* rootView = [UIApplication sharedApplication].keyWindow.rootViewController.view;
    // I tried rootView instead of nil and self.view.superview instead of self.view but got {0,0} coordinate

    CGPoint newCoord = [self.view convertPoint: bounds.origin
                                        toView: nil];

    bounds.origin.x = newCoord.x;
    bounds.origin.y = newCoord.y;
    NSLog(@"view.frame=%@", NSStringFromCGRect(bounds));
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    [super didRotateFromInterfaceOrientation: fromInterfaceOrientation];
    NSLog(@"===>didRotate");
    [self dumpFrame];
}

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [super willRotateToInterfaceOrientation: toInterfaceOrientation duration: duration];
    NSLog(@"===>willRotate");
    [self dumpFrame];
}

我的日志:

===>wilRotate
view.frame={{0, 20}, {768, 1004}}
===>didRotate
view.frame={{748, 0}, {1024, 748}}

代替

{{0, 20}, {1024, 748}}

我得到了

{{748, 0}, {1024, 748}}

旋转后,我需要做什么才能得到 {0,20}?非常感谢任何帮助。

2个回答

3
显然,UIWindow的坐标系始终保持在竖屏方向,旋转只是通过设置UIWindow的根视图控制器的transform属性来应用的。这个信息来自于这个SO问题
至少这能解释为什么你得到了意外的坐标。不过,不幸的是,我一直没有找到实际“解决”你的问题的方法。我认为应该有一种方法利用生效的变换矩阵,但我的数学技能不够。也许其他人可以在这里介入。
编辑
也许你可以使用这段代码(在“iOS Developer's Cookbook”的GitHub存储库中)。代码的部分内容在这篇文章中有解释并配有插图。

在这里为未来的人添加一条注释:从iOS 8开始,坐标系统与方向匹配,而不总是处于纵向状态,因此许多计算不必执行。 - Rizwan Sattar

-1

尝试:

CGPoint newCoord = [view.superview convertPoint: bounds.origin
                               toView: nil];

视图的原点是相对于其父视图的,因此您必须将该点从父视图坐标系转换。


尝试过了。newCoord 总是等于 {0, 0}。 - stosha
对于rootView(请参见我的问题),我也得到了{0,0}的newCoord。 - stosha
-1 是因为只有框架坐标是相对于父视图的。而边界坐标则是在视图自己的坐标系中。如果您编辑了您的答案,我将很高兴撤销负评。 - herzbube

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