Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 86 additions & 1 deletion PJ.NavigationTrans.Maui/NavigationTrans.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,115 @@
#endif

namespace PJ.NavigationTrans.Maui;

/// <summary>
/// Provides attached properties and methods for configuring navigation transitions in a <see cref="ShellContent"/>.
/// </summary>
/// <remarks>This class enables customization of navigation transitions, including duration and transition types,
/// for views within a .NET MAUI application. It supports platform-specific transition configurations for Android
/// and iOS, allowing developers to define custom animations.</remarks>
public static class NavigationTrans
{
/// <summary>
/// Identifies the attached property that specifies the duration, in milliseconds, for a given <see cref="ShellContent"/>.
/// </summary>
/// <remarks>
/// This property is used to define the duration of an operation or animation associated with a <see cref="ShellContent"/>.
/// The default value is 500 milliseconds.
/// </remarks>
public static readonly BindableProperty DurationProperty =
BindableProperty.CreateAttached("Duration", typeof(double), typeof(ShellContent), 500d);

/// <summary>
/// Retrieves the duration value associated with the specified view.
/// </summary>
/// <param name="view">The <see cref="BindableObject"/> from which to retrieve the duration value.</param>
/// <returns>The duration value as a <see cref="double"/>. Returns 0 if no value is set.</returns>
public static double GetDuration(BindableObject view) => (double)view.GetValue(DurationProperty);

/// <summary>
/// Sets the duration value for the specified bindable object.
/// </summary>
/// <remarks>This method assigns the specified duration value to the bindable object's <see cref="DurationProperty"/>.
/// Ensure that the <paramref name="value"/> is valid and appropriate for the context in
/// which the bindable object is used.</remarks>
/// <param name="view">The bindable object to which the duration value will be applied. Cannot be null.</param>
/// <param name="value">The duration value to set, expressed as a double. Must be a non-negative value.</param>
public static void SetDuration(BindableObject view, double value) => view.SetValue(DurationProperty, value);

/// <summary>
/// Identifies the attached property that specifies the transition type to be used when a <see cref="ShellContent"/>
/// is displayed.
/// </summary>
/// <remarks>This property allows developers to define custom transition effects for <see cref="ShellContent"/>
/// elements. The transition type can be set to one of the predefined values in the <see cref="TransitionType"/>
/// enumeration or a custom implementation.</remarks>
public static readonly BindableProperty TransitionInProperty =
BindableProperty.CreateAttached("TransitionIn", typeof(TransitionType), typeof(ShellContent), TransitionType.Default);

/// <summary>
/// Retrieves the transition type applied to the specified view when it enters the screen.
/// </summary>
/// <param name="view">The view for which the transition type is being retrieved. Cannot be null.</param>
/// <returns>The <see cref="TransitionType"/> associated with the view's entry transition.</returns>
public static TransitionType GetTransitionIn(BindableObject view) => (TransitionType)view.GetValue(TransitionInProperty);

/// <summary>
/// Sets the transition type to be applied when the specified view is displayed.
/// </summary>
/// <param name="view">The view to which the transition type will be applied. Must not be <see langword="null"/>.</param>
/// <param name="value">The transition type to apply when the view is displayed.</param>
public static void SetTransitionIn(BindableObject view, TransitionType value) => view.SetValue(TransitionInProperty, value);

/// <summary>
/// Identifies the attached property that specifies the transition type to be used when navigating away from a <see
/// cref="ShellContent"/>.
/// </summary>
/// <remarks>This property allows developers to define custom transition effects for navigation when a <see
/// cref="ShellContent"/> is exited. The default value is <see cref="TransitionType.Default"/>.</remarks>
public static readonly BindableProperty TransitionOutProperty =
BindableProperty.CreateAttached("TransitionOut", typeof(TransitionType), typeof(ShellContent), TransitionType.Default);

/// <summary>
/// Retrieves the transition type that is applied when the specified view transitions out.
/// </summary>
/// <param name="view">The <see cref="BindableObject"/> from which to retrieve the transition type.</param>
/// <returns>The <see cref="TransitionType"/> representing the transition applied when the view transitions out.</returns>
public static TransitionType GetTransitionOut(BindableObject view) => (TransitionType)view.GetValue(TransitionOutProperty);

/// <summary>
/// Sets the transition type to be applied when the specified view transitions out.
/// </summary>
/// <param name="view">The view to which the transition type will be applied. Cannot be null.</param>
/// <param name="value">The transition type to set for the view. Specifies how the view transitions out.</param>
public static void SetTransitionOut(BindableObject view, TransitionType value) => view.SetValue(TransitionOutProperty, value);

#if ANDROID
/// <summary>
/// Sets custom transition animations for an Android view.
/// </summary>
/// <remarks>This method registers custom transition animations for the specified Android view. The animations
/// are defined by the provided resource IDs and duration.</remarks>
/// <param name="view">The <see cref="BindableObject"/> representing the view to apply the transitions to. Cannot be null.</param>
/// <param name="transitionIn">The animation resource ID for the transition-in effect.</param>
/// <param name="transitionOut">The animation resource ID for the transition-out effect.</param>
/// <param name="duration">The duration of the transition animations, in milliseconds. Must be greater than or equal to 0.</param>
public static void SetAndroidTransitions(BindableObject view, int transitionIn, int transitionOut, double duration)
{
RegisterCustomTransitions(view);
var value = new AndroidCustomAnimation(duration, transitionIn, transitionOut);
PropertyManager.Add(view, value);
}
#elif IOS
/// <summary>
/// Sets custom transition animations for an iOS view.
/// </summary>
/// <param name="view">The <see cref="Page"/> or <see cref="ShellContent"/> that will be animated.</param>
/// <param name="animationIn">Code that describes animation for entering the page.</param>
/// <param name="configurationIn">Code that describes the configuration for the view that will be animated.</param>
/// <param name="animationOut">Code that describes animation for leaving the page.</param>
/// <param name="configurationOut">Code that describes the configuration for the view that will be animated.</param>
/// <param name="duration">Animation duration in milliseconds.</param>
public static void SetIosTransitions(BindableObject view, Action<UIView> animationIn, Action<UIView>? configurationIn, Action<UIView> animationOut, Action<UIView>? configurationOut, double duration)
{
RegisterCustomTransitions(view);
Expand All @@ -51,6 +130,12 @@ static void RegisterCustomTransitions(BindableObject view)
SetTransitionOut(view, TransitionType.Custom);
}

/// <summary>
/// Retrieves the custom animation transitions associated with the specified view.
/// </summary>
/// <param name="view">The <see cref="BindableObject"/> for which to retrieve the animation transitions. Cannot be <see langword="null"/>.</param>
/// <returns>The <see cref="BaseCustomAnimation"/> object representing the animation transitions for the specified view, or
/// <see langword="null"/> if no transitions are associated with the view.</returns>
public static BaseCustomAnimation? GetTransitions(BindableObject view) => PropertyManager.Get(view);

}
Expand All @@ -66,4 +151,4 @@ public static void Add(BindableObject key, BaseCustomAnimation value) =>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static BaseCustomAnimation? Get(BindableObject key) =>
properties.TryGetValue(key, out var value) ? value : null;
}
}
10 changes: 7 additions & 3 deletions PJ.NavigationTrans.Maui/PJ.NavigationTrans.Maui.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
<Description>This project allows you to use custom animatinos during navigation in .NET MAUI</Description>

