diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..652ab22 Binary files /dev/null and b/.DS_Store differ diff --git a/docs/SimpleToolkit.SimpleShell/Transitions.md b/docs/SimpleToolkit.SimpleShell/Transitions.md index f7bf3ad..d002f80 100644 --- a/docs/SimpleToolkit.SimpleShell/Transitions.md +++ b/docs/SimpleToolkit.SimpleShell/Transitions.md @@ -12,7 +12,7 @@ Each transition is represented by a `SimpleShellTransition` object which contain - `Duration` - method returning duration of the transition - `DestinationPageInFront` - method returning whether the destination page should be displayed in front of the origin page when navigating from one page to another -Each of these methods takes a object `SimpleShellTransitionArgs` as a parameter. Usefull information about currently running transition can be obtained from this object: +Each of these methods takes a `SimpleShellTransitionArgs` object as a parameter. Usefull information about currently running transition can be obtained from this object: - `OriginPage` of type `VisualElement` - page from which the navigation is initiated - `DestinationPage` of type `VisualElement` - destination page of the navigation @@ -39,16 +39,6 @@ public static void SetTransition( this Page page, SimpleShellTransition transition) -public static void SetTransition( - this Page page, - Action callback, - uint duration = 250, - Action starting = null, - Action finished = null, - bool destinationPageInFrontOnSwitching = true, - bool destinationPageInFrontOnPushing = true, - bool destinationPageInFrontOnPopping = true) - public static void SetTransition( this Page page, Action callback, @@ -108,8 +98,8 @@ public AppShell() _ => true }, duration: args => args.TransitionType switch { - SimpleShellTransitionType.Switching => 500, - _ => 350 + SimpleShellTransitionType.Switching => 500u, + _ => 350u }); } ``` @@ -128,15 +118,10 @@ public ImagePage() InitializeComponent(); this.SetTransition( - callback: args => - { - args.DestinationPage.Scale = args.Progress; - }, - 500, - finished: args => - { - args.DestinationPage.Scale = 1; - }); + callback: args => args.DestinationPage.Scale = args.Progress, + starting: args => args.DestinationPage.Scale = 0, + finished: args => args.DestinationPage.Scale = 1, + duration: args => 500u); } ``` @@ -145,3 +130,27 @@ Output:

