diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/NativeEmbeddingDemo.Droid.csproj b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/NativeEmbeddingDemo.Droid.csproj index d39fc34e9..157ef5cd0 100644 --- a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/NativeEmbeddingDemo.Droid.csproj +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/NativeEmbeddingDemo.Droid.csproj @@ -24,6 +24,4 @@ - - \ No newline at end of file diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/AppDelegate.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/AppDelegate.cs index 68279bda7..0ca07a70c 100644 --- a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/AppDelegate.cs +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/AppDelegate.cs @@ -1,15 +1,14 @@ -namespace NativeEmbeddingDemo.MacCatalyst +namespace NativeEmbeddingDemo.MacCatalyst; + +[Register("AppDelegate")] +public class AppDelegate : UIApplicationDelegate { - [Register("AppDelegate")] - public class AppDelegate : UIApplicationDelegate - { - public override UIWindow? Window { get; set; } + public override UIWindow? Window { get; set; } - public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions) => true; + public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions) => true; - public override UISceneConfiguration GetConfiguration(UIApplication application, UISceneSession connectingSceneSession, UISceneConnectionOptions options) => - Enumerable.FirstOrDefault(options.UserActivities)?.ActivityType == "NewTaskWindow" + public override UISceneConfiguration GetConfiguration(UIApplication application, UISceneSession connectingSceneSession, UISceneConnectionOptions options) => + Enumerable.FirstOrDefault(options.UserActivities)?.ActivityType == "NewTaskWindow" ? new UISceneConfiguration("New Task Configuration", UIWindowSceneSessionRole.Application) : new UISceneConfiguration("Default Configuration", UIWindowSceneSessionRole.Application); - } } diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/MainViewController.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/MainViewController.cs index 21b5fb3d3..ea10c2f41 100644 --- a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/MainViewController.cs +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/MainViewController.cs @@ -1,132 +1,131 @@ using Microsoft.Maui.Platform; -namespace NativeEmbeddingDemo.MacCatalyst +namespace NativeEmbeddingDemo.MacCatalyst; + +public class MainViewController : UIViewController { - public class MainViewController : UIViewController - { - UIWindow GetWindow() => - View?.Window ?? - ParentViewController?.View?.Window ?? - MainViewController.MauiApp.Value.Services.GetRequiredService().GetWindow() ?? - UIApplication.SharedApplication.Delegate.GetWindow(); + UIWindow GetWindow() => + View?.Window ?? + ParentViewController?.View?.Window ?? + MainViewController.MauiApp.Value.Services.GetRequiredService().GetWindow() ?? + UIApplication.SharedApplication.Delegate.GetWindow(); - public static readonly Lazy MauiApp = new(() => + public static readonly Lazy MauiApp = new(() => + { + var mauiApp = MauiProgram.CreateMauiApp(builder => { - var mauiApp = MauiProgram.CreateMauiApp(builder => - { - builder.UseMauiEmbedding(); - }); - return mauiApp; + builder.UseMauiEmbedding(); }); + return mauiApp; + }); - public static bool UseWindowContext = true; + public static bool UseWindowContext = true; - MyMauiContent? mauiView; + MyMauiContent? mauiView; - public override void ViewDidLoad() - { - base.ViewDidLoad(); + public override void ViewDidLoad() + { + base.ViewDidLoad(); - Title = "Main view controller"; + Title = "Main view controller"; - View!.BackgroundColor = UIColor.SystemBackground; + View!.BackgroundColor = UIColor.SystemBackground; - var stackView = new UIStackView - { - Axis = UILayoutConstraintAxis.Vertical, - Alignment = UIStackViewAlignment.Fill, - Distribution = UIStackViewDistribution.Fill, - Spacing = 8, - TranslatesAutoresizingMaskIntoConstraints = false - }; - View.AddSubview(stackView); - - NSLayoutConstraint.ActivateConstraints(new[] - { - stackView.TopAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TopAnchor, 20), - stackView.LeadingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.LeadingAnchor, 20), - stackView.TrailingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TrailingAnchor, -20), - stackView.BottomAnchor.ConstraintLessThanOrEqualTo(View.SafeAreaLayoutGuide.BottomAnchor, -20) - }); + var stackView = new UIStackView + { + Axis = UILayoutConstraintAxis.Vertical, + Alignment = UIStackViewAlignment.Fill, + Distribution = UIStackViewDistribution.Fill, + Spacing = 8, + TranslatesAutoresizingMaskIntoConstraints = false + }; + View.AddSubview(stackView); + + NSLayoutConstraint.ActivateConstraints(new[] + { + stackView.TopAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TopAnchor, 20), + stackView.LeadingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.LeadingAnchor, 20), + stackView.TrailingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TrailingAnchor, -20), + stackView.BottomAnchor.ConstraintLessThanOrEqualTo(View.SafeAreaLayoutGuide.BottomAnchor, -20) + }); - // Create UIKit button - var uiButton = new UIButton(UIButtonType.System); - uiButton.SetTitle("UIKit button above .NET MAUI controls", UIControlState.Normal); - uiButton.TouchUpInside += OnUIButtonClicked; - stackView.AddArrangedSubview(uiButton); + // Create UIKit button + var uiButton = new UIButton(UIButtonType.System); + uiButton.SetTitle("UIKit button above .NET MAUI controls", UIControlState.Normal); + uiButton.TouchUpInside += OnUIButtonClicked; + stackView.AddArrangedSubview(uiButton); - // Ensure .NET MAUI app is built before creating .NET MAUI views - var mauiApp = MainViewController.MauiApp.Value; + // Ensure .NET MAUI app is built before creating .NET MAUI views + var mauiApp = MainViewController.MauiApp.Value; - // Create .NET MAUI context - var mauiContext = UseWindowContext - ? mauiApp.CreateEmbeddedWindowContext(GetWindow()) // Create window context - : new MauiContext(mauiApp.Services); // Create app context + // Create .NET MAUI context + var mauiContext = UseWindowContext + ? mauiApp.CreateEmbeddedWindowContext(GetWindow()) // Create window context + : new MauiContext(mauiApp.Services); // Create app context - // Create .NET MAUI content - mauiView = new MyMauiContent(); + // Create .NET MAUI content + mauiView = new MyMauiContent(); - // Create native view - var nativeView = mauiView.ToPlatformEmbedded(mauiContext); - nativeView.WidthAnchor.ConstraintEqualTo(View.Frame.Width).Active = true; - nativeView.HeightAnchor.ConstraintEqualTo(500).Active = true; + // Create native view + var nativeView = mauiView.ToPlatformEmbedded(mauiContext); + nativeView.WidthAnchor.ConstraintEqualTo(View.Frame.Width).Active = true; + nativeView.HeightAnchor.ConstraintEqualTo(500).Active = true; - // Add native view to layout - stackView.AddArrangedSubview(nativeView); + // Add native view to layout + stackView.AddArrangedSubview(nativeView); - AddNavBarButtons(); - } + AddNavBarButtons(); + } - void AddNavBarButtons() - { - var addNewWindowButton = new UIBarButtonItem( - UIImage.GetSystemImage("macwindow.badge.plus"), - UIBarButtonItemStyle.Plain, - (sender, e) => RequestSession()); + void AddNavBarButtons() + { + var addNewWindowButton = new UIBarButtonItem( + UIImage.GetSystemImage("macwindow.badge.plus"), + UIBarButtonItemStyle.Plain, + (sender, e) => RequestSession()); - var addNewTaskButton = new UIBarButtonItem( - UIBarButtonSystemItem.Add, - (sender, e) => RequestSession("NewTaskWindow")); + var addNewTaskButton = new UIBarButtonItem( + UIBarButtonSystemItem.Add, + (sender, e) => RequestSession("NewTaskWindow")); - NavigationItem.RightBarButtonItems = [addNewTaskButton, addNewWindowButton]; - } + NavigationItem.RightBarButtonItems = [addNewTaskButton, addNewWindowButton]; + } - void RequestSession(string? activityType = null) + void RequestSession(string? activityType = null) + { + var activity = activityType is null + ? null + : new NSUserActivity(activityType); + + if (OperatingSystem.IsMacCatalystVersionAtLeast(17)) { - var activity = activityType is null - ? null - : new NSUserActivity(activityType); + var request = UISceneSessionActivationRequest.Create(); + request.UserActivity = activity; - if (OperatingSystem.IsMacCatalystVersionAtLeast(17)) + UIApplication.SharedApplication.ActivateSceneSession(request, error => { - var request = UISceneSessionActivationRequest.Create(); - request.UserActivity = activity; - - UIApplication.SharedApplication.ActivateSceneSession(request, error => - { - Console.WriteLine(new NSErrorException(error)); - }); - } - else + Console.WriteLine(new NSErrorException(error)); + }); + } + else + { + UIApplication.SharedApplication.RequestSceneSessionActivation(null, activity, null, error => { - UIApplication.SharedApplication.RequestSceneSessionActivation(null, activity, null, error => - { - Console.WriteLine(new NSErrorException(error)); - }); - } + Console.WriteLine(new NSErrorException(error)); + }); } + } - async void OnUIButtonClicked(object? sender, EventArgs e) - { - if (mauiView?.DotNetBot is not Image bot) - return; + async void OnUIButtonClicked(object? sender, EventArgs e) + { + if (mauiView?.DotNetBot is not Image bot) + return; - await bot.RotateTo(360, 1000); - bot.Rotation = 0; + await bot.RotateTo(360, 1000); + bot.Rotation = 0; - bot.HeightRequest = 90; - } + bot.HeightRequest = 90; } } diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/NewTaskSceneDelegate.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/NewTaskSceneDelegate.cs index 8f4c6a871..3c6ff6bf3 100644 --- a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/NewTaskSceneDelegate.cs +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/NewTaskSceneDelegate.cs @@ -1,55 +1,54 @@ using AppKit; -namespace NativeEmbeddingDemo.MacCatalyst +namespace NativeEmbeddingDemo.MacCatalyst; + +[Register(nameof(NewTaskSceneDelegate))] +public class NewTaskSceneDelegate : UIWindowSceneDelegate { - [Register(nameof(NewTaskSceneDelegate))] - public class NewTaskSceneDelegate : UIWindowSceneDelegate - { - public override UIWindow? Window { get; set; } + public override UIWindow? Window { get; set; } - [Export("scene:willConnectToSession:options:")] - public override void WillConnect(UIScene scene, UISceneSession session, UISceneConnectionOptions connectionOptions) - { - if (scene is not UIWindowScene windowScene) - return; + [Export("scene:willConnectToSession:options:")] + public override void WillConnect(UIScene scene, UISceneSession session, UISceneConnectionOptions connectionOptions) + { + if (scene is not UIWindowScene windowScene) + return; - var window = new UIWindow(windowScene); - window.RootViewController = new NewTaskViewController(); - window.WindowScene!.Title = "New Task"; - window.MakeKeyAndVisible(); + var window = new UIWindow(windowScene); + window.RootViewController = new NewTaskViewController(); + window.WindowScene!.Title = "New Task"; + window.MakeKeyAndVisible(); - Window = window; + Window = window; - if (OperatingSystem.IsMacCatalyst()) - { - ConfigureMacWindowSize(); - ConfigureToolbar(); - } + if (OperatingSystem.IsMacCatalyst()) + { + ConfigureMacWindowSize(); + ConfigureToolbar(); } + } - void ConfigureMacWindowSize() - { - if (Window?.WindowScene?.SizeRestrictions is null) - return; + void ConfigureMacWindowSize() + { + if (Window?.WindowScene?.SizeRestrictions is null) + return; - var fixedSize = new CGSize(400, 250); - Window.WindowScene.SizeRestrictions.MinimumSize = fixedSize; - Window.WindowScene.SizeRestrictions.MaximumSize = fixedSize; - } + var fixedSize = new CGSize(400, 250); + Window.WindowScene.SizeRestrictions.MinimumSize = fixedSize; + Window.WindowScene.SizeRestrictions.MaximumSize = fixedSize; + } - void ConfigureToolbar() - { - if (Window?.WindowScene?.Titlebar is null) - return; + void ConfigureToolbar() + { + if (Window?.WindowScene?.Titlebar is null) + return; - var toolbar = new NSToolbar(); - toolbar.ShowsBaselineSeparator = false; + var toolbar = new NSToolbar(); + toolbar.ShowsBaselineSeparator = false; - var titlebar = Window.WindowScene.Titlebar; - titlebar.Toolbar = toolbar; - titlebar.ToolbarStyle = UITitlebarToolbarStyle.Automatic; - titlebar.TitleVisibility = UITitlebarTitleVisibility.Visible; - } + var titlebar = Window.WindowScene.Titlebar; + titlebar.Toolbar = toolbar; + titlebar.ToolbarStyle = UITitlebarToolbarStyle.Automatic; + titlebar.TitleVisibility = UITitlebarTitleVisibility.Visible; } } diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/NewTaskViewController.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/NewTaskViewController.cs index faa828a4c..1887897bc 100644 --- a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/NewTaskViewController.cs +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/NewTaskViewController.cs @@ -1,67 +1,66 @@ -namespace NativeEmbeddingDemo.MacCatalyst +namespace NativeEmbeddingDemo.MacCatalyst; + +public class NewTaskViewController : UIViewController { - public class NewTaskViewController : UIViewController - { - UITextField taskTitleTextField = null; - UITextField notesTextField = null; + UITextField taskTitleTextField = null; + UITextField notesTextField = null; - public override void ViewDidLoad() - { - base.ViewDidLoad(); + public override void ViewDidLoad() + { + base.ViewDidLoad(); - View!.BackgroundColor = UIColor.SystemBackground; + View!.BackgroundColor = UIColor.SystemBackground; - var stackView = new UIStackView - { - Axis = UILayoutConstraintAxis.Vertical, - Alignment = UIStackViewAlignment.Fill, - Distribution = UIStackViewDistribution.Fill, - Spacing = 8, - TranslatesAutoresizingMaskIntoConstraints = false - }; - View.AddSubview(stackView); + var stackView = new UIStackView + { + Axis = UILayoutConstraintAxis.Vertical, + Alignment = UIStackViewAlignment.Fill, + Distribution = UIStackViewDistribution.Fill, + Spacing = 8, + TranslatesAutoresizingMaskIntoConstraints = false + }; + View.AddSubview(stackView); - NSLayoutConstraint.ActivateConstraints(new[] - { - stackView.TopAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TopAnchor, 20), - stackView.LeadingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.LeadingAnchor, 20), - stackView.TrailingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TrailingAnchor, -20), - stackView.BottomAnchor.ConstraintLessThanOrEqualTo(View.SafeAreaLayoutGuide.BottomAnchor, -20) - }); + NSLayoutConstraint.ActivateConstraints(new[] + { + stackView.TopAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TopAnchor, 20), + stackView.LeadingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.LeadingAnchor, 20), + stackView.TrailingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TrailingAnchor, -20), + stackView.BottomAnchor.ConstraintLessThanOrEqualTo(View.SafeAreaLayoutGuide.BottomAnchor, -20) + }); - // Title text field - taskTitleTextField = CreateTextField("Title"); - stackView.AddArrangedSubview(taskTitleTextField); + // Title text field + taskTitleTextField = CreateTextField("Title"); + stackView.AddArrangedSubview(taskTitleTextField); - // Notes text field - notesTextField = CreateTextField("Notes"); - stackView.AddArrangedSubview(notesTextField); + // Notes text field + notesTextField = CreateTextField("Notes"); + stackView.AddArrangedSubview(notesTextField); - // Create task button - var createTaskButton = new UIButton(UIButtonType.System); - createTaskButton.SetTitle("Create Task", UIControlState.Normal); - createTaskButton.TouchUpInside += CreateTaskButtonTapped; - stackView.AddArrangedSubview(createTaskButton); - } + // Create task button + var createTaskButton = new UIButton(UIButtonType.System); + createTaskButton.SetTitle("Create Task", UIControlState.Normal); + createTaskButton.TouchUpInside += CreateTaskButtonTapped; + stackView.AddArrangedSubview(createTaskButton); + } - UITextField CreateTextField(string placeholder) + UITextField CreateTextField(string placeholder) + { + var uiTextField = new UITextField { - var uiTextField = new UITextField - { - Placeholder = placeholder, - BorderStyle = UITextBorderStyle.RoundedRect, - TranslatesAutoresizingMaskIntoConstraints = false - }; - uiTextField.HeightAnchor.ConstraintEqualTo(40).Active = true; - return uiTextField; - } + Placeholder = placeholder, + BorderStyle = UITextBorderStyle.RoundedRect, + TranslatesAutoresizingMaskIntoConstraints = false + }; + uiTextField.HeightAnchor.ConstraintEqualTo(40).Active = true; + return uiTextField; + } - void CreateTaskButtonTapped(object? sender, EventArgs e) - { - Console.WriteLine("Create button tapped."); + void CreateTaskButtonTapped(object? sender, EventArgs e) + { + Console.WriteLine("Create button tapped."); - // Implement your logic here for creating a task. - } + // Implement your logic here for creating a task. } } diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/SceneDelegate.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/SceneDelegate.cs index b24413d9a..783501f88 100644 --- a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/SceneDelegate.cs +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/SceneDelegate.cs @@ -1,67 +1,66 @@ -namespace NativeEmbeddingDemo.MacCatalyst +namespace NativeEmbeddingDemo.MacCatalyst; + +[Register("SceneDelegate")] +public class SceneDelegate : UIResponder, IUIWindowSceneDelegate { - [Register("SceneDelegate")] - public class SceneDelegate : UIResponder, IUIWindowSceneDelegate - { - [Export("window")] - public UIWindow? Window { get; set; } + [Export("window")] + public UIWindow? Window { get; set; } - [Export("scene:willConnectToSession:options:")] - public void WillConnect(UIScene scene, UISceneSession session, UISceneConnectionOptions connectionOptions) - { - // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. - // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. - // This delegate does not imply the connecting scene or session are new (see UIApplicationDelegate `GetConfiguration` instead). + [Export("scene:willConnectToSession:options:")] + public void WillConnect(UIScene scene, UISceneSession session, UISceneConnectionOptions connectionOptions) + { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see UIApplicationDelegate `GetConfiguration` instead). - if (scene is not UIWindowScene windowScene) - return; + if (scene is not UIWindowScene windowScene) + return; - Window = new UIWindow(windowScene); + Window = new UIWindow(windowScene); - var mainVC = new MainViewController(); - var navigationController = new UINavigationController(mainVC); - navigationController.NavigationBar.PrefersLargeTitles = true; + var mainVC = new MainViewController(); + var navigationController = new UINavigationController(mainVC); + navigationController.NavigationBar.PrefersLargeTitles = true; - Window.RootViewController = navigationController; - Window.MakeKeyAndVisible(); - } + Window.RootViewController = navigationController; + Window.MakeKeyAndVisible(); + } - [Export("sceneDidDisconnect:")] - public void DidDisconnect(UIScene scene) - { - // Called as the scene is being released by the system. - // This occurs shortly after the scene enters the background, or when its session is discarded. - // Release any resources associated with this scene that can be re-created the next time the scene connects. - // The scene may re-connect later, as its session was not neccessarily discarded (see UIApplicationDelegate `DidDiscardSceneSessions` instead). - } + [Export("sceneDidDisconnect:")] + public void DidDisconnect(UIScene scene) + { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see UIApplicationDelegate `DidDiscardSceneSessions` instead). + } - [Export("sceneDidBecomeActive:")] - public void DidBecomeActive(UIScene scene) - { - // Called when the scene has moved from an inactive state to an active state. - // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. - } + [Export("sceneDidBecomeActive:")] + public void DidBecomeActive(UIScene scene) + { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } - [Export("sceneWillResignActive:")] - public void WillResignActive(UIScene scene) - { - // Called when the scene will move from an active state to an inactive state. - // This may occur due to temporary interruptions (ex. an incoming phone call). - } + [Export("sceneWillResignActive:")] + public void WillResignActive(UIScene scene) + { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } - [Export("sceneWillEnterForeground:")] - public void WillEnterForeground(UIScene scene) - { - // Called as the scene transitions from the background to the foreground. - // Use this method to undo the changes made on entering the background. - } + [Export("sceneWillEnterForeground:")] + public void WillEnterForeground(UIScene scene) + { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } - [Export("sceneDidEnterBackground:")] - public void DidEnterBackground(UIScene scene) - { - // Called as the scene transitions from the foreground to the background. - // Use this method to save data, release shared resources, and store enough scene-specific state information - // to restore the scene back to its current state. - } + [Export("sceneDidEnterBackground:")] + public void DidEnterBackground(UIScene scene) + { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. } } diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/AppDelegate.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/AppDelegate.cs index ba25f30ea..ae3852ed3 100644 --- a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/AppDelegate.cs +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/AppDelegate.cs @@ -1,17 +1,14 @@ -namespace NativeEmbeddingDemo.iOS -{ - [Register("AppDelegate")] - public class AppDelegate : UIApplicationDelegate - { - public override UIWindow? Window { get; set; } +namespace NativeEmbeddingDemo.iOS; - public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions) - { - Window = new UIWindow(UIScreen.MainScreen.Bounds); - var vc = new MainViewController(); - Window.RootViewController = vc; - Window.MakeKeyAndVisible(); - return true; - } - } +[Register("AppDelegate")] +public class AppDelegate : UIApplicationDelegate +{ + public override UIWindow? Window { get; set; } + + public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions) => true; + + public override UISceneConfiguration GetConfiguration(UIApplication application, UISceneSession connectingSceneSession, UISceneConnectionOptions options) => + Enumerable.FirstOrDefault(options.UserActivities)?.ActivityType == "NewTaskWindow" + ? new UISceneConfiguration("New Task Configuration", UIWindowSceneSessionRole.Application) + : new UISceneConfiguration("Default Configuration", UIWindowSceneSessionRole.Application); } diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Info.plist b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Info.plist index f72bacae2..48ae986c0 100644 --- a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Info.plist +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Info.plist @@ -37,6 +37,29 @@ UIInterfaceOrientationLandscapeRight XSAppIconAssets - Assets.xcassets/AppIcon.appiconset + Assets.xcassets/AppIcon.appiconset + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + New Task Configuration + UISceneDelegateClassName + NewTaskSceneDelegate + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + SceneDelegate + + + + diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/MainViewController.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/MainViewController.cs index 044cf1b99..fa4db19c0 100644 --- a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/MainViewController.cs +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/MainViewController.cs @@ -1,90 +1,131 @@ using Microsoft.Maui.Platform; -namespace NativeEmbeddingDemo.iOS +namespace NativeEmbeddingDemo.iOS; + +public class MainViewController : UIViewController { - public class MainViewController : UIViewController - { - UIWindow GetWindow() => - View?.Window ?? - ParentViewController?.View?.Window ?? - MainViewController.MauiApp.Value.Services.GetRequiredService().GetWindow() ?? - UIApplication.SharedApplication.Delegate.GetWindow(); + UIWindow GetWindow() => + View?.Window ?? + ParentViewController?.View?.Window ?? + MainViewController.MauiApp.Value.Services.GetRequiredService().GetWindow() ?? + UIApplication.SharedApplication.Delegate.GetWindow(); - public static readonly Lazy MauiApp = new(() => + public static readonly Lazy MauiApp = new(() => + { + var mauiApp = MauiProgram.CreateMauiApp(builder => { - var mauiApp = MauiProgram.CreateMauiApp(builder => - { - builder.UseMauiEmbedding(); - }); - return mauiApp; + builder.UseMauiEmbedding(); }); + return mauiApp; + }); + + public static bool UseWindowContext = true; + + MyMauiContent? mauiView; - public static bool UseWindowContext = true; + public override void ViewDidLoad() + { + base.ViewDidLoad(); + + Title = "Main view controller"; - MyMauiContent? mauiView; + View!.BackgroundColor = UIColor.SystemBackground; - public override void ViewDidLoad() + var stackView = new UIStackView { - base.ViewDidLoad(); + Axis = UILayoutConstraintAxis.Vertical, + Alignment = UIStackViewAlignment.Fill, + Distribution = UIStackViewDistribution.Fill, + Spacing = 8, + TranslatesAutoresizingMaskIntoConstraints = false + }; + View.AddSubview(stackView); + + NSLayoutConstraint.ActivateConstraints(new[] + { + stackView.TopAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TopAnchor, 20), + stackView.LeadingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.LeadingAnchor, 20), + stackView.TrailingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TrailingAnchor, -20), + stackView.BottomAnchor.ConstraintLessThanOrEqualTo(View.SafeAreaLayoutGuide.BottomAnchor, -20) + }); + + // Create UIKit button + var uiButton = new UIButton(UIButtonType.System); + uiButton.SetTitle("UIKit button above .NET MAUI controls", UIControlState.Normal); + uiButton.TouchUpInside += OnUIButtonClicked; + stackView.AddArrangedSubview(uiButton); + + // Ensure .NET MAUI app is built before creating .NET MAUI views + var mauiApp = MainViewController.MauiApp.Value; + + // Create .NET MAUI context + var mauiContext = UseWindowContext + ? mauiApp.CreateEmbeddedWindowContext(GetWindow()) // Create window context + : new MauiContext(mauiApp.Services); // Create app context + + // Create .NET MAUI content + mauiView = new MyMauiContent(); + + // Create native view + var nativeView = mauiView.ToPlatformEmbedded(mauiContext); + nativeView.WidthAnchor.ConstraintEqualTo(View.Frame.Width).Active = true; + nativeView.HeightAnchor.ConstraintEqualTo(500).Active = true; + + // Add native view to layout + stackView.AddArrangedSubview(nativeView); + + if (DeviceInfo.Idiom == DeviceIdiom.Tablet) + AddNavBarButtons(); + } + + void AddNavBarButtons() + { + var addNewWindowButton = new UIBarButtonItem( + UIImage.GetSystemImage("macwindow.badge.plus"), + UIBarButtonItemStyle.Plain, + (sender, e) => RequestSession()); + + var addNewTaskButton = new UIBarButtonItem( + UIBarButtonSystemItem.Add, + (sender, e) => RequestSession("NewTaskWindow")); - Title = "Main view controller"; + NavigationItem.RightBarButtonItems = [addNewTaskButton, addNewWindowButton]; + } - View!.BackgroundColor = UIColor.SystemBackground; + void RequestSession(string? activityType = null) + { + var activity = activityType is null + ? null + : new NSUserActivity(activityType); - var stackView = new UIStackView + if (OperatingSystem.IsIOSVersionAtLeast(17)) + { + var request = UISceneSessionActivationRequest.Create(); + request.UserActivity = activity; + + UIApplication.SharedApplication.ActivateSceneSession(request, error => { - Axis = UILayoutConstraintAxis.Vertical, - Alignment = UIStackViewAlignment.Fill, - Distribution = UIStackViewDistribution.Fill, - Spacing = 8, - TranslatesAutoresizingMaskIntoConstraints = false - }; - View.AddSubview(stackView); - - NSLayoutConstraint.ActivateConstraints(new[] + Console.WriteLine(new NSErrorException(error)); + }); + } + else + { + UIApplication.SharedApplication.RequestSceneSessionActivation(null, activity, null, error => { - stackView.TopAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TopAnchor, 20), - stackView.LeadingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.LeadingAnchor, 20), - stackView.TrailingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TrailingAnchor, -20), - stackView.BottomAnchor.ConstraintLessThanOrEqualTo(View.SafeAreaLayoutGuide.BottomAnchor, -20) + Console.WriteLine(new NSErrorException(error)); }); - - // Create UIKit button - var uiButton = new UIButton(UIButtonType.System); - uiButton.SetTitle("UIKit button above .NET MAUI controls", UIControlState.Normal); - uiButton.TouchUpInside += OnUIButtonClicked; - stackView.AddArrangedSubview(uiButton); - - // Ensure .NET MAUI app is built before creating .NET MAUI views - var mauiApp = MainViewController.MauiApp.Value; - - // Create .NET MAUI context - var mauiContext = UseWindowContext - ? mauiApp.CreateEmbeddedWindowContext(GetWindow()) // Create window context - : new MauiContext(mauiApp.Services); // Create app context - - // Create .NET MAUI content - mauiView = new MyMauiContent(); - - // Create native view - var nativeView = mauiView.ToPlatformEmbedded(mauiContext); - nativeView.WidthAnchor.ConstraintEqualTo(View.Frame.Width).Active = true; - nativeView.HeightAnchor.ConstraintEqualTo(500).Active = true; - - // Add native view to layout - stackView.AddArrangedSubview(nativeView); } + } - async void OnUIButtonClicked(object? sender, EventArgs e) - { - if (mauiView?.DotNetBot is not Image bot) - return; + async void OnUIButtonClicked(object? sender, EventArgs e) + { + if (mauiView?.DotNetBot is not Image bot) + return; - await bot.RotateTo(360, 1000); - bot.Rotation = 0; + await bot.RotateTo(360, 1000); + bot.Rotation = 0; - bot.HeightRequest = 90; - } + bot.HeightRequest = 90; } } diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/NativeEmbeddingDemo.iOS.csproj b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/NativeEmbeddingDemo.iOS.csproj index 9100674e4..f5ce970d0 100644 --- a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/NativeEmbeddingDemo.iOS.csproj +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/NativeEmbeddingDemo.iOS.csproj @@ -5,7 +5,6 @@ enable true 13.0 - true true diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/NewTaskSceneDelegate.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/NewTaskSceneDelegate.cs new file mode 100644 index 000000000..0c574f692 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/NewTaskSceneDelegate.cs @@ -0,0 +1,21 @@ +namespace NativeEmbeddingDemo.iOS; + +[Register(nameof(NewTaskSceneDelegate))] +public class NewTaskSceneDelegate : UIWindowSceneDelegate +{ + public override UIWindow? Window { get; set; } + + public override void WillConnect(UIScene scene, UISceneSession session, UISceneConnectionOptions connectionOptions) + { + if (scene is not UIWindowScene windowScene) + return; + + var window = new UIWindow(windowScene); + window.RootViewController = new NewTaskViewController(); + window.WindowScene!.Title = "New Task"; + window.MakeKeyAndVisible(); + + Window = window; + } +} + diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/NewTaskViewController.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/NewTaskViewController.cs new file mode 100644 index 000000000..9df351ec5 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/NewTaskViewController.cs @@ -0,0 +1,66 @@ +namespace NativeEmbeddingDemo.iOS; + +public class NewTaskViewController : UIViewController +{ + private UITextField taskTitleTextField = null!; + private UITextField notesTextField = null!; + + public override void ViewDidLoad() + { + base.ViewDidLoad(); + + View!.BackgroundColor = UIColor.SystemBackground; + + // StackView + var stackView = new UIStackView + { + Axis = UILayoutConstraintAxis.Vertical, + Alignment = UIStackViewAlignment.Fill, + Distribution = UIStackViewDistribution.Fill, + Spacing = 8, + TranslatesAutoresizingMaskIntoConstraints = false + }; + View.AddSubview(stackView); + + NSLayoutConstraint.ActivateConstraints(new[] + { + stackView.TopAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TopAnchor, 20), + stackView.LeadingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.LeadingAnchor, 20), + stackView.TrailingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TrailingAnchor, -20), + stackView.BottomAnchor.ConstraintLessThanOrEqualTo(View.SafeAreaLayoutGuide.BottomAnchor, -20) + }); + + // Title Text Field + taskTitleTextField = CreateTextField("Title"); + stackView.AddArrangedSubview(taskTitleTextField); + + // Notes Text Field + notesTextField = CreateTextField("Notes"); + stackView.AddArrangedSubview(notesTextField); + + // Create Task Button + var createTaskButton = new UIButton(UIButtonType.System); + createTaskButton.SetTitle("Create Task", UIControlState.Normal); + createTaskButton.TouchUpInside += CreateTaskButtonTapped; + stackView.AddArrangedSubview(createTaskButton); + } + + private UITextField CreateTextField(string placeholder) + { + var textField = new UITextField + { + Placeholder = placeholder, + BorderStyle = UITextBorderStyle.RoundedRect, + TranslatesAutoresizingMaskIntoConstraints = false + }; + textField.HeightAnchor.ConstraintEqualTo(40).Active = true; + return textField; + } + + private void CreateTaskButtonTapped(object? sender, EventArgs e) + { + Console.WriteLine("Create button tapped"); + + // Implement your logic here for creating a task + } +} \ No newline at end of file diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/SceneDelegate.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/SceneDelegate.cs new file mode 100644 index 000000000..b7ad6cf15 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/SceneDelegate.cs @@ -0,0 +1,68 @@ +namespace NativeEmbeddingDemo.iOS; + +[Register("SceneDelegate")] +public class SceneDelegate : UIResponder, IUIWindowSceneDelegate +{ + + [Export("window")] + public UIWindow? Window { get; set; } + + [Export("scene:willConnectToSession:options:")] + public void WillConnect(UIScene scene, UISceneSession session, UISceneConnectionOptions connectionOptions) + { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see UIApplicationDelegate `GetConfiguration` instead). + + if (scene is not UIWindowScene windowScene) + return; + + Window = new UIWindow(windowScene); + + var mainVC = new MainViewController(); + var navigationController = new UINavigationController(mainVC); + navigationController.NavigationBar.PrefersLargeTitles = true; + + Window.RootViewController = navigationController; + Window.MakeKeyAndVisible(); + } + + [Export("sceneDidDisconnect:")] + public void DidDisconnect(UIScene scene) + { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see UIApplicationDelegate `DidDiscardSceneSessions` instead). + } + + [Export("sceneDidBecomeActive:")] + public void DidBecomeActive(UIScene scene) + { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + [Export("sceneWillResignActive:")] + public void WillResignActive(UIScene scene) + { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + [Export("sceneWillEnterForeground:")] + public void WillEnterForeground(UIScene scene) + { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + [Export("sceneDidEnterBackground:")] + public void DidEnterBackground(UIScene scene) + { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } +} + diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo/NativeEmbeddingDemo.csproj b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo/NativeEmbeddingDemo.csproj index cc31ce144..ceba796fa 100644 --- a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo/NativeEmbeddingDemo.csproj +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo/NativeEmbeddingDemo.csproj @@ -1,7 +1,7 @@  - net8.0 + net8.0 NativeEmbeddingDemo true @@ -9,16 +9,6 @@ enable enable - - NativeEmbeddingDemo - - - com.companyname.nativeembeddingdemo - - - 1.0 - 1 - 11.0 13.1 21.0 @@ -28,6 +18,7 @@ +