Swift: Type 'ViewController' does not conform to protocol 'UIPageViewControllerDataSource'

18,718

It's because the UIPageViewControllerDataSource protocol has updated method signatures - you're using:

func pageViewController(pageViewController: UIPageViewController!, viewControllerBeforeViewController viewController: UIViewController!) -> UIViewController!

func pageViewController(pageViewController: UIPageViewController!, viewControllerAfterViewController viewController: UIViewController!) -> UIViewController!

but now they are:

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

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

When you're in doubt on a non conforming protocol, a Command+Click on the protocol name will bring you to the protocol declaration, where you can see if you are implementing its interface correctly

Share:
18,718
Illya Lapko
Author by

Illya Lapko

Updated on June 12, 2022

Comments

  • Illya Lapko
    Illya Lapko almost 2 years

    I'm using Xcode 6 GM. I'm attempting to implement this page view controller tutorial but in Swift instead of Objective-C but it's not working as expected.

    I've actually managed to find a git repo where someone else is doing the same, but after cloning their project and opening it in Xcode, it has the same errors I'm getting. I've managed to resolve most of them except for the protocol conformance issue when implementing the UIPageViewControllerDataSource protocol.

    To be honest, I don't completely understand the usage of ? and ! in Swift and if that's causing my issue. Removing the ! from the variables in the implementation of the protocol's methods causes other errors.

    Could someone please assist?

    class ViewController: UIViewController, UIPageViewControllerDataSource {
    
    var pageViewController : UIPageViewController?
    var pageTitles = ["Over 200 Tips and Tricks", "Discover Hidden Features", "Bookmark Favorite Tip", "FreeRegular Update"]
    var pageImages = ["page1.png", "page2.png", "page3.png", "page4.png"]
    var currentIndex = 0
    
    @IBAction func startWalkthrough(sender: UIButton) {
        var startingViewController : PageContentViewController = self.viewControllerAtIndex(0)!
        var viewControllers : NSArray = [startingViewController]
        self.pageViewController!.setViewControllers(viewControllers, direction: .Forward, animated: false, completion: nil)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        //Create page view controller
        self.pageViewController = UIPageViewController(transitionStyle: .Scroll, navigationOrientation: .Horizontal, options: nil)
        self.pageViewController!.dataSource = self
    
        let startingViewController : PageContentViewController = self.viewControllerAtIndex(0)!
        let viewControllers: NSArray = [startingViewController]
        self.pageViewController!.setViewControllers(viewControllers, direction: .Forward, animated: false, completion: nil)
    
        // Change the size of page view controller
        self.pageViewController!.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - 30);
    
        self.addChildViewController(self.pageViewController!)
        self.view.addSubview(self.pageViewController!.view)
        self.pageViewController!.didMoveToParentViewController(self)
    
    }
    
    func pageViewController(pageViewController: UIPageViewController!,
        viewControllerBeforeViewController viewController: UIViewController!) -> UIViewController! {
    
            var index = (viewController as PageContentViewController).pageIndex
    
            if index == 0 || index == NSNotFound {
                return nil
            }
    
            index!--
    
            println("Decreasing Index: \(index)")
    
            return self.viewControllerAtIndex(index!)
    }
    
    func pageViewController(pageViewController: UIPageViewController!,
        viewControllerAfterViewController viewController: UIViewController!) -> UIViewController! {
    
            var index = (viewController as PageContentViewController).pageIndex
    
            if index == NSNotFound {
                return nil
            }
    
            index!++
    
            println("Increasing Index: \(index)")
    
            if index == self.pageTitles.count {
                return nil;
            }
            return self.viewControllerAtIndex(index!);
    }
    
    func viewControllerAtIndex(index : Int) -> PageContentViewController? {
    
        if self.pageTitles.count == 0 || index >= self.pageTitles.count {
            return nil;
        }
    
        // Create a new view controller and pass suitable data.
        let pageContentViewController = self.storyboard!.instantiateViewControllerWithIdentifier("PageContentViewController") as PageContentViewController
        pageContentViewController.imageFile = self.pageImages[index]
        pageContentViewController.titleText = self.pageTitles[index]
        pageContentViewController.pageIndex = index
    
        return pageContentViewController;
    }
    
    func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
        return self.pageTitles.count
    }
    
    func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
        return 0
    }
    }
    
  • Illya Lapko
    Illya Lapko over 9 years
    Thanks a ton Antonio! As soon as I fixed that, the app works as expected. And thanks for the tip, I should have known that but I guess I was just ignoring the question and exclamation marks. Coming from a Java/Eclipse background, I'm used to the IDE automatically including an interface's methods when implementing that interface in a custom class.
  • pekpon
    pekpon about 9 years
    Awesome! The Cmd+Click trick work it for me with other protocol. Thanks!