无法重新加载第 ViewController 页中的下一个 ViewController

Can't reload next ViewController in PageViewController

我无法在我的 PageViewController 中更新下一页。

  1. 我添加了所需数量的控制器,但 pageController.setViewControllers([controllers[0]], direction: .forward, animated: false) 方法只剩下一个。

  2. 我有从 viewModel 获取的每个下一个控制器的信息,并在 currentIndex 计数器更改时更新

  3. 在 viewControllerBefore 和 viewControllerAfter 方法中,我初始化我的视图控制器并在向前或向后滚动时增加或减少 currentIndex

  4. 之后,视图控制器中的 didSet 为我工作并进行更新。

  5. 但是,最后,我看到的不是 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

然后,在 viewControllerBeforeviewControllerAfter 中,不是从 controllers 数组中获取 已经创建的 视图控制器,而是 * 创建 MainScreenViewController 的另一个 实例并将其 .currentIndex 设置为 -= 1+= 1 ... 但是你 附加controllers.

您的代码然后 returns 来自控制器数组 index - 1index + 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()*/
        }
    }