diff --git a/src/video/uikit/SDL_uikitappdelegate.m b/src/video/uikit/SDL_uikitappdelegate.m index 2ae61827f..19f510e0b 100644 --- a/src/video/uikit/SDL_uikitappdelegate.m +++ b/src/video/uikit/SDL_uikitappdelegate.m @@ -115,9 +115,7 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) return image; } -@implementation SDLLaunchScreenController { - UIInterfaceOrientationMask supportedOrientations; -} +@implementation SDLLaunchScreenController - (instancetype)init { @@ -127,18 +125,16 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) NSBundle *bundle = [NSBundle mainBundle]; NSString *screenname = [bundle objectForInfoDictionaryKey:@"UILaunchStoryboardName"]; - - /* Normally we don't want to rotate from the initial orientation. */ - supportedOrientations = (1 << [UIApplication sharedApplication].statusBarOrientation); + BOOL atleastiOS8 = UIKit_IsSystemVersionAtLeast(8.0); /* Launch screens were added in iOS 8. Otherwise we use launch images. */ - if (screenname && UIKit_IsSystemVersionAtLeast(8.0)) { + if (screenname && atleastiOS8) { @try { self.view = [bundle loadNibNamed:screenname owner:self options:nil][0]; } @catch (NSException *exception) { - /* iOS displays a blank screen rather than falling back to an image, - * if a launch screen name is specified but it fails to load. */ + /* If a launch screen name is specified but it fails to load, iOS + * displays a blank screen rather than falling back to an image. */ return nil; } } @@ -216,13 +212,37 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) } if (image) { - if (image.size.width > image.size.height) { - supportedOrientations = UIInterfaceOrientationMaskLandscape; - } else { - supportedOrientations = UIInterfaceOrientationMaskPortrait; + UIImageView *view = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds]; + UIImageOrientation imageorient = UIImageOrientationUp; + + /* Bugs observed / workaround tested in iOS 8.3, 7.1, and 6.1. */ + if (UIInterfaceOrientationIsLandscape(curorient)) { + if (atleastiOS8 && image.size.width < image.size.height) { + /* On iOS 8, portrait launch images displayed in forced- + * landscape mode (e.g. a standard Default.png on an iPhone + * when Info.plist only supports landscape orientations) need + * to be rotated to display in the expected orientation. */ + if (curorient == UIInterfaceOrientationLandscapeLeft) { + imageorient = UIImageOrientationRight; + } else if (curorient == UIInterfaceOrientationLandscapeRight) { + imageorient = UIImageOrientationLeft; + } + } else if (!atleastiOS8 && image.size.width > image.size.height) { + /* On iOS 7 and below, landscape launch images displayed in + * landscape mode (e.g. landscape iPad launch images) need + * to be rotated to display in the expected orientation. */ + if (curorient == UIInterfaceOrientationLandscapeLeft) { + imageorient = UIImageOrientationLeft; + } else if (curorient == UIInterfaceOrientationLandscapeRight) { + imageorient = UIImageOrientationRight; + } + } } - self.view = [[UIImageView alloc] initWithImage:image]; + /* Create the properly oriented image. */ + view.image = [[UIImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:imageorient]; + + self.view = view; } } @@ -234,9 +254,18 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) /* Do nothing. */ } +- (BOOL)shouldAutorotate +{ + /* If YES, the launch image will be incorrectly rotated in some cases. */ + return NO; +} + - (NSUInteger)supportedInterfaceOrientations { - return supportedOrientations; + /* We keep the supported orientations unrestricted to avoid the case where + * there are no common orientations between the ones set in Info.plist and + * the ones set here (it will cause an exception in that case.) */ + return UIInterfaceOrientationMaskAll; } @end diff --git a/src/video/uikit/SDL_uikitview.m b/src/video/uikit/SDL_uikitview.m index 8bd1f3198..84d98fe71 100644 --- a/src/video/uikit/SDL_uikitview.m +++ b/src/video/uikit/SDL_uikitview.m @@ -77,11 +77,8 @@ data.viewcontroller.view = view; - if (data.uiwindow.rootViewController != data.viewcontroller) { - data.uiwindow.rootViewController = data.viewcontroller; - } else if (view) { - [data.uiwindow addSubview:view]; - } + data.uiwindow.rootViewController = nil; + data.uiwindow.rootViewController = data.viewcontroller; [data.uiwindow layoutIfNeeded]; } @@ -96,13 +93,13 @@ [data.viewcontroller.view removeFromSuperview]; data.viewcontroller.view = self; - if (data.uiwindow.rootViewController != data.viewcontroller) { - /* The root view controller handles rotation and the status bar. - * Assigning it also adds the controller's view to the window. */ - data.uiwindow.rootViewController = data.viewcontroller; - } else { - [data.uiwindow addSubview:self]; - } + /* The root view controller handles rotation and the status bar. + * Assigning it also adds the controller's view to the window. We + * explicitly re-set it to make sure the view is properly attached to + * the window. Just adding the sub-view if the root view controller is + * already correct causes orientation issues on iOS 7 and below. */ + data.uiwindow.rootViewController = nil; + data.uiwindow.rootViewController = data.viewcontroller; /* The view's bounds may not be correct until the next event cycle. That * might happen after the current dimensions are queried, so we force a