Использование 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
.