【问题标题】:PageControll error number of page swift 4PageControll 页面 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)
            }
        }

【问题讨论】:

    标签: ios iphone swift xcode uipageviewcontroller


    【解决方案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
    猜你喜欢
    • 2018-05-23
    • 1970-01-01
    • 2014-07-27
    • 1970-01-01
    • 1970-01-01
    • 2019-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多