Hey everyone!
I got a problem with my custom page renderer which adds the SwipeBack Functionality on all Pages. I need this because the NavigationBar on the respective Pages is disabled but I want to have the SwipeBack Functionality. I found this solution in multiple sources but it is not working as expected.
[assembly: Xamarin.Forms.ExportRenderer(typeof(ContentPage), typeof(ContentPageRenderer))] namespace MyApp { public class ContentPageRenderer : PageRenderer { public ContentPage ContentPageElement => Element as ContentPage; public override void ViewWillAppear(bool animated) { base.ViewDidAppear(animated); if (ViewController.NavigationController != null) { ViewController.NavigationController.InteractivePopGestureRecognizer.Enabled = true; ViewController.NavigationController.InteractivePopGestureRecognizer.Delegate = new UIGestureRecognizerDelegate(); ViewController.NavigationController.InteractivePopGestureRecognizer.AddTarget(this, new ObjCRuntime.Selector(nameof(HandleBackSwipe))); } } [Export(nameof(HandleBackSwipe))] private void HandleBackSwipe() { if (ViewController.NavigationController != null) { ViewController.NavigationController.InteractivePopGestureRecognizer.RemoveTarget(this, new ObjCRuntime.Selector(nameof(HandleBackSwipe))); ContentPageElement.SendBackButtonPressed(); } } }
When swiping back from the page which is my second page in the navigation stack, I get to my root page as expected. But when I carry on swiping back on the root page (it makes no sense to swipe back at the root page, i know, however a user could do it for any reason), the app freezes, meaning i am not able to click any button on the root page.
Has anyone experienced the same issue with a renderer like mine? Thanks in advance!
I just made it work by moving everything in the ViedDidAppear instead of ViewWillAppear.
I also made disabling or enabling of the InteractivePopGestureRecognizer accessible via a field on a ContentPage wich tells me if SiwpeBack is allowed or not. I gave the root page IsSwipeBackAllowed = false. Here is the solution:
[assembly: Xamarin.Forms.ExportRenderer(typeof(ContentPage), typeof(ContentPageRenderer))] namespace MyApp { public class ContentPageRenderer : PageRenderer { public ContentPage ContentPageElement => Element as ContentPage; public override void ViewDidAppear(bool animated) { base.ViewDidAppear(animated); if (ViewController.NavigationController != null && ContentPageElement.IsSwipeBackAllowed == false) { ViewController.NavigationController.InteractivePopGestureRecognizer.Enabled = false; } if (ViewController.NavigationController != null && ContentPageElement.IsSwipeBackAllowed == true) { ViewController.NavigationController.InteractivePopGestureRecognizer.Enabled = true; ViewController.NavigationController.InteractivePopGestureRecognizer.Delegate = new UIGestureRecognizerDelegate(); ViewController.NavigationController.InteractivePopGestureRecognizer.AddTarget(this, new ObjCRuntime.Selector(nameof(HandleBackSwipe))); } } [Export(nameof(HandleBackSwipe))] private void HandleBackSwipe() { if (ViewController.NavigationController != null && ContentPageElement.IsSwipeBackAllowed == true) { ViewController.NavigationController.InteractivePopGestureRecognizer.RemoveTarget(this, new ObjCRuntime.Selector(nameof(HandleBackSwipe))); ContentPageElement.SendBackButtonPressed(); } } } }
Thanks for any help!
Answers
Add a condition to detect if current page is the root viewController in the navigation stack .
Try the following code
Xamarin forums are migrating to a new home on Microsoft Q&A!
We invite you to post new questions in the Xamarin forums’ new home on Microsoft Q&A!
For more information, please refer to this sticky post.
Thank you, I tried your solution but unfortunately this does not work...
In more detail: after I swiped back on the root page, I am able to click on a button which should navigate me to another page, but nothing happens. I did debug my code and it seems like, I get stuck on the await Navigation.PushAsync(nextPage) call. The program never returns from the call. When I swipe back again, meaning swiping from the left edge of the screen to the center of the screen, I see the page (second page, not root page) coming from the right side moving inwards. I think this indicates that the page was there but not shown or something like that. Afterwards, I can click on any button and the application behaves as expected. The only thing is that my navigation stack is messed up meaning the "second page" is there twice. Another guy uploaded a GIF where you can see exactely the same problem. I would be very thankful if someone finds a solution!
Replace the renderer as below
Yes this one is working!!! However the Swipe Gesture isn't like the one before. Do you also have a clue how to combine your solution with the InteractivePopGesureRecognizer in order to have a smooth swipe back functionality? Thank you very much in advance!!!
Try to disable the gesture when reaching root page .
It doesn't work... even if I check for != null. The gesture seems to be disabled before I navigated back to the root page what causes a total freez on the second page.
I just made it work by moving everything in the ViedDidAppear instead of ViewWillAppear.
I also made disabling or enabling of the InteractivePopGestureRecognizer accessible via a field on a ContentPage wich tells me if SiwpeBack is allowed or not. I gave the root page IsSwipeBackAllowed = false. Here is the solution:
Thanks for any help!