无法重新加载第 ViewController 页中的下一个 ViewController
Can't reload next ViewController in PageViewController
我无法在我的 PageViewController 中更新下一页。
我添加了所需数量的控制器,但 pageController.setViewControllers([controllers[0]], direction: .forward, animated: false)
方法只剩下一个。
我有从 viewModel 获取的每个下一个控制器的信息,并在 currentIndex 计数器更改时更新
在 viewControllerBefore 和 viewControllerAfter 方法中,我初始化我的视图控制器并在向前或向后滚动时增加或减少 currentIndex
之后,视图控制器中的 didSet 为我工作并进行更新。
但是,最后,我看到的不是 8 个控制器,而是 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()
在 PageViewController
中的 viewDidLoad()
中,您正在这样做:
for _ in realm.objects(Cities.self) {
let mainScreenViewController = MainScrenenViewController(viewModel: self.viewModel, locationViewModel: self.locationViewModel)
self.controllers.append(mainScreenViewController)
}
所以,您已经创建了一个包含 8 个 MainScreenViewController
个对象的数组。
但是,您还没有为它们设置.currentIndex
,所以它们目前都是currentIndex = 0
。
然后,在 viewControllerBefore
和 viewControllerAfter
中,不是从 controllers
数组中获取 已经创建的 视图控制器,而是 * 创建 MainScreenViewController
的另一个 实例并将其 .currentIndex
设置为 -= 1
或 += 1
... 但是你 附加到controllers
.
您的代码然后 returns 来自控制器数组 index - 1
或 index + 1
的控制器。
如果您开始简单一些,可能会有所帮助...让您的 UIPageViewController
正常工作...然后 然后 添加视图和位置模型的代码.
这是一个基于您的代码的快速示例,它添加了居中标签。显示每个页面的“索引”:
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
}
}
您已经在 viewDidLoad 中创建了您的视图控制器,那么为什么您再次在 viewControllerBefore 和 viewControllerAfter 中重新创建它们?在 viewControllerBefore 和 viewControllerAfter 中,您只需要访问已经创建的视图控制器,我已经更新了您的代码。
class PageViewController: UIViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource
{
var pageControl = UIPageControl.appearance()
var pageController: UIPageViewController!
var controllers = [UIViewController]()
var pendingIndex = 0
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 index in 0 ..< 10
{
let mainScreenViewController = MainScrenenViewController()
mainScreenViewController.currentIndex = index
mainScreenViewController.view.backgroundColor = index % 2 == 0 ? UIColor.red : UIColor.blue
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 = 10
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?
{
guard var index = controllers.firstIndex(of: viewController) else
{
return nil
}
if (index == 0)
{
return nil
}
index -= 1
return controllers[index]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController?
{
guard var index = controllers.firstIndex(of: viewController) else
{
return nil
}
index += 1
if (index >= controllers.count)
{
return nil
}
return controllers[index]
}
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool)
{
if completed == true
{
if let pageIndex = (pageViewController.viewControllers?.first as? MainScrenenViewController)?.currentIndex
{
pageControl.currentPage = pageIndex
}
}
}
}
class MainScrenenViewController: UIViewController/*, ChangeWeatherDelegate*/
{
var currentIndex = 0
override func viewDidLoad() {
super.viewDidLoad()
loadData()
}
func loadData()
{
/*mainCollectionView.reloadData()
todayCollectionView.reloadData()
weekCollectionView.reloadData()*/
}
}
我无法在我的 PageViewController 中更新下一页。
我添加了所需数量的控制器,但
pageController.setViewControllers([controllers[0]], direction: .forward, animated: false)
方法只剩下一个。我有从 viewModel 获取的每个下一个控制器的信息,并在 currentIndex 计数器更改时更新
在 viewControllerBefore 和 viewControllerAfter 方法中,我初始化我的视图控制器并在向前或向后滚动时增加或减少 currentIndex
之后,视图控制器中的 didSet 为我工作并进行更新。
但是,最后,我看到的不是 8 个控制器,而是 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()
在 PageViewController
中的 viewDidLoad()
中,您正在这样做:
for _ in realm.objects(Cities.self) {
let mainScreenViewController = MainScrenenViewController(viewModel: self.viewModel, locationViewModel: self.locationViewModel)
self.controllers.append(mainScreenViewController)
}
所以,您已经创建了一个包含 8 个 MainScreenViewController
个对象的数组。
但是,您还没有为它们设置.currentIndex
,所以它们目前都是currentIndex = 0
。
然后,在 viewControllerBefore
和 viewControllerAfter
中,不是从 controllers
数组中获取 已经创建的 视图控制器,而是 * 创建 MainScreenViewController
的另一个 实例并将其 .currentIndex
设置为 -= 1
或 += 1
... 但是你 附加到controllers
.
您的代码然后 returns 来自控制器数组 index - 1
或 index + 1
的控制器。
如果您开始简单一些,可能会有所帮助...让您的 UIPageViewController
正常工作...然后 然后 添加视图和位置模型的代码.
这是一个基于您的代码的快速示例,它添加了居中标签。显示每个页面的“索引”:
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
}
}
您已经在 viewDidLoad 中创建了您的视图控制器,那么为什么您再次在 viewControllerBefore 和 viewControllerAfter 中重新创建它们?在 viewControllerBefore 和 viewControllerAfter 中,您只需要访问已经创建的视图控制器,我已经更新了您的代码。
class PageViewController: UIViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource
{
var pageControl = UIPageControl.appearance()
var pageController: UIPageViewController!
var controllers = [UIViewController]()
var pendingIndex = 0
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 index in 0 ..< 10
{
let mainScreenViewController = MainScrenenViewController()
mainScreenViewController.currentIndex = index
mainScreenViewController.view.backgroundColor = index % 2 == 0 ? UIColor.red : UIColor.blue
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 = 10
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?
{
guard var index = controllers.firstIndex(of: viewController) else
{
return nil
}
if (index == 0)
{
return nil
}
index -= 1
return controllers[index]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController?
{
guard var index = controllers.firstIndex(of: viewController) else
{
return nil
}
index += 1
if (index >= controllers.count)
{
return nil
}
return controllers[index]
}
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool)
{
if completed == true
{
if let pageIndex = (pageViewController.viewControllers?.first as? MainScrenenViewController)?.currentIndex
{
pageControl.currentPage = pageIndex
}
}
}
}
class MainScrenenViewController: UIViewController/*, ChangeWeatherDelegate*/
{
var currentIndex = 0
override func viewDidLoad() {
super.viewDidLoad()
loadData()
}
func loadData()
{
/*mainCollectionView.reloadData()
todayCollectionView.reloadData()
weekCollectionView.reloadData()*/
}
}