I have a UIPagevViewController
which is used to show 4 ViewControllers
. I want the dots background color to change based on the view's background color I am currently into. While I have managed to get the same background color for both the dots and the first page I fail to do so for every other one. In other words I want to dynamically change the dots background based on the view that is shown
import UIKit
class PageViewController: UIPageViewController,UIPageViewControllerDelegate, UIPageViewControllerDataSource {
//my 4 viewControllers used in the UIPageViewController
fileprivate lazy var pages : [UIViewController] = {
return [
self.getViewController(withIdentifier: "firstViewControllerID"),
self.getViewController(withIdentifier: "secondViewControllerID"),
self.getViewController(withIdentifier: "thirdViewControllerID"),
self.getViewController(withIdentifier: "differentViewController")
]
}()
//function that accesses those view controllers used above from the storyboard
fileprivate func getViewController(withIdentifier identifier: String) -> UIViewController
{
return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: identifier)
}
/* needed function for the UIPageViewControllerDelegate, UIPageViewControllerDataSource protocols
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
//Some Code. Unnecessary for the question
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController?
{
//Some Code. Unnecessary for the question
}
*/
//function where the dots colours are set
private func setupPageControl() {
let appearance = UIPageControl.appearance(whenContainedInInstancesOf: [UIPageViewController.self])
appearance.pageIndicatorTintColor = UIColor.gray
appearance.currentPageIndicatorTintColor = UIColor.red
appearance.backgroundColor = pages[appearance.currentPage].view.backgroundColor
}
func presentationCount(for pageViewController: UIPageViewController) -> Int {
setupPageControl()
return pages.count
}
func presentationIndex(for pageViewController: UIPageViewController) -> Int {
return 0
}
override func viewDidLoad() {
super.viewDidLoad()
self.dataSource = self
delegate = self
if let firstVC = pages.first {
setViewControllers([firstVC], direction: .forward, animated: true, completion: nil)
setupPageControl()
}
}
}
First image->first page. Second image->second page. Look at the color of the dots background
Unfortunately you have no direct access to the page control built into a UIPageViewController. Therefore you have to use the appearance proxy in order to change its appearance (as you are already doing). But the appearance proxy only affects future instances of a thing; once the page control is already present, therefore, setting the appearance proxy will have no affect (as you have discovered).
Therefore the simplest solution is to give up on the page control built into the UIPageViewController and just use your own UIPageControl whose dots you can change directly. You will have to coordinate it with the page view controller but that is not difficult.
Another possibility is to try to get direct access to the UIPageViewController's UIPageControl. That's fragile because there is no official access, but that technique has been discussed here, as for example in this answer.