Использование UIPageViewController с быстрыми и множественными контрольными контроллерами

Я пытаюсь использовать UIPageViewController в приложении Swift с несколькими контроллерами представлений. У меня есть 2 контроллера вида на моем раскадровке (firstViewController и secondViewController), которые встроены в свои собственные контроллеры навигации. У них есть идентификаторы раскадровки "firstViewController" и "secondViewController". У меня также есть контроллер просмотра страниц на моей раскадровке с контроллером identifierPageView и установите навигацию в горизонтальном и переходном стиле для прокрутки в инспекторе атрибутов. firstViewController - это контроллер корневого представления приложения

Я хочу, чтобы firstViewController была первой страницей контроллера просмотра страницы, поэтому я написал свой класс следующим образом:

import Foundation
import UIKit

class FirsttViewController: UITableViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate  {

    override func viewDidLoad() {

        let pageViewController: PageViewController = self.storyboard.instantiateViewControllerWithIdentifier("PageViewController") as PageViewController

        pageViewController.delegate = self

        var viewControllers: [UIViewController] = [self]

        pageViewController.setViewControllers(viewControllers, direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)
        pageViewController.view.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height)

        self.addChildViewController(pageViewController)
        self.view.addSubview(pageViewController.view)
        pageViewController.didMoveToParentViewController(self)


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


        let secondViewController: SecondViewController = self.storyboard.instantiateViewControllerWithIdentifier("SecondViewController") as SecondViewController


        return secondViewController
    }

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

        return nil
    }

    func presentationCountForPageViewController(pageViewController: UIPageViewController!) -> Int {
        return 2
    }

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

файл для secondViewController выглядит следующим образом:

import Foundation
import UIKit

class SecondViewController: UITableViewController, UIPageViewControllerDataSource {

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

        return nil
    }

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

        let firstViewController: FirstViewController = self.storyboard.instantiateViewControllerWithIdentifier("FirstViewController") as FirstViewController
        return firstViewController
    }

}

Однако, когда я запускаю свое приложение, у него нет контроллера просмотра страниц. Он просто показывает firstViewController и что он. Нет точек, нет страниц и т.д. Кто-нибудь знает, что случилось? Я нашел несколько учебников по Objective-C, но все они покрывают с помощью одного контроллера вида для всех страниц и имеют контроллер корневого представления, который не является страницей в pageView, поэтому они не слишком помогают. Я надеялся, что это будет похоже на использование tabBarController, где вы просто щелкаете мышью и перетаскиваете их в контроллеры представлений, но это не так, к сожалению. как я сказал, что я не работал с одним из них раньше, поэтому я как бы потерял.

обновление:

после предложения iiFreeman, я подклассифицировал UIPageViewController и сделал его корнем в моем файле раскадровки. ниже подкласс

import Foundation
import UIKit
class PageViewController: UIPageViewController {

    override func viewDidLoad() {

        let startingViewController = self.storyboard.instantiateViewControllerWithIdentifier("FirstViewController") as FirstViewController

        self.dataSource = startingViewController
        var viewControllers: [UIViewController] = [startingViewController]

        self.setViewControllers(viewControllers, direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)



    }

}

Однако теперь приложение просто зависает на черном экране, а в конечном итоге Xcode теряет соединение с симулятором. Я не совсем уверен, что.

Ответы

Ответ 1

Хорошо, я понял. так как мне нужно, чтобы контроллер просмотра страниц был корневым и обрабатывал все, я подклассифицировал UIPageViewController, поскольку iiFreeman предложил и соответствовал протоколам делегатов и источников данных. Затем я настроил контроллер в viewDidLoad и реализовал методы делегирования и источника данных. Я добавил хранилище свойств массива идентификаторов раскадровки, а также один, чтобы отслеживать текущий индекс этого массива. Я также добавил вспомогательный метод для возврата правильного контроллера представления с учетом индекса. Мне не нужно было ничего в других моих подклассах tableView, так как мой контроллер просмотра страниц обрабатывал все. Одна вещь, которую я понял, так это то, что мой tableViewController был встроен в контроллеры навигации, мне действительно нужен диспетчер просмотра страниц, чтобы отображать контроллеры навигации, а не контроллеры tableView. ниже моя реализация:

import Foundation
import UIKit

class PageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {

    var index = 0
    var identifiers: NSArray = ["FirstNavigationController", "SecondNavigationController"]
    override func viewDidLoad() {

        self.dataSource = self
        self.delegate = self

        let startingViewController = self.viewControllerAtIndex(self.index)
        let viewControllers: NSArray = [startingViewController]
        self.setViewControllers(viewControllers, direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)



    }

    func viewControllerAtIndex(index: Int) -> UINavigationController! {

        //first view controller = firstViewControllers navigation controller
        if index == 0 {

            return self.storyboard.instantiateViewControllerWithIdentifier("FirstNavigationController") as UINavigationController

        }

        //second view controller = secondViewController navigation controller
        if index == 1 {

            return self.storyboard.instantiateViewControllerWithIdentifier("SecondNavigationController") as UINavigationController
        }

        return nil
    }
    func pageViewController(pageViewController: UIPageViewController!, viewControllerAfterViewController viewController: UIViewController!) -> UIViewController! {

        let identifier = viewController.restorationIdentifier
        let index = self.identifiers.indexOfObject(identifier)

        //if the index is the end of the array, return nil since we dont want a view controller after the last one
        if index == identifiers.count - 1 {

            return nil
        }

        //increment the index to get the viewController after the current index
        self.index = self.index + 1
        return self.viewControllerAtIndex(self.index)

    }

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

        let identifier = viewController.restorationIdentifier
        let index = self.identifiers.indexOfObject(identifier)

        //if the index is 0, return nil since we dont want a view controller before the first one
        if index == 0 {

            return nil
        }

        //decrement the index to get the viewController before the current one
        self.index = self.index - 1
        return self.viewControllerAtIndex(self.index)

    }


    func presentationCountForPageViewController(pageViewController: UIPageViewController!) -> Int {
        return self.identifiers.count
    }

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

}

этот пост очень помог мне

Ответ 2

уверен, что FirstViewController - контроллер начального представления в вашем раскадровке

добавить пользовательский подкласс UIPageViewController в свою раскадровку, пометить его как начальную и сделать всю работу внутри, создать экземпляр элементов контроллера страницы с помощью идентификаторов storyboardID в вашем подклассе UIPageViewController, сделать то же самое только внутри другого класса

Ответ 3

Помните, что этот код будет работать только с двумя ViewController. Если вы планируете использовать больше, вам нужно изменить строку:

self.index = self.index + 1

Найдено при до и после вызова, чтобы:

self.index = index + 1

Чтобы вызвать текущий индекс ViewController.