Search code examples
iosswiftxcodecocoa-touchuipageviewcontroller

Changes on navigation bar in UIPageViewController not working properly


My code :

@IBOutlet weak var pageControllerView: UIView!
@IBOutlet weak var pageController: UIPageControl!
// The pages it contains
var pages =  [UIViewController]()

// The UIPageViewController
var pageContainer: UIPageViewController!

In viewDodLoad()

 // Setup the pages
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    page1 = storyboard.instantiateViewController(withIdentifier: "DVC") as? DashboardViewController1
    page2 = storyboard.instantiateViewController(withIdentifier: "MDVC") as? DashboardViewController2
    pages.append(page1)
    pages.append(page2)

    // Create the page container
    pageContainer = UIPageViewController(transitionStyle: .pageCurl, navigationOrientation: .horizontal, options: nil)
    pageContainer.delegate = self
    pageContainer.dataSource = self

    self.pageContainer.setViewControllers([self.page1], direction: UIPageViewController.NavigationDirection.forward, animated: false, completion: nil)

    DispatchQueue.main.async {
        self.firstLabel.text = "Dashboard1"
        self.filterBarButton.isEnabled = true
        self.filterBarButton.tintColor = .white
    }

    // Add it to the view
    pageControllerView.addSubview(pageContainer.view)

    // set the frame of the pageContainer view to match its superview (the pageControllerView view)
    pageContainer.view.frame =  pageControllerView.bounds
    // let it resize if needed (such as device rotation)
    pageContainer.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]

    // Configure our custom pageControl
    // view.bringSubviewToFront(pageController)
    pageController.numberOfPages = pages.count
    pageController.currentPage = 0



// MARK: - UIPageViewController delegates
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
    let currentIndex = pages.firstIndex(of:viewController)!
    print(currentIndex) //Prints 0
    if currentIndex == 0 {
        DispatchQueue.main.async {
            self.firstLabel.text = "Dashboard1"
            self.filterBarButton.isEnabled = true
            self.filterBarButton.tintColor = .white
        }
        return nil
    }
    let previousIndex = abs((currentIndex - 1) % pages.count)

    return pages[previousIndex]
}

func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
    let currentIndex = pages.firstIndex(of:viewController)!
    print(currentIndex) //Print 1
    if currentIndex == 1 {
        DispatchQueue.main.async {
        self.firstLabel.text = "Dashboard2"
        self.filterBarButton.isEnabled = false
        self.filterBarButton.tintColor = .clear
        }
        return nil
    }
    let nextIndex = abs((currentIndex + 1) % pages.count)
    return pages[nextIndex]
}

func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
    pendingIndex = pages.firstIndex(of:pendingViewControllers.first!)
}

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
    if completed {
        currentIndex = pendingIndex
        if let index = currentIndex {
            pageController.currentPage = index
        }
    }
}

Here i want to change the navigation label title and barButton status when move pages. It's some times working some times not working. When we drag page either left or right once again after page displaying now its changing.


Solution

  • implement:

    func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
        if completed {
            currentIndex = pendingIndex
            print(currentIndex)
            if currentIndex == 0 {
                DispatchQueue.main.async {
                    self.firstLabel.text = "Dashboard1"
                    self.filterBarButton.isEnabled = true
                    self.filterBarButton.tintColor = .white
                }
            }
            if currentIndex == 1 {
                DispatchQueue.main.async {
                    self.firstLabel.text = "Dashboard2"
                    self.filterBarButton.isEnabled = false
                    self.filterBarButton.tintColor = .clear
                }
            }
            if let index = currentIndex {
                pageController.currentPage = index
            }
        }
    }
    

    And change navbar there not when you load view