The solution I found to this problem involved a few steps:
1) I found it necessary to change the center of the modal (an assignment to self.myNavController.view.superview.center) relative to the center of the screen. I computed the center of the screen based on [UIScreen mainScreen].bounds.size. For some example code, I used the method screenCenter below.
// Adapted from: http://stackoverflow.com/questions/24150359/is-uiscreen-mainscreen-bounds-size-becoming-orientation-dependent-in-ios8
+ (CGSize) screenSize;
{
CGSize screenSize = [UIScreen mainScreen].bounds.size;
CGSize rotatedSize;
if ([UIDevice ios7OrEarlier] && [[SMRotation session] isLandscape]) {
rotatedSize = CGSizeMake(screenSize.height, screenSize.width);
}
else {
rotatedSize = screenSize;
}
return rotatedSize;
}
+ (CGPoint) screenCenter;
{
CGSize size = [self screenSize];
CGPoint center = CGPointMake(size.width/2.0, size.height/2);
return center;
}
2) Now, given that you have computed the amount that you have to shift the modal upwards (e.g., given the keyboard height and your modal height and the position of the text field on the modal), call this amount dy. I next found it necessary if the app was in an inverted rotation (upside down portrait or landscape), to change the sign of dy before applying it to the CGPoint center position I was calculating. Something like this:
CGPoint newCenter = [SMRotation screenCenter];
if ([SMRotation session].isInverted) {
dy = -dy;
}
newCenter.y += dy;
With some of the code for isInverted here:
- (BOOL) isInverted;
{
switch (self.interfaceOrientation) {
case UIInterfaceOrientationPortraitUpsideDown:
case UIInterfaceOrientationLandscapeRight:
return YES;
case UIInterfaceOrientationPortrait:
case UIInterfaceOrientationLandscapeLeft:
case UIInterfaceOrientationUnknown:
return NO;
}
}
3) Then, if the app was in landscape I found it necessary to swap the x and y coordinates. Something like this:
if ([SMRotation session].isLandscape) {
newCenter = CGPointMake(newCenter.y, newCenter.x);
}
4 Finally, I did the assignment to update the center of the modal:
self.myNavController.view.superview.center = newCenter;