0

Without going into the 'why' of it all, I have UITextField that is part of a view hierarchy that is forcibly 'upside down' on screen via an affine transform.

CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(180))

This works fine for all of the subviews -- including the UITextField -- until the user wants to use the copy/paste features of UIMenuController on the text field content. When the UIMenuController is shown, it is 'right side up' rather than 'upside down' like the UITextField.

Is there anyway to get a hold of the UIMenuController's view to apply the same transform when it is shown?

Currently, I am listening for the UIMenuControllerWillShowMenuNotification notification and then getting the UIMenuController. But I can't seem to find a way to apply the transform to it. Any ideas?

- (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? 
}
quaid
  • 38
  • 1
  • 3
  • How much of the app is upside down? The entire thing or just the `UITextField`? – CaptJak Sep 09 '15 at 18:12
  • Pretty much the whole thing. The device remains in portrait orientation the entire time, but my top root view controller is rotated (based on user prefs) 180 degrees due to various app requirements around mic location. I've found ways (when the root view controller & all subviews are upside down) to transform UIAlertViews, the keyboard, etc. But can't crack the UIMenuController. – quaid Sep 09 '15 at 18:45

1 Answers1

0

I don't think you can modify the UIMenuController so it's upside down.

But if it's pretty much your entire app that's altered, you could either check the device orientation or the app orientation (by checking where the status bar is) and force it to be the opposite.

To get the device orientation you could do something like this:

UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]

Note from the docs:

The value of this property always returns 0 unless orientation notifications have been enabled by calling beginGeneratingDeviceOrientationNotifications.

Or get the app orientation with this:

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
}

and then set it with something like this:

Objective-C:

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

Swift:

let value = UIInterfaceOrientation.LandscapeLeft.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")
CaptJak
  • 3,592
  • 1
  • 29
  • 50
  • Yes, it looks like this should work for me. However, I did have to implement shouldAutorotate and supportedInterfaceOrientations. One curious thing though: shouldAutorotate is not always called when I set the orientation. Which means it doesn't work. But when I jiggle my device a bit... well then autoRotate starts getting called. Any ideas of what is going on? – quaid Sep 13 '15 at 22:25
  • Most likely because the NavigationController isn't passing the message to the visible viewController. Have you specified the Nav as being root in AppDelegate? – CaptJak Sep 13 '15 at 23:13
  • On second thought, @quaid, see [this answer](http://stackoverflow.com/a/28220616/2535467) it might solve that issue. – CaptJak Sep 13 '15 at 23:16
  • Thanks for the additional ideas @CaptJak. In this case, however, I am not using a `UINavigationController`, just a regular a normal `UIViewController`. For some reason, my UIButton which executes `[[UIDevice currentDevice] setValue:value forKey:@"orientation"];` simply doesn't do anything sometimes until I move my device around (which apparently forces calls to `shouldAutorotate`. Then all is well. After playing around I found that an additional call too `[UIViewController attemptRotationToDeviceOrientation];` makes it work every time. Anyway, I'm marking this answer as the correct one. – quaid Sep 15 '15 at 19:10
  • All right @quaid, thanks. Glad you got it to work, and glad I could help. – CaptJak Sep 15 '15 at 19:19