是否可以旋转/仿射变换 UIMenuController

Posted

技术标签:

【中文标题】是否可以旋转/仿射变换 UIMenuController【英文标题】:Is it possible to Rotate/Affine Transform UIMenuController 【发布时间】:2015-09-09 16:18:35 【问题描述】:

没有深入了解这一切的“原因”,我有 UITextField,它是视图层次结构的一部分,它通过仿射变换在屏幕上强制“倒置”。

CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(180))

这适用于所有子视图——包括 UITextField——直到用户想要在文本字段内容上使用 UIMenuController 的复制/粘贴功能。当 UIMenuController 显示时,它是“正面朝上”而不是像 UITextField 那样“倒置”。

是否有把握 UIMenuController 的视图在显示时应用相同的转换?

目前,我正在监听 UIMenuControllerWillShowMenuNotification 通知,然后获取 UIMenuController。但我似乎找不到将转换应用于它的方法。有任何想法吗?

- (void)textFieldDidBeginEditing:(UITextField *)textField 
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(menuControllerWillShow:) name:UIMenuControllerWillShowMenuNotification object:nil];

- (void)menuControllerWillShow:(NSNotification*)aNotification 

    UIMenuController* menuController = [UIMenuController sharedMenuController];
    CGAffineTransform xform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(180));

    CGRect oldRect = menuController.menuFrame;
    CGRect newRect = CGRectApplyAffineTransform(oldRect, xform);   

    // eh... now what? 

【问题讨论】:

应用中有多少是颠倒的?整个事情还是只是UITextField 几乎是整个事情。该设备始终保持纵向,但由于围绕麦克风位置的各种应用程序要求,我的顶部根视图控制器旋转了(基于用户偏好)180 度。我找到了转换 UIAlertViews、键盘等的方法(当根视图控制器和所有子视图倒置时)。但无法破解 UIMenuController。 【参考方案1】:

我不认为你可以修改 UIMenuController 所以它是颠倒的。

但是,如果您的整个应用程序几乎都被更改了,您可以检查设备方向或应用程序方向(通过检查状态栏的位置)并强制它相反。

要获得device orientation,您可以执行以下操作:

UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]

来自文档的注释:

除非已通过调用 beginGeneratingDeviceOrientationNotifications 启用方向通知,否则此属性的值始终返回 0。

或通过以下方式获取应用方向:

UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;

if(orientation == 0) //Default orientation 

    //UI is in Default (Portrait) -- this is really a just a failsafe. 

else if(orientation == UIInterfaceOrientationPortrait)
 
    //Do something if the orientation is in Portrait

else if(orientation == UIInterfaceOrientationLandscapeLeft)
     
   // Do something if Left

else if(orientation == UIInterfaceOrientationLandscapeRight)
    
    //Do something if right

然后用这样的东西设置它:

目标-C:

NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];

斯威夫特:

let value = UIInterfaceOrientation.LandscapeLeft.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")

【讨论】:

是的,看起来这应该适合我。但是,我确实必须实现 shouldAutorotate 和supportedInterfaceOrientations。一件奇怪的事:当我设置方向时,shouldAutorotate 并不总是被调用。这意味着它不起作用。但是当我稍微摇晃一下我的设备时……然后 autoRotate 开始被调用。有什么想法吗? 很可能是因为 NavigationController 没有将消息传递给可见的 viewController。您是否在 AppDelegate 中将 Nav 指定为 root 用户? 再想一想,@quaid,请参阅this answer 它可能会解决这个问题。 感谢@CaptJak 的其他想法。然而,在这种情况下,我没有使用UINavigationController,只是一个普通的UIViewController。出于某种原因,我执行[[UIDevice currentDevice] setValue:value forKey:@"orientation"]; 的 UIButton 有时根本不做任何事情,直到我移动我的设备(这显然会强制调用shouldAutorotate。然后一切都很好。玩了之后我发现还有一个额外的调用@ 987654332@ 每次都能正常工作。无论如何,我将此答案标记为正确答案。 好的@quaid,谢谢。很高兴你让它工作,很高兴我能帮上忙。

以上是关于是否可以旋转/仿射变换 UIMenuController的主要内容,如果未能解决你的问题,请参考以下文章

仿射变换与透视变换

opencv 图像平移缩放旋转翻转 图像仿射变换

几何变换——放大镜像平移旋转透视仿射

OpenCV 完整例程24. 图像的仿射变换

对图像的仿射变换

图像的仿射变换:cv2.warpAffine()