可以手动旋转 UIPopoverController 的视图吗?

Posted

技术标签:

【中文标题】可以手动旋转 UIPopoverController 的视图吗?【英文标题】:Possible to manually rotate UIPopoverController's view? 【发布时间】:2012-03-13 18:08:24 【问题描述】:

我的应用中的视图系统是高度定制的,并使用了许多根据用户交互手动从纵向旋转到横向的视图(旋转是通过对视图/图层应用仿射变换来完成的)。

我想在这些旋转视图之一中显示一个弹出框,但弹出框的方向总是相对于设备的方向出现(即,不相对于视图)。我猜答案是否定的,但以防万一有人有一个聪明的主意:有没有办法手动旋转 UIPopoverController 呈现的视图?

【问题讨论】:

【参考方案1】:

肖恩,我刚刚测试了它的效果,是的,它有效。 它必须在 viewDidAppear 中完成(至少在我的情况下)(如果在 viewWillAppear 中完成,它会被退回到原始设置。)

这很好用(刚刚测试过)以 90 度角弹出一个弹出框。即在我的情况下,我的主视图处于纵向模式,并且弹出框旋转 90 度。

self.navigationController.view.superview.superview.transform = CGAffineTransformMakeRotation (M_PI/2.0);

【讨论】:

是的!看起来你可以做到这一点。我把这个想法更进一步。我将在下面单独发布答案。【参考方案2】:

您是要旋转弹出框还是仅旋转弹出框中显示的内容?您可以通过设置可能的箭头方向来控制前者。我对后者感兴趣,它似乎只需要抓住内容视图控制器就可以工作。 例如

aPopoverController.contentViewController.view.transform = CGAffineTransformMakeRotation(M_PI);

【讨论】:

【参考方案3】:

免责声明:如果您有兴趣尝试将您的应用程序放入商店,则几乎可以肯定此代码会被拒绝。它深入研究了 UIKit 的私有 API,这对苹果来说是一个很大的禁忌。

@RunningPink 的想法是正确的。根据视图层次结构的设置方式,弹出框的备份可能比两个超级视图更远。弹出框本身是(私有)类_UIPopover 的实例(至少在ios 5 中)。您可以通过以下方式找到此视图:

UIView *possiblePopover = popoverController.contentViewController.view;
while (possiblePopover != nil) 
    // Climb up the view hierarchy
    possiblePopover = possiblePopover.superview;
    if ( [NSStringFromClass([possiblePopover class]) isEqualToString:@"_UIPopoverView"] ) 
        // We found the popover, break out of the loop
        break;
    


if (nil != possiblePopover) 
    // Do whatever you want with the popover

在此过程中,我发现转换视图通常会导致弹出框看起来模糊。我发现原因是弹出框的超级视图是另一个名为UIDimmingView 的私​​有类的实例,它负责接受弹出框之外的触摸并导致弹出框关闭。在调暗视图上执行旋转消除了我在弹出窗口中看到的模糊。

但是,转换调光可能会导致奇怪的情况,即窗口的某些部分没有被调光视图“覆盖”,因此如果点击窗口的这些部分,弹出框不会消失。为了解决这个问题,我将旋转应用于调光视图,重置调光视图的框架以覆盖屏幕,然后将弹出视图平移到位。

if (nil != possiblePopover) 
    // Found the popover view
    CGAffineTransform rotation = CGAffineTransformMakeRotation(-M_PI_2);
    CGAffineTransform translation = // Whatever translation in necessary here

    // Rotate the UIDimming View and reset its frame
    [possiblePopover.superview setTransform:rotation];
    [possiblePopover.superview setFrame:CGRectMake(0, 0, possiblePopover.superview.frame.size.height, possiblePopover.superview.frame.size.width)];

    // Translate the popover view
    [possiblePopover setTransform:translation];

【讨论】:

以上是关于可以手动旋转 UIPopoverController 的视图吗?的主要内容,如果未能解决你的问题,请参考以下文章

在easeljs/tweenjs 中手动旋转

如何使用 glm::mat4 手动正确编写旋转矩阵?

使用 Core Graphics 以 30-60 fps 手动移动/旋转物体

屏幕旋转

Xcode 自动布局和旋转

安卓旋转动画