From 96629be579af47f1a0377afc9705f0b17d7a71fb Mon Sep 17 00:00:00 2001 From: RadekVym Date: Sat, 4 Mar 2023 10:47:56 +0100 Subject: [PATCH 1/4] Finally fixed the transformation problems with pages --- .DS_Store | Bin 0 -> 6148 bytes .../PlaygroundAppShell.xaml.cs | 7 ------- .../Handlers/Platform/CustomContentView.cs | 6 +++++- 3 files changed, 5 insertions(+), 8 deletions(-) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..652ab22fe67272a820a5ba0ab7d2e784c21e7da5 GIT binary patch literal 6148 zcmeHK%}T>S5T0$TO(;SS3OxqA7OX)J#Y>3#0!H+pQWINhXv~(THHT8jSzpK}@p+ut z-3X;QcoMNQu=~x<&u->}><<74e=$4;Xaj(SjZlzMA!M#})l4v$)as3$-DcBnwwe#Yv&@5eIA3IbIJ=|K zwUkLz>S1&fkMco#|6Hc?FiuA^l@Jd{7;=9br$d?ha*+-*l^bY>ZCm!B-B~VAd%do6 z;<~G@v+TR1_ubXXwhj)D&aMWNzx!aFJ(b-f0&G?D2TePv!5&&Uig z1Iz$3ussZzGr($XPsv;J8XIkn#* a9pgNMg+`i%>?$3RF9M1X?wEmJVBib-drZUt literal 0 HcmV?d00001 diff --git a/src/SimpleToolkit.Playground/PlaygroundAppShell.xaml.cs b/src/SimpleToolkit.Playground/PlaygroundAppShell.xaml.cs index ebf45f9..1ce2043 100644 --- a/src/SimpleToolkit.Playground/PlaygroundAppShell.xaml.cs +++ b/src/SimpleToolkit.Playground/PlaygroundAppShell.xaml.cs @@ -60,16 +60,9 @@ public PlaygroundAppShell() 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; } 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); + } } } } From 6d6859841b4d6a48655018cbb1c42b5ce15e4c81 Mon Sep 17 00:00:00 2001 From: RadekVym Date: Sat, 4 Mar 2023 16:09:53 +0100 Subject: [PATCH 2/4] Page transitions improvements --- .../PlaygroundAppShell.xaml.cs | 55 +++++++++-------- .../Views/Pages/ImagePage.xaml.cs | 17 +++--- .../Extensions/SimpleShellExtensions.cs | 15 ++++- .../SimpleShellTransitionExtensions.cs | 59 +++++++++++++++++++ .../SimpleShellSectionHandler.Shared.cs | 4 +- .../Transitions/SimpleShellTransition.cs | 4 +- 6 files changed, 115 insertions(+), 39 deletions(-) create mode 100644 src/SimpleToolkit.SimpleShell/Extensions/SimpleShellTransitionExtensions.cs diff --git a/src/SimpleToolkit.Playground/PlaygroundAppShell.xaml.cs b/src/SimpleToolkit.Playground/PlaygroundAppShell.xaml.cs index 1ce2043..3a1e476 100644 --- a/src/SimpleToolkit.Playground/PlaygroundAppShell.xaml.cs +++ b/src/SimpleToolkit.Playground/PlaygroundAppShell.xaml.cs @@ -50,32 +50,37 @@ public PlaygroundAppShell() Loaded += PlaygroundAppShellLoaded; - this.SetTransition(args => - { - switch (args.TransitionType) + this.SetTransition( + callback: 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; - args.DestinationPage.TranslationX = (1 - args.Progress) * args.DestinationPage.Width; - break; - case SimpleShellTransitionType.Popping: - 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: args => 250u, + finished: args => + { + args.DestinationPage.TranslationX = 0; + args.OriginPage.TranslationX = 0; + args.OriginPage.Opacity = 1; + args.DestinationPage.Opacity = 1; + }, + destinationPageInFront: args => args.TransitionType switch + { + SimpleShellTransitionType.Popping => false, + _ => true + }); } private void PlaygroundAppShellLoaded(object sender, EventArgs e) diff --git a/src/SimpleToolkit.Playground/Views/Pages/ImagePage.xaml.cs b/src/SimpleToolkit.Playground/Views/Pages/ImagePage.xaml.cs index ef758de..543bfde 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,16 +9,12 @@ public ImagePage() { InitializeComponent(); - this.SetTransition( - callback: args => - { - args.DestinationPage.Scale = args.Progress; - }, - 500, - finished: args => - { - args.DestinationPage.Scale = 1; - }); + 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)); } //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/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/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. From 5876b6713a52b10af723289a1b773c0ee487f334 Mon Sep 17 00:00:00 2001 From: RadekVym Date: Sat, 4 Mar 2023 16:49:44 +0100 Subject: [PATCH 3/4] Updated docs --- docs/SimpleToolkit.SimpleShell/Transitions.md | 53 +++++++++++-------- .../PlaygroundAppShell.xaml.cs | 8 +-- .../SampleAppShell.xaml.cs | 12 ++--- .../Views/Pages/ImagePage.xaml.cs | 14 ++--- .../SimpleToolkit.SimpleShell.csproj | 2 +- 5 files changed, 50 insertions(+), 39 deletions(-) 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 3a1e476..a55ae54 100644 --- a/src/SimpleToolkit.Playground/PlaygroundAppShell.xaml.cs +++ b/src/SimpleToolkit.Playground/PlaygroundAppShell.xaml.cs @@ -51,7 +51,7 @@ public PlaygroundAppShell() Loaded += PlaygroundAppShellLoaded; this.SetTransition( - callback: args => + callback: static args => { switch (args.TransitionType) { @@ -68,15 +68,15 @@ public PlaygroundAppShell() break; } }, - duration: args => 250u, - finished: args => + duration: static args => 250u, + finished: static args => { args.DestinationPage.TranslationX = 0; args.OriginPage.TranslationX = 0; args.OriginPage.Opacity = 1; args.DestinationPage.Opacity = 1; }, - destinationPageInFront: args => args.TransitionType switch + destinationPageInFront: static args => args.TransitionType switch { SimpleShellTransitionType.Popping => false, _ => true 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/Views/Pages/ImagePage.xaml.cs b/src/SimpleToolkit.Playground/Views/Pages/ImagePage.xaml.cs index 543bfde..7a443b5 100644 --- a/src/SimpleToolkit.Playground/Views/Pages/ImagePage.xaml.cs +++ b/src/SimpleToolkit.Playground/Views/Pages/ImagePage.xaml.cs @@ -10,12 +10,14 @@ 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)); - } + 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/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. From a1069e0b25d486287a8646560f903ca23343dc1a Mon Sep 17 00:00:00 2001 From: RadekVym Date: Sat, 4 Mar 2023 17:00:03 +0100 Subject: [PATCH 4/4] Updated package version in the playground project --- src/SimpleToolkit.Playground/SimpleToolkit.Playground.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 @@ - +