Browse Source

Implement scene delegate for iOS (#20454)

* Implement scene delegate for iOS

* Move OS check to its own method to make analyzer happy
pull/20504/head
Julien Lebosquain 2 weeks ago
committed by GitHub
parent
commit
ac37bd6353
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 44
      src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs
  2. 36
      src/iOS/Avalonia.iOS/AvaloniaSceneDelegate.cs
  3. 15
      src/iOS/Avalonia.iOS/SingleViewLifetime.cs

44
src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs

@ -1,4 +1,5 @@
using System;
using System.Runtime.Versioning;
using Foundation;
using Avalonia.Controls.ApplicationLifetimes;
using UIKit;
@ -27,6 +28,7 @@ namespace Avalonia.iOS
add { _onActivated += value; }
remove { _onActivated -= value; }
}
event EventHandler<ActivatedEventArgs> IAvaloniaAppDelegate.Deactivated
{
add { _onDeactivated += value; }
@ -39,6 +41,17 @@ namespace Avalonia.iOS
[Export("window")]
public UIWindow? Window { get; set; }
[Export("application:configurationForConnectingSceneSession:options:")]
[SupportedOSPlatform("ios13.0")]
[SupportedOSPlatform("tvos13.0")]
[SupportedOSPlatform("maccatalyst")]
public UISceneConfiguration GetConfiguration(UIApplication application, UISceneSession connectingSceneSession, UISceneConnectionOptions options)
{
var config = new UISceneConfiguration(null, connectingSceneSession.Role);
config.DelegateType = typeof(AvaloniaSceneDelegate);
return config;
}
[Export("application:didFinishLaunchingWithOptions:")]
public bool FinishedLaunching(UIApplication application, NSDictionary? launchOptions)
{
@ -46,28 +59,27 @@ namespace Avalonia.iOS
builder = CustomizeAppBuilder(builder);
var lifetime = new SingleViewLifetime();
builder.AfterApplicationSetup(_ =>
{
Window = new UIWindow();
var view = new AvaloniaView();
lifetime.View = view;
var controller = new DefaultAvaloniaViewController
{
View = view
};
Window.RootViewController = controller;
view.InitWithController(controller);
});
builder.AfterApplicationSetup(_ => CreateAndInitWindow(lifetime));
builder.SetupWithLifetime(lifetime);
Window!.MakeKeyAndVisible();
Window?.MakeKeyAndVisible();
return true;
}
private void CreateAndInitWindow(SingleViewLifetime lifetime)
{
if (OperatingSystem.IsIOSVersionAtLeast(13) ||
OperatingSystem.IsTvOSVersionAtLeast(13) ||
OperatingSystem.IsMacCatalyst())
{
return;
}
Window = new UIWindow();
AvaloniaSceneDelegate.InitWindow(Window, lifetime);
}
[Export("application:openURL:options:")]
public bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
{

36
src/iOS/Avalonia.iOS/AvaloniaSceneDelegate.cs

@ -0,0 +1,36 @@
using Foundation;
using UIKit;
namespace Avalonia.iOS;
internal sealed class AvaloniaSceneDelegate : UIResponder, IUIWindowSceneDelegate
{
[Export("window")]
public UIWindow? Window { get; set; }
[Export("scene:willConnectToSession:options:")]
public void WillConnect(UIScene scene, UISceneSession session, UISceneConnectionOptions connectionOptions)
{
if (session.Configuration.Name is not null ||
scene is not UIWindowScene windowScene ||
Application.Current?.ApplicationLifetime is not SingleViewLifetime lifetime)
{
return;
}
Window = new UIWindow(windowScene);
InitWindow(Window, lifetime);
Window.MakeKeyAndVisible();
}
internal static void InitWindow(UIWindow window, SingleViewLifetime lifetime)
{
var view = new AvaloniaView();
lifetime.View = view;
var controller = new DefaultAvaloniaViewController { View = view };
window.RootViewController = controller;
view.InitWithController(controller);
}
}

15
src/iOS/Avalonia.iOS/SingleViewLifetime.cs

@ -1,6 +1,4 @@
using System;
using System.Diagnostics.CodeAnalysis;
using Avalonia.Controls;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
namespace Avalonia.iOS;
@ -10,9 +8,9 @@ internal class SingleViewLifetime : ISingleViewApplicationLifetime, ISingleTopLe
private Control? _mainView;
private AvaloniaView? _view;
public AvaloniaView View
public AvaloniaView? View
{
[return: MaybeNull] get => _view!;
get => _view;
internal set
{
if (_view != null)
@ -21,7 +19,7 @@ internal class SingleViewLifetime : ISingleViewApplicationLifetime, ISingleTopLe
_view.Dispose();
}
_view = value;
_view.Content = _mainView;
_view?.Content = _mainView;
}
}
@ -33,10 +31,7 @@ internal class SingleViewLifetime : ISingleViewApplicationLifetime, ISingleTopLe
if (_mainView != value)
{
_mainView = value;
if (_view != null)
{
_view.Content = _mainView;
}
_view?.Content = _mainView;
}
}
}

Loading…
Cancel
Save