+ +### Combining transitions + +Two transitions can be combined into one when you want to use different transitions under different conditions: + +```csharp +public ImagePage() +{ + InitializeComponent(); + + this.SetTransition(new SimpleShellTransition( + callback: args => args.DestinationPage.Scale = args.Progress, + starting: args => args.DestinationPage.Scale = 0, + finished: args => args.DestinationPage.Scale = 1, + duration: args => 500u) + .CombinedWith( + transition: SimpleShell.Current.GetTransition(), + when: args => args.TransitionType != SimpleShellTransitionType.Pushing)); +} +``` + +`when` delegate determines when the second `transition` should be used. + +> In this example, scale transition is used only when the the page is being pushed to the navigation stack, otherwise the default transition defined in shell is used. \ No newline at end of file diff --git a/src/SimpleToolkit.Playground/PlaygroundAppShell.xaml.cs b/src/SimpleToolkit.Playground/PlaygroundAppShell.xaml.cs index ebf45f9..a55ae54 100644 --- a/src/SimpleToolkit.Playground/PlaygroundAppShell.xaml.cs +++ b/src/SimpleToolkit.Playground/PlaygroundAppShell.xaml.cs @@ -50,39 +50,37 @@ public PlaygroundAppShell() Loaded += PlaygroundAppShellLoaded; - this.SetTransition(args => - { - switch (args.TransitionType) + this.SetTransition( + callback: static args => { - case SimpleShellTransitionType.Switching: - args.OriginPage.Opacity = 1 - args.Progress; - args.DestinationPage.Opacity = args.Progress; - break; - case SimpleShellTransitionType.Pushing: - args.DestinationPage.Opacity = args.DestinationPage.Width < 0 ? 0 : 1; -#if IOS - // If I use just TranslationX, it is not applied on iOS - args.DestinationPage.Scale = 0.99 + (0.01 * args.Progress); -#endif - args.DestinationPage.TranslationX = (1 - args.Progress) * args.DestinationPage.Width; - break; - case SimpleShellTransitionType.Popping: -#if IOS - args.OriginPage.Scale = 0.99 + (0.01 * (1 - args.Progress)); -#endif - args.OriginPage.TranslationX = args.Progress * args.OriginPage.Width; - break; - } - }, - 250, - finished: args => - { - args.DestinationPage.TranslationX = 0; - args.OriginPage.TranslationX = 0; - args.OriginPage.Opacity = 1; - args.DestinationPage.Opacity = 1; - }, - destinationPageInFrontOnPopping: false); + switch (args.TransitionType) + { + case SimpleShellTransitionType.Switching: + args.OriginPage.Opacity = 1 - args.Progress; + args.DestinationPage.Opacity = args.Progress; + break; + case SimpleShellTransitionType.Pushing: + args.DestinationPage.Opacity = args.DestinationPage.Width < 0 ? 0 : 1; + args.DestinationPage.TranslationX = (1 - args.Progress) * args.DestinationPage.Width; + break; + case SimpleShellTransitionType.Popping: + args.OriginPage.TranslationX = args.Progress * args.OriginPage.Width; + break; + } + }, + duration: static args => 250u, + finished: static args => + { + args.DestinationPage.TranslationX = 0; + args.OriginPage.TranslationX = 0; + args.OriginPage.Opacity = 1; + args.DestinationPage.Opacity = 1; + }, + destinationPageInFront: static args => args.TransitionType switch + { + SimpleShellTransitionType.Popping => false, + _ => true + }); } private void PlaygroundAppShellLoaded(object sender, EventArgs e) diff --git a/src/SimpleToolkit.Playground/SampleAppShell.xaml.cs b/src/SimpleToolkit.Playground/SampleAppShell.xaml.cs index b8c277d..0eb0656 100644 --- a/src/SimpleToolkit.Playground/SampleAppShell.xaml.cs +++ b/src/SimpleToolkit.Playground/SampleAppShell.xaml.cs @@ -14,7 +14,7 @@ public SampleAppShell() Routing.RegisterRoute(nameof(ImagePage), typeof(ImagePage)); this.SetTransition( - callback: args => + callback: static args => { switch (args.TransitionType) { @@ -30,22 +30,22 @@ public SampleAppShell() break; } }, - finished: args => + finished: static args => { args.OriginPage.Opacity = 1; args.OriginPage.TranslationX = 0; args.DestinationPage.Opacity = 1; args.DestinationPage.TranslationX = 0; }, - destinationPageInFront: args => args.TransitionType switch + destinationPageInFront: static args => args.TransitionType switch { SimpleShellTransitionType.Popping => false, _ => true }, - duration: args => args.TransitionType switch + duration: static args => args.TransitionType switch { - SimpleShellTransitionType.Switching => 500, - _ => 350 + SimpleShellTransitionType.Switching => 500u, + _ => 350u }); Loaded += PlaygroundAppShellLoaded; diff --git a/src/SimpleToolkit.Playground/SimpleToolkit.Playground.csproj b/src/SimpleToolkit.Playground/SimpleToolkit.Playground.csproj index 863069f..8affc44 100644 --- a/src/SimpleToolkit.Playground/SimpleToolkit.Playground.csproj +++ b/src/SimpleToolkit.Playground/SimpleToolkit.Playground.csproj @@ -72,7 +72,7 @@ - + diff --git a/src/SimpleToolkit.Playground/Views/Pages/ImagePage.xaml.cs b/src/SimpleToolkit.Playground/Views/Pages/ImagePage.xaml.cs index ef758de..7a443b5 100644 --- a/src/SimpleToolkit.Playground/Views/Pages/ImagePage.xaml.cs +++ b/src/SimpleToolkit.Playground/Views/Pages/ImagePage.xaml.cs @@ -1,4 +1,5 @@ using SimpleToolkit.SimpleShell.Extensions; +using SimpleToolkit.SimpleShell.Transitions; namespace SimpleToolkit.SimpleShell.Playground.Views.Pages; @@ -8,17 +9,15 @@ public ImagePage() { InitializeComponent(); - this.SetTransition( - callback: args => - { - args.DestinationPage.Scale = args.Progress; - }, - 500, - finished: args => - { - args.DestinationPage.Scale = 1; - }); - } + this.SetTransition(new SimpleShellTransition( + callback: static args => args.DestinationPage.Scale = args.Progress, + starting: static args => args.DestinationPage.Scale = 0, + finished: static args => args.DestinationPage.Scale = 1, + duration: static args => 500u) + .CombinedWith( + transition: SimpleShell.Current.GetTransition(), + when: static args => args.TransitionType != SimpleShellTransitionType.Pushing)); + } //protected override void OnNavigatedTo(NavigatedToEventArgs args) //{ diff --git a/src/SimpleToolkit.SimpleShell/Extensions/SimpleShellExtensions.cs b/src/SimpleToolkit.SimpleShell/Extensions/SimpleShellExtensions.cs index 5789773..ff4a7aa 100644 --- a/src/SimpleToolkit.SimpleShell/Extensions/SimpleShellExtensions.cs +++ b/src/SimpleToolkit.SimpleShell/Extensions/SimpleShellExtensions.cs @@ -1,12 +1,20 @@ using SimpleToolkit.SimpleShell.Transitions; -using static System.TimeZoneInfo; namespace SimpleToolkit.SimpleShell.Extensions { public static class SimpleShellExtensions { /// - /// Sets the transition to the page. + /// Gets the page transition. + /// + /// Page with required transition. + public static SimpleShellTransition GetTransition(this Page page) + { + return SimpleShell.GetTransition(page); + } + + /// + /// Sets the page transition. /// /// Destination page of a navigation with this transition. /// Transition of a navigation to the page. @@ -26,6 +34,8 @@ public static void SetTransition(this Page page, SimpleShellTransition transitio /// Whether the destination page should be displayed in front of the origin page when switching root pages in the stack. /// Whether the destination page should be displayed in front of the origin page when pushing new page to the stack. /// Whether the destination page should be displayed in front of the origin page when popping existing page from the stack. + [Obsolete("This extension method is deprecated. Please use other overload of this method.")] + [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] public static void SetTransition( this Page page, Action callback, @@ -94,6 +104,7 @@ public static void SetTransition( }, duration, starting, finished, destinationPageInFront)); } + internal static IEnumerable GetShellSections(this BaseShellItem baseShellItem) { var list = new HashSet(); diff --git a/src/SimpleToolkit.SimpleShell/Extensions/SimpleShellTransitionExtensions.cs b/src/SimpleToolkit.SimpleShell/Extensions/SimpleShellTransitionExtensions.cs new file mode 100644 index 0000000..d257e4f --- /dev/null +++ b/src/SimpleToolkit.SimpleShell/Extensions/SimpleShellTransitionExtensions.cs @@ -0,0 +1,59 @@ +using System; +using SimpleToolkit.SimpleShell.Transitions; + +namespace SimpleToolkit.SimpleShell.Extensions +{ + public static class SimpleShellTransitionExtensions + { + /// + /// Combines two page transitions. + /// + /// Default page transition + /// Page transition which should be combined with the default one + /// When the second page transition should be used + /// New page transition + public static SimpleShellTransition CombinedWith( + this SimpleShellTransition originalTransition, + SimpleShellTransition transition, + Func when) + { + return new SimpleShellTransition( + callback: args => + { + if (when?.Invoke(args) ?? false) + transition?.Callback?.Invoke(args); + else + originalTransition?.Callback?.Invoke(args); + }, + duration: args => + { + if (when?.Invoke(args) ?? false) + return transition?.Duration?.Invoke(args) ?? SimpleShellTransition.DefaultDuration; + else + return originalTransition?.Duration?.Invoke(args) ?? SimpleShellTransition.DefaultDuration; + }, + starting: args => + { + if (when?.Invoke(args) ?? false) + transition?.Starting?.Invoke(args); + else + originalTransition?.Starting?.Invoke(args); + }, + finished: args => + { + if (when?.Invoke(args) ?? false) + transition?.Finished?.Invoke(args); + else + originalTransition?.Finished?.Invoke(args); + }, + destinationPageInFront: args => + { + if (when?.Invoke(args) ?? false) + return transition?.DestinationPageInFront?.Invoke(args) ?? false; + else + return originalTransition?.DestinationPageInFront?.Invoke(args) ?? false; + }); + } + } +} + diff --git a/src/SimpleToolkit.SimpleShell/Handlers/Platform/CustomContentView.cs b/src/SimpleToolkit.SimpleShell/Handlers/Platform/CustomContentView.cs index f2836e9..927980c 100644 --- a/src/SimpleToolkit.SimpleShell/Handlers/Platform/CustomContentView.cs +++ b/src/SimpleToolkit.SimpleShell/Handlers/Platform/CustomContentView.cs @@ -11,7 +11,11 @@ public override void LayoutSubviews() foreach (var subview in Subviews) { - subview.Frame = Bounds; + // Only resize a subview when it does not match the size of the parent + if (subview.Bounds.Width != Bounds.Width || subview.Bounds.Height != Bounds.Height) + { + subview.Frame = new CoreGraphics.CGRect(subview.Frame.X, subview.Frame.Y, Bounds.Width, Bounds.Height); + } } } } diff --git a/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellSection/SimpleShellSectionHandler.Shared.cs b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellSection/SimpleShellSectionHandler.Shared.cs index ec33eba..323ebe9 100644 --- a/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellSection/SimpleShellSectionHandler.Shared.cs +++ b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellSection/SimpleShellSectionHandler.Shared.cs @@ -110,7 +110,9 @@ protected virtual void SyncNavigationStack(bool animated, NavigationRequestedEve (VirtualView.CurrentItem as IShellContentController).GetOrCreateContent() }; - //LogStack(e, pageStack, VirtualView); +#if DEBUG + LogStack(e, pageStack, VirtualView); +#endif if (e?.RequestType != NavigationRequestType.PopToRoot) // See https://github.com/dotnet/maui/pull/10653 { diff --git a/src/SimpleToolkit.SimpleShell/SimpleToolkit.SimpleShell.csproj b/src/SimpleToolkit.SimpleShell/SimpleToolkit.SimpleShell.csproj index 173c3f0..082212b 100644 --- a/src/SimpleToolkit.SimpleShell/SimpleToolkit.SimpleShell.csproj +++ b/src/SimpleToolkit.SimpleShell/SimpleToolkit.SimpleShell.csproj @@ -24,7 +24,7 @@ MAUI, Controls, Shell, Navigation, Transitions RadekVyM ..\..\packages - 2.0.1 + 2.1.0 $(VersionPrefix)$(VersionSuffix) Simplified implementation of .NET MAUI Shell that is part of SimpleToolkit library. diff --git a/src/SimpleToolkit.SimpleShell/Transitions/SimpleShellTransition.cs b/src/SimpleToolkit.SimpleShell/Transitions/SimpleShellTransition.cs index 4793831..51d12ab 100644 --- a/src/SimpleToolkit.SimpleShell/Transitions/SimpleShellTransition.cs +++ b/src/SimpleToolkit.SimpleShell/Transitions/SimpleShellTransition.cs @@ -93,6 +93,8 @@ public class SimpleShellTransition /// Whether the destination page should be displayed in front of the origin page when switching root pages in the stack. /// Whether the destination page should be displayed in front of the origin page when pushing new page to the stack. /// Whether the destination page should be displayed in front of the origin page when popping existing page from the stack. + [Obsolete("This constructor is deprecated. Please use other constructor.")] + [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] public SimpleShellTransition( Action callback, uint duration = DefaultDuration, @@ -116,7 +118,7 @@ public SimpleShellTransition( } /// - /// Constructor that allows to dynamically set some properties of the transition. + /// Constructor that allows to dynamically set properties of the transition. /// /// Callback that is called when progress of the transition changes. /// Duration of the transition.