I am having an issue with my UIPageViewControllerDelegate methods. It doesn't track the pages properly when the user swipes in one direction, doesn't complete that swipe and swipes back to the first page.
Ex.
Here is how I implement these methods:
public Action<int> PageSwiped { get; set; }
public override void WillTransition(
UIPageViewController pageViewController, UIViewController[] pendingViewControllers)
{
_currentController = pendingViewControllers[0] as AssetViewController;
}
public override void DidFinishAnimating(
UIPageViewController pageViewController, bool finished,
UIViewController[] previousViewControllers, bool completed)
{
if (completed)
{
PageSwiped(_currentController.CurrentMedia.Content.ProofIndex);
}
}
The 'PageSwiped' action is fired to allow other classes to know that the page was swiped.
I have tried replacing:
if (completed)
with
if (finished)
and had the exact same issue.
So there has to be something I'm doing wrong in these two methods, any suggestions?
When using UIPageViewController
you don't need to implement those methods to navigate between pages (ViewControllers).
You should either implement the IUIPageViewControllerDataSource
interface right in the UIPageViewController
and set your datasource as this
or subclass UIPageViewControllerDataSource
and set the datasource as the object created.
In either case you will be implementing/overriding these two methods
UIViewController IUIPageViewControllerDataSource.GetNextViewController(UIPageViewController pageViewController, UIViewController referenceViewController)
{
}
UIViewController IUIPageViewControllerDataSource.GetPreviousViewController(UIPageViewController pageViewController, UIViewController referenceViewController)
{
}
These are the methods which returns the Page (UIViewController) that will be displayed.
Here you just find what it's the index of the control currently on screen and get the next or previous and return that item from the collection.
Getting the Next ViewController:
UIViewController IUIPageViewControllerDataSource.GetNextViewController(UIPageViewController pageViewController, UIViewController referenceViewController)
{
var index = MyViewControllers.IndexOf(referenceViewController);
var nextIndex = index + 1;
return MyViewControllers.ElementAtOrDefault(nextIndex);
}
Getting the previous ViewController:
UIViewController IUIPageViewControllerDataSource.GetPreviousViewController(UIPageViewController pageViewController, UIViewController referenceViewController)
{
var index = MyViewControllers.IndexOf(referenceViewController);
var previousIndex = index - 1;
return MyViewControllers.ElementAtOrDefault(previousIndex);
}
The difference is that these methods are called only when the transition has successfully completed.
Here's the full code:
public partial class MyPageViewController : UIPageViewController, IUIPageViewControllerDataSource
{
List<UIViewController> MyViewControllers = new List<UIViewController>();
public MyPageViewController (IntPtr handle) : base (handle)
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
var redViewController = UIStoryboard.FromName("Main", null).InstantiateViewController("redViewController");
var greenViewController = UIStoryboard.FromName("Main", null).InstantiateViewController("greenViewController");
var blueViewController = UIStoryboard.FromName("Main", null).InstantiateViewController("blueViewController");
MyViewControllers.Add(redViewController);
MyViewControllers.Add(greenViewController);
MyViewControllers.Add(blueViewController);
DataSource = this;
SetViewControllers(new UIViewController[] { MyViewControllers.First() }, UIPageViewControllerNavigationDirection.Forward, true, null);
}
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
}
UIViewController IUIPageViewControllerDataSource.GetNextViewController(UIPageViewController pageViewController, UIViewController referenceViewController)
{
var index = MyViewControllers.IndexOf(referenceViewController);
var nextIndex = index + 1;
return MyViewControllers.ElementAtOrDefault(nextIndex);
}
UIViewController IUIPageViewControllerDataSource.GetPreviousViewController(UIPageViewController pageViewController, UIViewController referenceViewController)
{
var index = MyViewControllers.IndexOf(referenceViewController);
var previousIndex = index - 1;
return MyViewControllers.ElementAtOrDefault(previousIndex);
}
}
Hope this helps!