<PackageTags>.NET MAUI, Navigation, Animation</PackageTags>

<PackageId>PJSouzaSoftware.NavigationTrans.Maui</PackageId>

<PackageReadmeFile>README.md</PackageReadmeFile>
<RepositoryUrl>https://github.com/pictos/PJ.NavigationTrans.Maui/</RepositoryUrl>
<PackageProjectUrl>$(RepositoryUrl)</PackageProjectUrl>
<Product>NavigationTrans.Maui</Product>
Expand All @@ -33,11 +33,11 @@
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>

<PropertyGroup Condition="'$(GITHUB_ACTIONS)' == 'true'">
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
</PropertyGroup>
<ItemGroup>
<SourceRoot Include="$(MSBuildThisFileDirectory)/" />
Expand All @@ -50,4 +50,8 @@
<ItemGroup Condition="$(IsAndroid)">
<AndroidResource Include="Platforms\Android\Resources\anim\**\*.xml" />
</ItemGroup>

<ItemGroup>
<None Include="..\README.md" Pack="true" PackagePath="\" />
</ItemGroup>
</Project>
112 changes: 110 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,119 @@
# PJ.NavigationTrans.Maui 🏳️‍⚧️

This is a library that allows you to use custom animations during Flyout navigations and Push navigations using Shell.
This is a library that allows you to use custom animations during Flyout navigations and Push navigations using Shell or NavigationPage.
Be aware that transition respects the behavior of the native platform, so they may look different between OSes.



