UnityViewControllerBase+iOS.mm 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. #if PLATFORM_IOS
  2. #import "UnityViewControllerBase.h"
  3. #import "UnityAppController.h"
  4. #include "OrientationSupport.h"
  5. #include "Keyboard.h"
  6. #include "UnityView.h"
  7. #include "PluginBase/UnityViewControllerListener.h"
  8. #include "UnityAppController.h"
  9. #include "UnityAppController+ViewHandling.h"
  10. #include "Unity/ObjCRuntime.h"
  11. // when returning from presenting UIViewController we might need to update app orientation to "correct" one, as we wont get rotation notification
  12. @interface UnityAppController ()
  13. - (void)updateAppOrientation:(UIInterfaceOrientation)orientation;
  14. @end
  15. @implementation UnityViewControllerBase (iOS)
  16. ScreenOrientation _currentOrientation;
  17. - (void)viewDidAppear:(BOOL)animated
  18. {
  19. [super viewDidAppear: animated];
  20. _currentOrientation = UIViewControllerOrientation(self);
  21. AppController_SendUnityViewControllerNotification(kUnityViewDidAppear);
  22. }
  23. - (BOOL)shouldAutorotate
  24. {
  25. return YES;
  26. }
  27. - (BOOL)prefersStatusBarHidden
  28. {
  29. static bool _PrefersStatusBarHidden = true;
  30. static bool _PrefersStatusBarHiddenInited = false;
  31. if (!_PrefersStatusBarHiddenInited)
  32. {
  33. NSNumber* hidden = [[[NSBundle mainBundle] infoDictionary] objectForKey: @"UIStatusBarHidden"];
  34. _PrefersStatusBarHidden = hidden ? [hidden boolValue] : YES;
  35. _PrefersStatusBarHiddenInited = true;
  36. }
  37. return _PrefersStatusBarHidden;
  38. }
  39. - (UIStatusBarStyle)preferredStatusBarStyle
  40. {
  41. static UIStatusBarStyle _PreferredStatusBarStyle = UIStatusBarStyleDefault;
  42. static bool _PreferredStatusBarStyleInited = false;
  43. if (!_PreferredStatusBarStyleInited)
  44. {
  45. NSString* style = [[[NSBundle mainBundle] infoDictionary] objectForKey: @"UIStatusBarStyle"];
  46. if (style && [style isEqualToString: @"UIStatusBarStyleLightContent"])
  47. _PreferredStatusBarStyle = UIStatusBarStyleLightContent;
  48. _PreferredStatusBarStyleInited = true;
  49. }
  50. return _PreferredStatusBarStyle;
  51. }
  52. - (UIRectEdge)preferredScreenEdgesDeferringSystemGestures
  53. {
  54. UIRectEdge res = UIRectEdgeNone;
  55. if (UnityGetDeferSystemGesturesTopEdge())
  56. res |= UIRectEdgeTop;
  57. if (UnityGetDeferSystemGesturesBottomEdge())
  58. res |= UIRectEdgeBottom;
  59. if (UnityGetDeferSystemGesturesLeftEdge())
  60. res |= UIRectEdgeLeft;
  61. if (UnityGetDeferSystemGesturesRightEdge())
  62. res |= UIRectEdgeRight;
  63. return res;
  64. }
  65. - (BOOL)prefersHomeIndicatorAutoHidden
  66. {
  67. return UnityGetHideHomeButton();
  68. }
  69. - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
  70. {
  71. // Dropped UIViewControllerOrientation(self) usage to calculate current orientation because
  72. // in some cases this method is called after screen has already turned so
  73. // UIViewControllerOrientation(self) might give inconsistant results
  74. ScreenOrientation curOrient = _currentOrientation;
  75. ScreenOrientation newOrient = OrientationAfterTransform(curOrient, [coordinator targetTransform]);
  76. _currentOrientation = newOrient;
  77. // in case of presentation controller it will take control over orientations
  78. // so to avoid crazy corner cases, make default view controller to ignore "wrong" orientations
  79. // as they will come only in case of presentation view controller and will be reverted anyway
  80. // NB: we still want to pass message to super, we just want to skip unity-specific magic
  81. NSUInteger targetMask = 1 << ConvertToIosScreenOrientation(newOrient);
  82. if (([self supportedInterfaceOrientations] & targetMask) != 0)
  83. {
  84. [UIView setAnimationsEnabled: UnityUseAnimatedAutorotation() ? YES : NO];
  85. [KeyboardDelegate StartReorientation];
  86. [GetAppController() interfaceWillChangeOrientationTo: ConvertToIosScreenOrientation(newOrient)];
  87. [coordinator animateAlongsideTransition: nil completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
  88. [self.view setNeedsLayout];
  89. [GetAppController() interfaceDidChangeOrientationFrom: ConvertToIosScreenOrientation(curOrient)];
  90. [KeyboardDelegate FinishReorientation];
  91. [UIView setAnimationsEnabled: YES];
  92. }];
  93. }
  94. [super viewWillTransitionToSize: size withTransitionCoordinator: coordinator];
  95. }
  96. @end
  97. @implementation UnityDefaultViewController
  98. - (NSUInteger)supportedInterfaceOrientations
  99. {
  100. NSAssert(UnityShouldAutorotate(), @"UnityDefaultViewController should be used only if unity is set to autorotate");
  101. return EnabledAutorotationInterfaceOrientations();
  102. }
  103. @end
  104. @implementation UnityPortraitOnlyViewController
  105. - (NSUInteger)supportedInterfaceOrientations
  106. {
  107. return 1 << UIInterfaceOrientationPortrait;
  108. }
  109. - (void)viewWillAppear:(BOOL)animated
  110. {
  111. [GetAppController() updateAppOrientation: UIInterfaceOrientationPortrait];
  112. [super viewWillAppear: animated];
  113. }
  114. @end
  115. @implementation UnityPortraitUpsideDownOnlyViewController
  116. - (NSUInteger)supportedInterfaceOrientations
  117. {
  118. return 1 << UIInterfaceOrientationPortraitUpsideDown;
  119. }
  120. - (void)viewWillAppear:(BOOL)animated
  121. {
  122. [GetAppController() updateAppOrientation: UIInterfaceOrientationPortraitUpsideDown];
  123. [super viewWillAppear: animated];
  124. }
  125. @end
  126. @implementation UnityLandscapeLeftOnlyViewController
  127. - (NSUInteger)supportedInterfaceOrientations
  128. {
  129. return 1 << UIInterfaceOrientationLandscapeLeft;
  130. }
  131. - (void)viewWillAppear:(BOOL)animated
  132. {
  133. [GetAppController() updateAppOrientation: UIInterfaceOrientationLandscapeLeft];
  134. [super viewWillAppear: animated];
  135. }
  136. @end
  137. @implementation UnityLandscapeRightOnlyViewController
  138. - (NSUInteger)supportedInterfaceOrientations
  139. {
  140. return 1 << UIInterfaceOrientationLandscapeRight;
  141. }
  142. - (void)viewWillAppear:(BOOL)animated
  143. {
  144. [GetAppController() updateAppOrientation: UIInterfaceOrientationLandscapeRight];
  145. [super viewWillAppear: animated];
  146. }
  147. @end
  148. NSUInteger EnabledAutorotationInterfaceOrientations()
  149. {
  150. NSUInteger ret = 0;
  151. if (UnityIsOrientationEnabled(portrait))
  152. ret |= (1 << UIInterfaceOrientationPortrait);
  153. if (UnityIsOrientationEnabled(portraitUpsideDown))
  154. ret |= (1 << UIInterfaceOrientationPortraitUpsideDown);
  155. if (UnityIsOrientationEnabled(landscapeLeft))
  156. ret |= (1 << UIInterfaceOrientationLandscapeRight);
  157. if (UnityIsOrientationEnabled(landscapeRight))
  158. ret |= (1 << UIInterfaceOrientationLandscapeLeft);
  159. return ret;
  160. }
  161. #endif // PLATFORM_IOS