diff --git a/osu.Android.props b/osu.Android.props
index 7ae16b8b70..d2682fc024 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -10,7 +10,7 @@
true
-
+
diff --git a/osu.iOS.props b/osu.iOS.props
index 7b0a027d39..309a9dcc87 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -17,6 +17,6 @@
-all
-
+
diff --git a/osu.iOS/AppDelegate.cs b/osu.iOS/AppDelegate.cs
index e88b39f710..5d309f2fc1 100644
--- a/osu.iOS/AppDelegate.cs
+++ b/osu.iOS/AppDelegate.cs
@@ -1,14 +1,61 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using System;
using Foundation;
using osu.Framework.iOS;
+using UIKit;
namespace osu.iOS
{
[Register("AppDelegate")]
public class AppDelegate : GameApplicationDelegate
{
- protected override Framework.Game CreateGame() => new OsuGameIOS();
+ private UIInterfaceOrientationMask? defaultOrientationsMask;
+ private UIInterfaceOrientationMask? orientations;
+
+ ///
+ /// The current orientation the game is displayed in.
+ ///
+ public UIInterfaceOrientation CurrentOrientation => Host.Window.UIWindow.WindowScene!.InterfaceOrientation;
+
+ ///
+ /// Controls the orientations allowed for the device to rotate to, overriding the default allowed orientations.
+ ///
+ public UIInterfaceOrientationMask? Orientations
+ {
+ get => orientations;
+ set
+ {
+ if (orientations == value)
+ return;
+
+ orientations = value;
+
+ if (OperatingSystem.IsIOSVersionAtLeast(16))
+ Host.Window.ViewController.SetNeedsUpdateOfSupportedInterfaceOrientations();
+ else
+ UIViewController.AttemptRotationToDeviceOrientation();
+ }
+ }
+
+ protected override Framework.Game CreateGame() => new OsuGameIOS(this);
+
+ public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations(UIApplication application, UIWindow forWindow)
+ {
+ if (orientations != null)
+ return orientations.Value;
+
+ if (defaultOrientationsMask == null)
+ {
+ defaultOrientationsMask = 0;
+ var defaultOrientations = (NSArray)NSBundle.MainBundle.ObjectForInfoDictionary("UISupportedInterfaceOrientations");
+
+ foreach (var value in defaultOrientations.ToArray())
+ defaultOrientationsMask |= Enum.Parse(value.ToString().Replace("UIInterfaceOrientation", string.Empty));
+ }
+
+ return defaultOrientationsMask.Value;
+ }
}
}
diff --git a/osu.iOS/Info.plist b/osu.iOS/Info.plist
index 70747fc9c8..120e8caecc 100644
--- a/osu.iOS/Info.plist
+++ b/osu.iOS/Info.plist
@@ -153,6 +153,8 @@
Editor
+ ITSAppUsesNonExemptEncryption
+
LSApplicationCategoryType
public.app-category.music-games
LSSupportsOpeningDocumentsInPlace
diff --git a/osu.iOS/OsuGameIOS.cs b/osu.iOS/OsuGameIOS.cs
index a9ca1778a0..a5a42c1e66 100644
--- a/osu.iOS/OsuGameIOS.cs
+++ b/osu.iOS/OsuGameIOS.cs
@@ -8,17 +8,60 @@ using osu.Framework.Graphics;
using osu.Framework.iOS;
using osu.Framework.Platform;
using osu.Game;
+using osu.Game.Screens;
using osu.Game.Updater;
using osu.Game.Utils;
+using UIKit;
namespace osu.iOS
{
public partial class OsuGameIOS : OsuGame
{
+ private readonly AppDelegate appDelegate;
public override Version AssemblyVersion => new Version(NSBundle.MainBundle.InfoDictionary["CFBundleVersion"].ToString());
public override bool HideUnlicensedContent => true;
+ public OsuGameIOS(AppDelegate appDelegate)
+ {
+ this.appDelegate = appDelegate;
+ }
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+ UserPlayingState.BindValueChanged(_ => updateOrientation());
+ }
+
+ protected override void ScreenChanged(IOsuScreen? current, IOsuScreen? newScreen)
+ {
+ base.ScreenChanged(current, newScreen);
+
+ if (newScreen != null)
+ updateOrientation();
+ }
+
+ private void updateOrientation()
+ {
+ bool iPad = UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad;
+ var orientation = MobileUtils.GetOrientation(this, (IOsuScreen)ScreenStack.CurrentScreen, iPad);
+
+ switch (orientation)
+ {
+ case MobileUtils.Orientation.Locked:
+ appDelegate.Orientations = (UIInterfaceOrientationMask)(1 << (int)appDelegate.CurrentOrientation);
+ break;
+
+ case MobileUtils.Orientation.Portrait:
+ appDelegate.Orientations = UIInterfaceOrientationMask.Portrait;
+ break;
+
+ case MobileUtils.Orientation.Default:
+ appDelegate.Orientations = null;
+ break;
+ }
+ }
+
protected override UpdateManager CreateUpdateManager() => new MobileUpdateNotifier();
protected override BatteryInfo CreateBatteryInfo() => new IOSBatteryInfo();