* Available on NuGet: [![NuGet](https://img.shields.io/nuget/v/PJSouzaSoftware.NavigationTrans.Maui.svg?label=NuGet)](https://www.nuget.org/packages/PJSouzaSoftware.NavigationTrans.Maui/)

## Basic Usage

You can add transitions to your Shell content using XAML:

```xml
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:PJ.NavigationTrans.Maui;assembly=PJ.NavigationTrans.Maui"
x:Class="YourNamespace.YourPage"
local:NavigationTrans.TransitionIn="FadeIn"
local:NavigationTrans.TransitionOut="FadeOut"
local:NavigationTrans.Duration="800">
<!-- Your page content -->
</ContentPage>
```

Adding Transitions in C#

```cs
public partial class YourPage : ContentPage
{
public YourPage()
{
InitializeComponent();

// Set transition properties
NavigationTrans.SetTransitionIn(this, TransitionType.RightIn);
NavigationTrans.SetTransitionOut(this, TransitionType.LeftOut);
NavigationTrans.SetDuration(this, 500);
}
}
```

Available Built-in Transitions
• Default: System default transition
• FadeIn/FadeOut: Fade animation
• LeftIn/LeftOut: Slide from/to left
• RightIn/RightOut: Slide from/to right
• TopIn/TopOut: Slide from/to top
• BottomIn/BottomOut: Slide from/to bottom
• Custom: User-defined custom animation

## Custom Animation

Custom Android Animations
To create custom Android animations, you need to define animation resources and reference them:

```cs
public partial class YourPage : ContentPage
{
public YourPage()
{
InitializeComponent();

// Use custom Android animations by resource ID
NavigationTrans.SetAndroidTransitions(
this,
Resource.Animation.your_enter_animation, // Resource ID for enter animation
Resource.Animation.your_exit_animation, // Resource ID for exit animation
300 // Duration in milliseconds
);
}
}
```

Custom iOS Animations
For iOS, you can define custom UIView animations:

```cs
public partial class YourPage : ContentPage
{
public YourPage()
{
InitializeComponent();

#if IOS
// Define custom iOS animations
NavigationTrans.SetIosTransitions(
this,
// Animation when entering
animationIn: view => {
view.Alpha = 1;
view.Transform = CGAffineTransform.MakeIdentity();
},
// Initial configuration when entering
configurationOn: view => {
view.Alpha = 0;
view.Transform = CGAffineTransform.MakeScale(0.8f, 0.8f);
},
// Animation when exiting
animationOut: view => {
view.Alpha = 0;
view.Transform = CGAffineTransform.MakeScale(1.2f, 1.2f);
},
// Initial configuration when exiting
configurationOut: null,
duration: 400 // Duration in milliseconds
);
#endif
}
}
```


## Support

This project is open source and maintened by one person, so if you need a urgent fix for a bug and don't want to submit it
This project is open source and maintained by one person, so if you need a urgent fix for a bug and don't want to submit it
you can pay for my work using [github sponsor](https://github.com/sponsors/pictos/sponsorships?sponsor=pictos&tier_id=485056&preview=false).

## Demo
Expand Down