Cesare Cesare - 6 months ago 29
Swift Question

How do I implement transitionCompleted of the UIPageViewController delegate in Swift?

As you can see, there are two

UIViewControllers
(one of them is called
ProView
and acts as a container for the other
UIViewController
and one
UIPageViewController
.

gif1

import UIKit

class ProView: UIViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {

var pageViewController: UIPageViewController?

let characterImages = ["character1", "character2"]

override func viewDidLoad() {
super.viewDidLoad()
createPageViewController()
setupPageControl()
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}

func pageViewController(pageViewController: UIPageViewController,
viewControllerAfterViewController ProView: UIViewController) -> UIViewController? {

let itemController = ProView as PageItemController

if itemController.itemIndex+1 < characterImages.count {
return getItemController(itemController.itemIndex+1)
}

return nil
}

func pageViewController(pageViewController: UIPageViewController,
viewControllerBeforeViewController ProView: UIViewController) -> UIViewController? {

let itemController = ProView as PageItemController

if itemController.itemIndex > 0 {
return getItemController(itemController.itemIndex-1)
}

return nil
}

private func getItemController(itemIndex: Int) -> PageItemController? {

if itemIndex < characterImages.count {
let pageItemController = self.storyboard!.instantiateViewControllerWithIdentifier("ItemController") as PageItemController
pageItemController.itemIndex = itemIndex
pageItemController.imageName = characterImages[itemIndex]
return pageItemController
}

return nil
}

func createPageViewController() {

let pageController = self.storyboard!.instantiateViewControllerWithIdentifier("PageController") as UIPageViewController
pageController.dataSource = self

if characterImages.count > 0 {
let firstController = getItemController(0)!
let startingViewControllers: NSArray = [firstController]
pageController.setViewControllers(startingViewControllers, direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)
}

pageViewController = pageController
addChildViewController(pageViewController!)
self.view.addSubview(pageViewController!.view)
pageViewController?.didMoveToParentViewController(self)
}

func setupPageControl() {
let appearance = UIPageControl.appearance()
appearance.pageIndicatorTintColor = UIColor.grayColor()
appearance.currentPageIndicatorTintColor = UIColor.whiteColor()
}

func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return characterImages.count
}

func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
return 0
}

}

class PageItemController: UIViewController {

@IBOutlet weak var imageCharacterChoose: UIImageView!

var itemIndex: Int = 0
var imageName: String = "" {
didSet {

if let imageView = imageCharacterChoose {imageCharacterChoose.image = UIImage(named: imageName)
}

}
}

override func viewDidLoad() {
super.viewDidLoad()

imageCharacterChoose!.image = UIImage(named: imageName)

}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}

}


I would like to know if the user correctly swipes from one view to another. For that matter, I need the method
transitionCompleted
to work:

func pageViewController(ProView: UIPageViewController,
didFinishAnimating finished: Bool,
previousViewControllers pageViewController: [AnyObject],
transitionCompleted completed: Bool)
{
// If the page did not turn
if (!completed)
{
// You do nothing because whatever page you thought
// the book was on before the gesture started is still the correct page
println("The page number did not change.")
return;
}

// This is where you would know the page number changed and handle it appropriately
println("The page number has changed.")
}


The problem is that doesn't work (the console output doesn't print anything) because the parameters aren't correct probably. According to Apple Reference,

pageViewController The page view controller.
previousViewControllers The view controllers prior to the transition.

I therefore changed the parameters using "ProView" and "pageViewController" but that doesn't seem to work. What are the correct parameters according to the code for the
transitionCompleted
method?
Do I need to declare something?

Answer

The problem is that pageViewController:didFinishAnimating:... is a delegate method, but this class is not the page view controller's delegate.

You have this line:

pageController.dataSource = self

So you are setting the dataSource. But you never set the delegate. Set it:

pageController.delegate = self