ios - tutorial - uipageviewcontroller swift 4
Índice de la página actual de PageViewController en Swift (7)
Quiero obtener el índice actual de un controlador de visualización de página, no sé cómo obtengo el índice de páginas visibles.
func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool,previousViewControllers: [UIViewController],transitionCompleted completed: Bool)
{
// How to get it?
}
Cree un método dentro de, por ejemplo, clase -> WalkthroughPageViewController), de manera que:
/* The method takes in a page index and creates the next content view controller. If the controller can
be created, we call the built-in setViewControllers method and navigate to the next view controller.*/
func forward(index: Int) {
if let nextViewController = contentViewController(at: index + 1) {
setViewControllers([nextViewController], direction: .forward, animated: true, completion: nil)
}
}
Y en la clase que controla dicho UIPageController, que será una vista de controlador (clase -> WalkthroughContentViewController) y que contiene un botón siguiente que pasa a la página siguiente y actualiza la propiedad "pageControl.currentPage" (que en sí es el UIpageControl), implementos:
class WalkthroughContentViewController: UIViewController {
@IBOutlet var headingLabel: UILabel!
@IBOutlet var contentLabel: UILabel!
@IBOutlet var forwardButton: UIButton!
@IBOutlet var pageControl: UIPageControl!
@IBOutlet var contentImageView: UIImageView!
var index = 0
var heading = ""
var content = ""
var imageFile = ""
override func viewDidLoad() {
super.viewDidLoad()
headingLabel.text = heading
contentLabel.text = content
contentImageView.image = UIImage(named: imageFile)
// Update the ''currentPage'' property of the page control.
pageControl.currentPage = index
if case 0...1 = index {
forwardButton.setTitle("NEXT", for : .normal)
} else if case 2 = index {
forwardButton.setTitle("DONE", for : .normal)
}
}
// MARK: - Actions
@IBAction func nextButtonTapped(sender: UIButton) {
switch index {
case 0...1: /* Get the parent controller & call to the "forward" method from the ''WalkthroughPageViewController''. */
let pageViewController = parent as! WalkthroughPageViewController
pageViewController.forward(index: index)
case 2: /* Dismiss the page view controller and show the main screen of the app*/
dismiss(animated: true, completion: nil)
default: break
}
}
}
Intentalo..
func pageViewController(pageViewController: UIPageViewController,didFinishAnimating finished: Bool,previousViewControllers: [UIViewController],transitionCompleted completed: Bool){
guard completed else { return }
self.pageControl.currentPage = pageViewController.viewControllers!.first!.view.tag
}
No te olvides de configurar delegado pageviewcontroller.
func createPageViewController() {
// Create page view controller
pageViewController = storyboard?.instantiateViewController(withIdentifier: "PageViewController") as? UIPageViewController
pageViewController?.delegate = self
pageViewController?.dataSource = self
let startingViewController: ChildViewController = viewControllerAtIndex(index: 0)!
let viewControllers: Array = [startingViewController]
pageViewController?.setViewControllers(viewControllers, direction: .forward, animated: true, completion: nil)
self.addChildViewController(pageViewController!)
self.view.frame = CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height: self.view.bounds.size.height)
self.view.addSubview((pageViewController?.view)!)
self.pageViewController?.didMove(toParentViewController: self)
}
func viewControllerAtIndex(index: Int) -> ChildViewController? {
// return nil here, if there won''t be any page in pageviewcontroller
// Create a new view controller and pass suitable data.
let pageContentViewController: ChildViewController = storyboard?.instantiateViewController(withIdentifier: "ChildViewController") as! ChildViewController
pageContentViewController.pageIndex = index
return pageContentViewController
}
//Also add viewControllerAfter and viewControllerBefore methods
func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
self.pendingIndex = (pendingViewControllers.first as! ChildViewController).pageIndex
}
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if completed {
self.currentIndex = self.pendingIndex!
//Perform your task here
}
}
Puede usar didFinishAnimating y establecer etiquetas para ver los controladores. prueba esto
func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool)
{
if (!completed)
{
return
}
self.pageControl.currentPageIndex = pageViewController.viewControllers!.first!.view.tag //Page Index
}
Puedes usar el siguiente método:
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
guard
completed,
let viewControllerIndex = tutorialViews.index(of: pageViewController.viewControllers!.first!) else
return
}
self.currentIndex = viewControllerIndex
}
Donde tutorialViews es una matriz de páginas (ViewControllers).
E inicialice currentIndex de esa manera:
var currentIndex = 0 {
didSet {
self.updateContentForPage(withIndex: currentIndex)
}
}
En swift 3
Reemplace la función didFinishAnimating de UIPageViewControllerDelegate de esta manera:
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if completed {
if let currentViewController = pageViewController.viewControllers![0] as? WalkthroughContentViewController {
pageControl.currentPage = currentViewController.index
}
}
}
donde WalkthroughContentViewController es el UIViewController presentado por UIPageViewController
Recuerde mantener una variable de índice dentro del WalkthroughContentViewController. Además, en el conjunto de métodos viewDidLoad:
delegate = self
Swift 3: ejemplo programático completo de PageViewController para obtener / establecer el índice de la página actual sin etiquetado de vista:
enum PageViewType:String {
case green = "greenView"
case blue = "blueView"
case red = "redView"
}
class MyPageViewController: UIPageViewController {
private (set) lazy var orderedViewControllers:[UIViewController] = {
return [self.newPageView(.green),
self.newPageView(.blue),
self.newPageView(.red)
]
}
var currentIndex:Int {
get {
return orderedViewControllers.index(of: self.viewControllers!.first!)!
}
set {
guard newValue >= 0,
newValue < orderedViewControllers.count else {
return
}
let vc = orderedViewControllers[newValue]
let direction:UIPageViewControllerNavigationDirection = newValue > currentIndex ? .forward : .reverse
self.setViewControllers([vc], direction: direction, animated: true, completion: nil)
}
}
override func viewDidLoad() {
super.viewDidLoad()
dataSource = self
if let firstViewController = orderedViewControllers.first {
setViewControllers([firstViewController],
direction: .forward,
animated: true,
completion: nil)
}
}
private func newPageView(_ viewType:PageViewType) -> UIViewController {
let vc = self.storyboard?.instantiateViewController(withIdentifier: viewType.rawValue)
return vc
}
}
Implementación UIPageViewController DataSource:
extension MyPageViewController:UIPageViewControllerDataSource {
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let previousIndex = currentIndex - 1
guard previousIndex >= 0 else {
return nil
}
guard orderedViewControllers.count > previousIndex else {
return nil
}
return orderedViewControllers[previousIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let nextIndex = currentIndex + 1
guard orderedViewControllers.count != nextIndex else {
return nil
}
guard orderedViewControllers.count > nextIndex else {
return nil
}
return orderedViewControllers[nextIndex]
}
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return orderedViewControllers.count
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
return currentIndex
}
}