PageViewController - 自动滑动 - Swift 3
PageViewController - Auto Slide - Swift 3
我正在尝试同时自动滑动页面视图控制器页面和页面指示器。我的页面视图控制器中有 5 个页面。从图 1-5 开始,流程运行良好,但我无法从第 5 个图像返回到第一个图像并重新启动自动滑动。
下面是我的代码:
import UIKit
class PageSliderViewController: UIViewController , UIPageViewControllerDataSource, UIPageViewControllerDelegate {
@IBOutlet weak var pageControl: UIPageControl!
var pageContainer: UIPageViewController!
// The pages it contains
var pages = [UIViewController]()
// Track the current index
var currentIndex: Int?
private var pendingIndex: Int?
override func viewDidLoad() {
super.viewDidLoad()
// Setup the pages
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let page1: UIViewController! = storyboard.instantiateViewController(withIdentifier: "Page1")
let page2: UIViewController! = storyboard.instantiateViewController(withIdentifier: "Page2")
let page3: UIViewController! = storyboard.instantiateViewController(withIdentifier: "Page3")
let page4: UIViewController! = storyboard.instantiateViewController(withIdentifier: "Page4")
let page5: UIViewController! = storyboard.instantiateViewController(withIdentifier: "Page5")
pages.append(page1)
pages.append(page2)
pages.append(page3)
pages.append(page4)
pages.append(page5)
// Create the page container
pageContainer = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
pageContainer.delegate = self
pageContainer.dataSource = self
pageContainer.setViewControllers([page1], direction: UIPageViewControllerNavigationDirection.forward, animated: false, completion: nil)
currentIndex = 0
// Add it to the view
view.addSubview(pageContainer.view)
// Configure our custom pageControl
self.view.bringSubview(toFront: self.loginButton)
self.view.bringSubview(toFront: self.signUpButton)
self.view.bringSubview(toFront: self.pageControl)
pageControl.numberOfPages = pages.count
pageControl.currentPage = 0
Timer.scheduledTimer(timeInterval: 5,
target: self,
selector: #selector(self.next(_:)),
userInfo: nil,
repeats: true)
}
func next(_ timer: Timer) {
pageContainer.goToNextPage()
currentIndex = currentIndex! + 1
if currentIndex == pageControl.numberOfPages{
currentIndex = 0
}
pageControl.currentPage = currentIndex!
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - UIPageViewController delegates
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.index(of: viewController)!
if currentIndex == 0 {
return nil
}
let previousIndex = abs((currentIndex - 1) % pages.count)
return pages[previousIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.index(of: viewController)!
if currentIndex == pages.count-1 {
return nil
}
let nextIndex = abs((currentIndex + 1) % pages.count)
return pages[nextIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
pendingIndex = pages.index(of: pendingViewControllers.first!)
}
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if completed {
currentIndex = pendingIndex
if let index = currentIndex {
pageControl.currentPage = index
}
}
}
}
extension UIPageViewController {
func goToNextPage(animated: Bool = true, completion: ((Bool) -> Void)? = nil) {
if let currentViewController = viewControllers?[0] {
if let nextPage = dataSource?.pageViewController(self, viewControllerAfter: currentViewController) {
setViewControllers([nextPage], direction: .forward, animated: animated, completion: completion)
}
}
}
}
请注意,通过此代码,页面控件从第 5 个点变为第 1 个点,但页面没有变化。有一些小错误,但无法弄清楚。任何帮助将不胜感激!
我没有试过运行这段代码,但我的猜测是:
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.index(of: viewController)!
if currentIndex == pages.count-1 {
return nil
}
let nextIndex = abs((currentIndex + 1) % pages.count)
return pages[nextIndex]
}
数组是从零开始的,所以如果您当前正在查看 page
5,那么您正在查看 pages[4]
... 而 pages.count - 1
等于 4。因此,您的代码是说:
if the current page is page5
return nil
因此您的 func goToNextPage()
分机调用 viewControllerAfter
并在 return 中获得 nil
。
您很可能想将 viewControllerAfter
更改为:
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.index(of: viewController)!
// you don't need this, because you are using % modulo operator
// to keep "nextIndex" within the array bounds
//if currentIndex == pages.count-1 {
// return nil
//}
let nextIndex = abs((currentIndex + 1) % pages.count)
return pages[nextIndex]
}
我正在尝试同时自动滑动页面视图控制器页面和页面指示器。我的页面视图控制器中有 5 个页面。从图 1-5 开始,流程运行良好,但我无法从第 5 个图像返回到第一个图像并重新启动自动滑动。
下面是我的代码:
import UIKit
class PageSliderViewController: UIViewController , UIPageViewControllerDataSource, UIPageViewControllerDelegate {
@IBOutlet weak var pageControl: UIPageControl!
var pageContainer: UIPageViewController!
// The pages it contains
var pages = [UIViewController]()
// Track the current index
var currentIndex: Int?
private var pendingIndex: Int?
override func viewDidLoad() {
super.viewDidLoad()
// Setup the pages
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let page1: UIViewController! = storyboard.instantiateViewController(withIdentifier: "Page1")
let page2: UIViewController! = storyboard.instantiateViewController(withIdentifier: "Page2")
let page3: UIViewController! = storyboard.instantiateViewController(withIdentifier: "Page3")
let page4: UIViewController! = storyboard.instantiateViewController(withIdentifier: "Page4")
let page5: UIViewController! = storyboard.instantiateViewController(withIdentifier: "Page5")
pages.append(page1)
pages.append(page2)
pages.append(page3)
pages.append(page4)
pages.append(page5)
// Create the page container
pageContainer = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
pageContainer.delegate = self
pageContainer.dataSource = self
pageContainer.setViewControllers([page1], direction: UIPageViewControllerNavigationDirection.forward, animated: false, completion: nil)
currentIndex = 0
// Add it to the view
view.addSubview(pageContainer.view)
// Configure our custom pageControl
self.view.bringSubview(toFront: self.loginButton)
self.view.bringSubview(toFront: self.signUpButton)
self.view.bringSubview(toFront: self.pageControl)
pageControl.numberOfPages = pages.count
pageControl.currentPage = 0
Timer.scheduledTimer(timeInterval: 5,
target: self,
selector: #selector(self.next(_:)),
userInfo: nil,
repeats: true)
}
func next(_ timer: Timer) {
pageContainer.goToNextPage()
currentIndex = currentIndex! + 1
if currentIndex == pageControl.numberOfPages{
currentIndex = 0
}
pageControl.currentPage = currentIndex!
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - UIPageViewController delegates
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.index(of: viewController)!
if currentIndex == 0 {
return nil
}
let previousIndex = abs((currentIndex - 1) % pages.count)
return pages[previousIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.index(of: viewController)!
if currentIndex == pages.count-1 {
return nil
}
let nextIndex = abs((currentIndex + 1) % pages.count)
return pages[nextIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
pendingIndex = pages.index(of: pendingViewControllers.first!)
}
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if completed {
currentIndex = pendingIndex
if let index = currentIndex {
pageControl.currentPage = index
}
}
}
}
extension UIPageViewController {
func goToNextPage(animated: Bool = true, completion: ((Bool) -> Void)? = nil) {
if let currentViewController = viewControllers?[0] {
if let nextPage = dataSource?.pageViewController(self, viewControllerAfter: currentViewController) {
setViewControllers([nextPage], direction: .forward, animated: animated, completion: completion)
}
}
}
}
请注意,通过此代码,页面控件从第 5 个点变为第 1 个点,但页面没有变化。有一些小错误,但无法弄清楚。任何帮助将不胜感激!
我没有试过运行这段代码,但我的猜测是:
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.index(of: viewController)!
if currentIndex == pages.count-1 {
return nil
}
let nextIndex = abs((currentIndex + 1) % pages.count)
return pages[nextIndex]
}
数组是从零开始的,所以如果您当前正在查看 page
5,那么您正在查看 pages[4]
... 而 pages.count - 1
等于 4。因此,您的代码是说:
if the current page is page5
return nil
因此您的 func goToNextPage()
分机调用 viewControllerAfter
并在 return 中获得 nil
。
您很可能想将 viewControllerAfter
更改为:
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.index(of: viewController)!
// you don't need this, because you are using % modulo operator
// to keep "nextIndex" within the array bounds
//if currentIndex == pages.count-1 {
// return nil
//}
let nextIndex = abs((currentIndex + 1) % pages.count)
return pages[nextIndex]
}