The following code responds to a user swipe gesture with a tab change animated with a cross dissolve. It creates a custom renderer for TabbedPage
that adds an iOS UISwipeGestureRecognizer
for each direction.
The gesture recognizer works simultaneously with other gestures on the page (otherwise, page gestures such as scrolling will prevent the swipe gesture from working unless the gesture is perfectly horizontal), but not itself (otherwise, one swipe will move across multiple pages).
[assembly: ExportRenderer(typeof(TabbedPage), typeof(SwipeTabbedRenderer))]
class SwipeTabbedRenderer : TabbedRenderer
{
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
NativeView.AddGestureRecognizer(new UISwipeGestureRecognizer(() => SelectNextTab(1)) { Direction = UISwipeGestureRecognizerDirection.Left, ShouldRecognizeSimultaneously = ShouldRecognizeSimultaneously });
NativeView.AddGestureRecognizer(new UISwipeGestureRecognizer(() => SelectNextTab(-1)) { Direction = UISwipeGestureRecognizerDirection.Right, ShouldRecognizeSimultaneously = ShouldRecognizeSimultaneously });
}
void SelectNextTab(int direction)
{
int nextIndex = TabbedPage.GetIndex(Tabbed.CurrentPage) + direction;
if (nextIndex < 0 || nextIndex >= Tabbed.Children.Count) return;
var nextPage = Tabbed.Children[nextIndex];
UIView.Transition(Platform.GetRenderer(Tabbed.CurrentPage).NativeView, Platform.GetRenderer(nextPage).NativeView, 0.15, UIViewAnimationOptions.TransitionCrossDissolve, null);
Tabbed.CurrentPage = nextPage;
}
static bool ShouldRecognizeSimultaneously(UIGestureRecognizer gestureRecognizer, UIGestureRecognizer otherGestureRecognizer) => gestureRecognizer != otherGestureRecognizer;
}
Opportunity for improvement: A slide gesture would be better than the cross dissolve, but when I tried to use CATransition to create one, the initial state of the animation was a blank page, rather than the page for the starting tab. This caused the animation to feel slightly jarring.