我创建了一个包含3页的PageController。我分配并声明了所有内容,实现了两个允许滚动视图的功能,在同一页面中,我输入了命令以启用具有正确页面的控制器。结果是,如果我的页面顺畅,一切正常,而页面计数器则按他的意愿工作..而我无法理解什么地方出了问题
problem problem2 problem3
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)
}
}
最佳答案
只需尝试以下代码。这将是有帮助的。
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)
}
}
}
}
在Container View Controller中编写以下代码:-
// 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()
}
}
关于ios - PageController错误页数 swift 4,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51079428/