I can't update next page in my PageViewController.
I add the required number of controllers, but the pageController.setViewControllers([controllers[0]], direction: .forward, animated: false)
method leaves us with one.
I have information for each next controller taken from the viewModel and updated when the currentIndex counter changes
In the viewControllerBefore and viewControllerAfter methods, I initialize my view controller and increase or decrease currentIndex when scrolling forward or backward
After that, the didSet in the view controller works for me and the update takes place.
But, in the end, instead of 8 controllers, I only see 2.
PageViewController
class PageViewController: UIViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {
let viewModel: GeneralViewModel
let locationViewModel: LocationViewModel
let realm = try! Realm()
var pageControl = UIPageControl.appearance()
var pageController: UIPageViewController!
var controllers = [UIViewController]()
var pendingIndex = 0
init(viewModel: GeneralViewModel, locationViewModel: LocationViewModel) {
self.viewModel = viewModel
self.locationViewModel = locationViewModel
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
pageController = UIPageViewController(transitionStyle: .scroll,
navigationOrientation: .horizontal,
options: nil)
pageController.delegate = self
pageController.dataSource = self
addChild(pageController)
view.addSubview(pageController.view)
let views = ["pageController": pageController.view] as [String: AnyObject]
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[pageController]|", options: [], metrics: nil, views: views))
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[pageController]|", options: [], metrics: nil, views: views))
for _ in realm.objects(Cities.self) {
let mainScreenViewController = MainScrenenViewController(viewModel: self.viewModel, locationViewModel: self.locationViewModel)
self.controllers.append(mainScreenViewController)
}
pageController.setViewControllers([controllers[0]], direction: .forward, animated: false)
setupPageControl()
}
func setupPageControl() {
let realmCities = realm.objects(Cities.self)
pageControl = UIPageControl(frame: CGRect(x: 0,y: 100,width: UIScreen.main.bounds.width,height: 50))
pageControl.numberOfPages = realmCities.count
pageControl.tintColor = UIColor.lightGray
pageControl.pageIndicatorTintColor = UIColor.lightGray
pageControl.currentPageIndicatorTintColor = UIColor.black
pageControl.backgroundColor = UIColor.clear
view.addSubview(pageControl)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
if let index = controllers.firstIndex(of: viewController) {
if index > 0 {
let mainScreenViewController = MainScrenenViewController(viewModel: self.viewModel, locationViewModel: self.locationViewModel)
mainScreenViewController.currentIndex -= 1
controllers.append(mainScreenViewController)
return controllers[index - 1]
} else {
return nil
}
}
return nil
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
if let index = controllers.firstIndex(of: viewController) {
if index < controllers.count - 1 {
let mainScreenViewController = MainScrenenViewController(viewModel: self.viewModel, locationViewModel: self.locationViewModel)
mainScreenViewController.currentIndex += 1
controllers.append(mainScreenViewController)
return controllers[index + 1]
} else {
return nil
}
}
return nil
}
MainScreenViewController
class MainScrenenViewController: UIViewController, ChangeWeatherDelegate {
let viewModel: GeneralViewModel
let locationViewModel: LocationViewModel
var currentIndex = 0 {
didSet {
mainCollectionView.reloadData()
todayCollectionView.reloadData()
weekCollectionView.reloadData()
}
}
//MARK: -Realm
let realm = try! Realm()
In viewDidLoad()
in PageViewController
, you are doing this:
for _ in realm.objects(Cities.self) {
let mainScreenViewController = MainScrenenViewController(viewModel: self.viewModel, locationViewModel: self.locationViewModel)
self.controllers.append(mainScreenViewController)
}
so, you've created an array of 8 MainScreenViewController
objects.
However, you haven't set .currentIndex
on them, so they currently are all currentIndex = 0
.
Then, in viewControllerBefore
and viewControllerAfter
, instead of getting the already created view controller from your controllers
array, you are *creating another instance of MainScreenViewController
and setting its .currentIndex
to either -= 1
or += 1
... but then you're appending it to controllers
.
Your code then returns a controller at index - 1
or index + 1
from the controllers array.
It may help if you start a bit simpler... get your UIPageViewController
working... and then add in the code for your view and location models.
Here's a quick example - based on your code - that adds a centered label. showing the "index" of each page:
class MainScrenenViewController: UIViewController {
var currentIndex: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .yellow
let label = UILabel()
label.text = "\(currentIndex)"
label.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(label)
label.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
label.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
}
}
class PageViewController: UIViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {
var pageControl = UIPageControl.appearance()
var pageController: UIPageViewController!
var controllers = [UIViewController]()
override func viewDidLoad() {
super.viewDidLoad()
pageController = UIPageViewController(transitionStyle: .scroll,
navigationOrientation: .horizontal,
options: nil)
pageController.delegate = self
pageController.dataSource = self
addChild(pageController)
view.addSubview(pageController.view)
pageController.didMove(toParent: self)
let views = ["pageController": pageController.view] as [String: AnyObject]
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[pageController]|", options: [], metrics: nil, views: views))
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[pageController]|", options: [], metrics: nil, views: views))
for i in 0..<8 {
let mainScreenViewController = MainScrenenViewController()
mainScreenViewController.currentIndex = i
self.controllers.append(mainScreenViewController)
}
pageController.setViewControllers([controllers[0]], direction: .forward, animated: false)
setupPageControl()
}
func setupPageControl() {
pageControl = UIPageControl(frame: CGRect(x: 0,y: 100,width: UIScreen.main.bounds.width,height: 50))
pageControl.numberOfPages = self.controllers.count
pageControl.tintColor = UIColor.lightGray
pageControl.pageIndicatorTintColor = UIColor.lightGray
pageControl.currentPageIndicatorTintColor = UIColor.black
pageControl.backgroundColor = UIColor.clear
view.addSubview(pageControl)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
if let index = controllers.firstIndex(of: viewController) {
if index > 0 {
return controllers[index - 1]
} else {
return nil
}
}
return nil
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
if let index = controllers.firstIndex(of: viewController) {
if index < controllers.count - 1 {
return controllers[index + 1]
} else {
return nil
}
}
return nil
}
}