PageControll 页面 swift 4 的错误号

Posted

技术标签:

【中文标题】PageControll 页面 swift 4 的错误号【英文标题】:PageControll error number of page swift 4 【发布时间】:2018-06-28 09:33:57 【问题描述】:

我创建了一个包含 3 个页面的 PageController .. 我分配并声明了所有内容,我实现了两个允许滚动视图的功能,同时我输入了命令以启用控制器并报告了正确的页面。结果是,如果我流动我的页面一切正常,而在页面计数器下按他的意愿工作.. 我不明白出了什么问题

problemproblem2problem3

        import UIKit
        import AVFoundation
        protocol IntroNavigationDelegate: class 
            func showNextViewController()
            func showPreviousViewController()
            var isPagingEnabled: Bool  get set 
        
        final class IntroViewController: UIPageViewController, UIPageViewControllerDelegate, IntroNavigationDelegate, UIPageViewControllerDataSource    
            func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? 
                if let viewControllerIndex = self.displayedControllers.index(of: viewController) 
                    if viewControllerIndex == 0 
                     else if viewControllerIndex == 1 
                        return self.displayedControllers[viewControllerIndex - 1]
                    
                
                return nil
            

            func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? 
                if let viewControllerIndex = self.displayedControllers.index(of: viewController) 

                    if viewControllerIndex < self.displayedControllers.count - 1 
                        self.pageControl.currentPage = 1
                        return self.displayedControllers[viewControllerIndex + 1]
                     else 
                        self.pageControl.currentPage = 0
                    
                
                return nil
            

            var introRouter: IntroRouter?

            var pageControl = UIPageControl()

            var displayedControllers: [UIViewController] = []

            private var scrollView: UIScrollView? 
                for view in view.subviews 
                    if let subView = view as? UIScrollView 
                        return subView
                    
                
                return nil
            

            var isPagingEnabled: Bool 
                get 
                    return scrollView?.isScrollEnabled ?? true
                
                set 
                    scrollView?.isScrollEnabled = newValue
                
            

            override func viewDidLoad() 
                super.viewDidLoad()
                configurePageControl()
                setupUI()
                self.pageControl.updateCurrentPageDisplay()
                arrangeSubviews()
                self.delegate = self
            

            override func viewWillAppear(_ animated: Bool) 
                self.navigationController?.setNavigationBarHidden(true, animated: animated)
            

            override func viewWillDisappear(_ animated: Bool) 
                super.viewWillDisappear(animated)
                navigationController?.isNavigationBarHidden = false
            

            func setDiplayedControllers(_ controllers: [UIViewController], visualizedController: UIViewController) 
                displayedControllers = controllers
                setViewControllers([visualizedController], direction: .forward, animated: false, completion: nil)
            

            func showNextViewController() 
                if let current = viewControllers?.first, let next = IntroViewController(self, viewControllerAfter: current) 
                    setViewControllers([next], direction: .forward, animated: true, completion: nil)
                
            

            func showPreviousViewController() 
                if let current = viewControllers?.first, let previous = IntroViewController(self, viewControllerBefore: current) 
                    setViewControllers([previous], direction: .reverse, animated: true, completion: nil)
                
            

            func configurePageControl()
                self.pageControl.frame = CGRect()
                self.pageControl.numberOfPages = self.displayedControllers.count
                self.pageControl.translatesAutoresizingMaskIntoConstraints = false
                self.pageControl.updateCurrentPageDisplay()

                self.view.addSubview(self.pageControl)
                pageControl.activate([
                    pageControl.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -20),
                    pageControl.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.1),
                    pageControl.widthAnchor.constraint(equalTo: self.view.widthAnchor, multiplier: 1),
                    ])
            

            override init(transitionStyle style: UIPageViewControllerTransitionStyle, navigationOrientation: UIPageViewControllerNavigationOrientation, options: [String : Any]? = nil) 
                super.init(transitionStyle: style, navigationOrientation: navigationOrientation, options: options)
                setup()
            

            func setRouter(introRouter: IntroRouter) 
                self.introRouter = introRouter
            

            required init?(coder aDecoder: NSCoder) 
                fatalError("init(coder:) has not been implemented")
            

            private func setup() 
                view.backgroundColor = .white
                dataSource = self
            
        

        private extension IntroViewController 

                func IntroViewController(_ IntroViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? 

                    if let viewControllerIndex = self.displayedControllers.index(of: viewController) 
                        if viewControllerIndex == 0 
                            // wrap to last page in array
                            return self.displayedControllers.last
                         else 
                            // go to previous page in array
                            return self.displayedControllers[viewControllerIndex + 1]
                        
                    
                    return nil
                

                func IntroViewController(_ IntroViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? 
                    self.pageControl.updateCurrentPageDisplay()
                    if let viewControllerIndex = self.displayedControllers.index(of: viewController) 
                        if viewControllerIndex < self.displayedControllers.count - 1 
                            // go to next page in array
                            self.pageControl.currentPage = viewControllerIndex
                            return self.displayedControllers[viewControllerIndex + 1]
                         else 
                            // wrap to first page in array
                            self.pageControl.currentPage = viewControllerIndex
                            return self.displayedControllers.first
                        
                    
                    return nil
                

            func IntroViewController(_ IntroViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) 

        //         set the pageControl.currentPage to the index of the current viewController in pages
                if let viewControllers = IntroViewController.viewControllers 
                    if let viewControllerIndex = self.displayedControllers.index(of: viewControllers[0]) 
                        self.pageControl.currentPage = viewControllerIndex
                        self.pageControl.updateCurrentPageDisplay()
                    
                
            

            func setupUI() 
                configurePageControl()
                pageControl.do 
                    $0.numberOfPages = 3
        //            $0.currentPage = 0
                    $0.pageIndicatorTintColor = .lightGray
                    $0.currentPageIndicatorTintColor = Theme.Colors.white
                    $0.currentPage = self.displayedControllers.count
                
            

            func arrangeSubviews() 
                view.addSubview(pageControl)
            
        

【问题讨论】:

【参考方案1】:

试试下面的代码。这会很有帮助。

class PageViewModel: NSObject 

    private var timer: Timer?
    private var interval: Double?
    var enableAutoScroll: Bool = false 
        didSet 
            self.toggleTimer()
        
    
    var viewControllers: [UIViewController]
    var currentIndex: Int = 0
    var direction: UIPageViewControllerNavigationDirection = .forward

    init(viewControllers: [UIViewController]) 
        self.viewControllers = viewControllers
        super.init()
    

    override convenience init() 
        self.init(viewControllers: [])
    

    private func stopTimer() 
        if self.timer != nil 
            timer?.invalidate()
            timer = nil
            return
        
    

    private func startTimer() 

        if self.timer != nil 
            return
        

        if #available(ios 10.0, *) 
            if let time = interval 
                timer = Timer.scheduledTimer(withTimeInterval: time, repeats: true, block:  (timer: Timer) in
                    self.timerFire()
                )
            
         else 
            // Fallback on earlier versions
            if let time = interval 
                timer = Timer.scheduledTimer(timeInterval: time, target: self, selector: #selector(PageViewModel.timerFire), userInfo: nil, repeats: true)
            
        
    

    @objc private func timerFire() 
        if direction == .forward 
            var index = currentIndex
            if index < self.viewControllers.count - 1 
                index += 1
             else 
                index = 0
            

            currentIndex = index
            scrollToNextPage?(currentIndex)
            pageNumberChangedObserver?(currentIndex)

         else 

            var index = currentIndex
            if index <= 0 
                index = (self.viewControllers.count - 1)
             else 
                index -= 1
            
            currentIndex = index
            scrollToNextPage?(index)
            pageNumberChangedObserver?(currentIndex)
        
    


    // MARK: - Timer
    func toggleTimer() 
        if enableAutoScroll == true 
            startTimer()
         else 
            stopTimer()
        
    

    fileprivate var scrollToNextPage: ((_ index: Int) -> Void)?
    func scrollToNextPage(callBack: @escaping (_ index: Int) -> Void) 
        scrollToNextPage = callBack
    

    // MARK: - PageNumberChangedObserver
    fileprivate var pageNumberChangedObserver: ((_ index: Int) -> Void)?
    func pageNumberChanged(callBack: @escaping (_ index: Int) -> Void) 
        pageNumberChangedObserver = callBack
    



// MARK: - UIPageViewControllerDataSource
extension PageViewModel: UIPageViewControllerDataSource 

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? 

        guard let viewControllerIndex = viewControllers.index(of: viewController) else 
            return nil
        
        let previousIndex = viewControllerIndex - 1

        // User is on the first view controller and swiped left to loop to
        // the last view controller.
        guard previousIndex >= 0 else 
            //return orderedViewControllers.last
            // Uncommment the line below, remove the line above if you don't want the page control to loop.
            return nil
        

        guard viewControllers.count > previousIndex else 
            return nil
        

        return viewControllers[previousIndex]
    

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? 
        guard let viewControllerIndex = viewControllers.index(of: viewController) else 
            return nil
        

        let nextIndex = viewControllerIndex + 1
        let orderedViewControllersCount = viewControllers.count

        // User is on the last view controller and swiped right to loop to
        // the first view controller.
        guard orderedViewControllersCount != nextIndex else 
            //return orderedViewControllers.first
            // Uncommment the line below, remove the line above if you don't want the page control to loop.
            return nil
        

        guard orderedViewControllersCount > nextIndex else 
            return nil
        

        return viewControllers[nextIndex]
    



// MARK: - UIPageViewControllerDelegate
extension PageViewModel: UIPageViewControllerDelegate 

    func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) 

        if let pageContentViewController = pageViewController.viewControllers?[0] 

            if let index = viewControllers.index(of: pageContentViewController) 
                currentIndex = index
                pageNumberChangedObserver?(currentIndex)
            
        
    

在您的容器视图控制器中编写以下代码:-

    // set current page to the page controller
    func setNextPage(index: Int, direction: UIPageViewControllerNavigationDirection) 

        if let firstViewController = pageViewModel?.viewControllers[selectedCategoryCell] 
            pageViewController?.setViewControllers([firstViewController],
                                                   direction: direction,
                                                   animated: true,
                                                   completion: nil)
        
    


 // MARK: - SET PAGE CONTROLLER's VIEW's
    private func setupPageViewController() 
        let pageViewController: UIPageViewController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
        pageViewController.dataSource = pageViewModel
        pageViewController.delegate = pageViewModel
        if let firstViewController = pageViewModel?.viewControllers[selectedCategoryCell] 
            pageViewController.setViewControllers([firstViewController],
                                                  direction: .forward,
                                                  animated: true,
                                                  completion: nil)
        

        for recognizer in pageViewController.gestureRecognizers 
            if recognizer is UITapGestureRecognizer 
                recognizer.isEnabled = false
            
        
        self.addChildViewController(pageViewController)
        self.containerView.addSubview(pageViewController.view)
        var pageViewRect = self.containerView.bounds
        if UIDevice.current.userInterfaceIdiom == .pad 
            pageViewRect = pageViewRect.insetBy(dx: 40.0, dy: 40.0)
        
        pageViewController.view.frame = pageViewRect
        pageViewController.didMove(toParentViewController: self)
        self.pageViewController = pageViewController
    


    // set the selected page and accordingly set the above collection view ( that is treatment option's collection view)
    func pageNumberChanged(index: Int) 
        self.selectedCategoryCell = index
    

    // MARK: Init View Controller for Page Controller
    func initViewController(index: Int) -> UIViewController 
        guard let itemsViewController = self.storyboard?.instantiateViewController(withIdentifier: "MatchesV2ViewController") as? MatchesV2ViewController else 
            fatalError("Items View Controller Not Found")
        
        itemsViewController.delegate = self
        itemsViewController.currentMatch = matches.user[index]
        return itemsViewController
    

    // MARK: Setting VC In Page View Controller
    func instantiateViewControllers() 
        matchesScreen.removeAll()
        for i in 0..<matches.user.count 
            matchesScreen.append(initViewController(index: i))
        
        pageViewModel = PageViewModel(viewControllers: matchesScreen)
        pageViewModel?.pageNumberChanged(callBack:  (index: Int) in
            self.pageNumberChanged(index: index)
        )
        pageViewModel?.scrollToNextPage(callBack:  (index: Int) in
            self.setNextPage(index: index, direction: .forward)
        )
        if matchesScreen.count > 0 
            self.setupPageViewController()
        
    

【讨论】:

我只需要管理页面控制器的部分,我不想重做所有事情.. 其余的都在工作 我认为这是处理 UIPageController 的完美方式。 我写的代码我应该删除什么来使用你的? 我的代码分为两部分。第一部分只需在 Pageview.Swift 中编写,其中包含 UIPageController 委托和数据源的处理。就像 UITableViewDelegate 和 dataSource 一样。第二部分包含如何使用该功能。比如将 DataSource 设置为 UIPageController,移动 Next PageController

以上是关于PageControll 页面 swift 4 的错误号的主要内容,如果未能解决你的问题,请参考以下文章

使用我的视图控制器 swift 4 中的按钮使用 UIPageViewController 更改页面

在计时器的帮助下,Swift 4 在页面视图控制器中自动滑动

为多个变量创建和填充页面 Swift 4.0

UIPageControl

swift 4中的页面控制是不是可以有一个无限的水平分页uiscrollview?

swift 4 中使用 performSegue 打开的关闭页面时,如何在视图控制器和 TableViewController 之间传递数据?