UIPageViewController 当前页面索引 Swift
PageViewController current page index in Swift
我想获取 pageViewController 的当前索引,我不知道如何获取可见页面索引。
func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool,previousViewControllers: [UIViewController],transitionCompleted completed: Bool)
{
// How to get it?
}
你可以使用didFinishAnimating,给viewcontrollers设置标签。试试这个
func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool)
{
if (!completed)
{
return
}
self.pageControl.currentPageIndex = pageViewController.viewControllers!.first!.view.tag //Page Index
}
试试吧..
func pageViewController(pageViewController: UIPageViewController,didFinishAnimating finished: Bool,previousViewControllers: [UIViewController],transitionCompleted completed: Bool){
guard completed else { return }
self.pageControl.currentPage = pageViewController.viewControllers!.first!.view.tag
}
Swift 3: 完整的程序化 PageViewController 示例 get/set 当前页面索引没有视图标记:
enum PageViewType:String {
case green = "greenView"
case blue = "blueView"
case red = "redView"
}
class MyPageViewController: UIPageViewController {
private (set) lazy var orderedViewControllers:[UIViewController] = {
return [self.newPageView(.green),
self.newPageView(.blue),
self.newPageView(.red)
]
}
var currentIndex:Int {
get {
return orderedViewControllers.index(of: self.viewControllers!.first!)!
}
set {
guard newValue >= 0,
newValue < orderedViewControllers.count else {
return
}
let vc = orderedViewControllers[newValue]
let direction:UIPageViewControllerNavigationDirection = newValue > currentIndex ? .forward : .reverse
self.setViewControllers([vc], direction: direction, animated: true, completion: nil)
}
}
override func viewDidLoad() {
super.viewDidLoad()
dataSource = self
if let firstViewController = orderedViewControllers.first {
setViewControllers([firstViewController],
direction: .forward,
animated: true,
completion: nil)
}
}
private func newPageView(_ viewType:PageViewType) -> UIViewController {
let vc = self.storyboard?.instantiateViewController(withIdentifier: viewType.rawValue)
return vc
}
}
UIPageViewController 数据源实现:
extension MyPageViewController:UIPageViewControllerDataSource {
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let previousIndex = currentIndex - 1
guard previousIndex >= 0 else {
return nil
}
guard orderedViewControllers.count > previousIndex else {
return nil
}
return orderedViewControllers[previousIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let nextIndex = currentIndex + 1
guard orderedViewControllers.count != nextIndex else {
return nil
}
guard orderedViewControllers.count > nextIndex else {
return nil
}
return orderedViewControllers[nextIndex]
}
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return orderedViewControllers.count
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
return currentIndex
}
}
在Swift3
像这样重写 UIPageViewControllerDelegate 的 didFinishAnimating 函数:
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if completed {
if let currentViewController = pageViewController.viewControllers![0] as? WalkthroughContentViewController {
pageControl.currentPage = currentViewController.index
}
}
}
其中 WalkthroughContentViewController 是由 UIPageViewController 呈现的 UIViewController
记得在 WalkthroughContentViewController 中保留一个索引变量。另外,在 viewDidLoad 方法中设置:
delegate = self
不要忘记设置 uipageviewcontroller 委托。
func createPageViewController() {
// Create page view controller
pageViewController = storyboard?.instantiateViewController(withIdentifier: "PageViewController") as? UIPageViewController
pageViewController?.delegate = self
pageViewController?.dataSource = self
let startingViewController: ChildViewController = viewControllerAtIndex(index: 0)!
let viewControllers: Array = [startingViewController]
pageViewController?.setViewControllers(viewControllers, direction: .forward, animated: true, completion: nil)
self.addChildViewController(pageViewController!)
self.view.frame = CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height: self.view.bounds.size.height)
self.view.addSubview((pageViewController?.view)!)
self.pageViewController?.didMove(toParentViewController: self)
}
func viewControllerAtIndex(index: Int) -> ChildViewController? {
// return nil here, if there won't be any page in pageviewcontroller
// Create a new view controller and pass suitable data.
let pageContentViewController: ChildViewController = storyboard?.instantiateViewController(withIdentifier: "ChildViewController") as! ChildViewController
pageContentViewController.pageIndex = index
return pageContentViewController
}
//Also add viewControllerAfter and viewControllerBefore methods
func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
self.pendingIndex = (pendingViewControllers.first as! ChildViewController).pageIndex
}
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if completed {
self.currentIndex = self.pendingIndex!
//Perform your task here
}
}
您可以使用下一个方法:
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
guard
completed,
let viewControllerIndex = tutorialViews.index(of: pageViewController.viewControllers!.first!) else
return
}
self.currentIndex = viewControllerIndex
}
其中 tutorialViews 是页面数组 (ViewControllers)。
并像这样初始化 currentIndex:
var currentIndex = 0 {
didSet {
self.updateContentForPage(withIndex: currentIndex)
}
}
在 class -> WalkthroughPageViewController) 中创建一个方法,这样:
/* The method takes in a page index and creates the next content view controller. If the controller can
be created, we call the built-in setViewControllers method and navigate to the next view controller.*/
func forward(index: Int) {
if let nextViewController = contentViewController(at: index + 1) {
setViewControllers([nextViewController], direction: .forward, animated: true, completion: nil)
}
}
并且在控制 UIPageController 的 class 中,它将是一个控制器视图(class -> WalkthroughContentViewController)并且包含一个传递到下一页并更新 属性 "pageControl.currentPage"(它本身就是 UIpageControl),实现:
class WalkthroughContentViewController: UIViewController {
@IBOutlet var headingLabel: UILabel!
@IBOutlet var contentLabel: UILabel!
@IBOutlet var forwardButton: UIButton!
@IBOutlet var pageControl: UIPageControl!
@IBOutlet var contentImageView: UIImageView!
var index = 0
var heading = ""
var content = ""
var imageFile = ""
override func viewDidLoad() {
super.viewDidLoad()
headingLabel.text = heading
contentLabel.text = content
contentImageView.image = UIImage(named: imageFile)
// Update the 'currentPage' property of the page control.
pageControl.currentPage = index
if case 0...1 = index {
forwardButton.setTitle("NEXT", for : .normal)
} else if case 2 = index {
forwardButton.setTitle("DONE", for : .normal)
}
}
// MARK: - Actions
@IBAction func nextButtonTapped(sender: UIButton) {
switch index {
case 0...1: /* Get the parent controller & call to the "forward" method from the 'WalkthroughPageViewController'. */
let pageViewController = parent as! WalkthroughPageViewController
pageViewController.forward(index: index)
case 2: /* Dismiss the page view controller and show the main screen of the app*/
dismiss(animated: true, completion: nil)
default: break
}
}
}
只需查看 apple 的文档 (https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit) -> 第 3 节 -> 第 5 步
你可以这样获取当前索引
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if completed,
let visibleViewController = pageViewController.viewControllers?.first,
let index = parent.controllers.firstIndex(of: visibleViewController)
{
parent.currentPage = index
}
}
或者如果您将 viewController 保存在一个数组中,您可以这样做
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if completed,
let visibleViewController = pageViewController.viewControllers?.first,
let index = orderedViewControllers.firstIndex(of: visibleViewController)
{
statisticsPageDelegate?.statisticsPageViewController(statisticsPageViewController: self, didUpdatePageIndex: index)
}
}
这是完整代码
class StatisticsPageViewController: UIPageViewController,UIPageViewControllerDataSource, UIPageViewControllerDelegate {
var currentIndex: Int?
var statisticsPageDelegate: StatisticsPageViewControllerDelegate?
private var pendingIndex: Int?
required init?(coder aDecoder: NSCoder) {
super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
dataSource = self
delegate = self
if let firstViewController = orderedViewControllers.first {
setViewControllers([firstViewController],
direction: .forward,
animated: true,
completion: nil)
}
statisticsPageDelegate?.statisticsPageViewController(
statisticsPageViewController: self,
didUpdatePageCount: orderedViewControllers.count
)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.index(of:viewController) else {
return nil
}
let previousIndex = viewControllerIndex - 1
guard previousIndex >= 0 else {
return nil
}
guard orderedViewControllers.count > previousIndex else {
return nil
}
return orderedViewControllers[previousIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.index(of:viewController) else {
return nil
}
let nextIndex = viewControllerIndex + 1
let orderedViewControllersCount = orderedViewControllers.count
guard orderedViewControllersCount != nextIndex else {
return nil
}
guard orderedViewControllersCount > nextIndex else {
return nil
}
return orderedViewControllers[nextIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if completed,
let visibleViewController = pageViewController.viewControllers?.first,
let index = orderedViewControllers.firstIndex(of: visibleViewController)
{
statisticsPageDelegate?.statisticsPageViewController(statisticsPageViewController: self, didUpdatePageIndex: index)
}
}
private(set) lazy var orderedViewControllers: [UIViewController] = {
return [self.newStatisticsViewController(identifier: Identifiers.PROGRAM_VIEW_CONTROLLER),
self.newStatisticsViewController(identifier: Identifiers.LOGIN_VIEW_CONTROLLER)]
}()
private func newStatisticsViewController(identifier: String) -> UIViewController {
return UIStoryboard(name: "Main", bundle: nil) .
instantiateViewController(withIdentifier: identifier)
}
}
protocol StatisticsPageViewControllerDelegate: class {
func statisticsPageViewController(statisticsPageViewController:
StatisticsPageViewController, didUpdatePageCount count: Int)
func statisticsPageViewController(statisticsPageViewController:
StatisticsPageViewController, didUpdatePageIndex index: Int)
}
首先,让您的 UIPageViewController 实现 UIPageViewControllerDataSource 方法presentationIndex(for pageViewController: UIPageViewController) -> Int
return 每个 PageViewController 的 ViewController 的索引。
然后在您的委托中,通过传入的 PageViewController 访问数据源:
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
guard let dataSource = pageViewController.dataSource,
let currentIndex = dataSource.presentationIndex?(for: pageViewController) else { preconditionFailure() }
}
使用 viewDidAppear
将页面标记为可见,使用 viewDidDisappear
将页面标记为不可见
项目ViewController:
class PageItemViewController: UIViewController {
private(set) var isVisible: Bool = false
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
isVisible = true
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
isVisible = false
}
}
获取可见页面的索引
class PageViewController: UIPageViewController, UIPageViewControllerDelegate {
var items: [PageItemViewController] = [] {
didSet {
if let last = items.last {
setViewControllers([last], direction: .forward, animated: true, completion: nil)
}
}
}
// ...
public func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if finished {
guard let currentIndex = items.firstIndex(where: { [=11=].isVisible }) else { return }
print(currentIndex)
}
}
}
Swift 4个版本
使用这些协议(UIPageViewControllerDelegate
、UIPageViewControllerDataSource
)扩展 ViewController class 并添加以下功能帮助我使我的页面控制正常工作。
class ViewController : UIPageViewControllerDelegate,UIPageViewControllerDataSource {
func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
if let viewController = pendingViewControllers[0] as? DataViewController {
self.lastPendingViewControllerIndex = viewController.index!
}
}
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if completed {
pageControl.currentPage = self.lastPendingViewControllerIndex
if lastPendingViewControllerIndex == 4 {
self.getstartedButton.isHidden=false
} else {
self.getstartedButton.isHidden=true
}
}
}
}
将此代码添加到您的 UIPageViewController
。
var pages = [UIViewController]()
var currentIndex: Int {
guard let vc = viewControllers?.first else { return 0 }
return pages.firstIndex(of: vc) ?? 0
}
我想获取 pageViewController 的当前索引,我不知道如何获取可见页面索引。
func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool,previousViewControllers: [UIViewController],transitionCompleted completed: Bool)
{
// How to get it?
}
你可以使用didFinishAnimating,给viewcontrollers设置标签。试试这个
func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool)
{
if (!completed)
{
return
}
self.pageControl.currentPageIndex = pageViewController.viewControllers!.first!.view.tag //Page Index
}
试试吧..
func pageViewController(pageViewController: UIPageViewController,didFinishAnimating finished: Bool,previousViewControllers: [UIViewController],transitionCompleted completed: Bool){
guard completed else { return }
self.pageControl.currentPage = pageViewController.viewControllers!.first!.view.tag
}
Swift 3: 完整的程序化 PageViewController 示例 get/set 当前页面索引没有视图标记:
enum PageViewType:String {
case green = "greenView"
case blue = "blueView"
case red = "redView"
}
class MyPageViewController: UIPageViewController {
private (set) lazy var orderedViewControllers:[UIViewController] = {
return [self.newPageView(.green),
self.newPageView(.blue),
self.newPageView(.red)
]
}
var currentIndex:Int {
get {
return orderedViewControllers.index(of: self.viewControllers!.first!)!
}
set {
guard newValue >= 0,
newValue < orderedViewControllers.count else {
return
}
let vc = orderedViewControllers[newValue]
let direction:UIPageViewControllerNavigationDirection = newValue > currentIndex ? .forward : .reverse
self.setViewControllers([vc], direction: direction, animated: true, completion: nil)
}
}
override func viewDidLoad() {
super.viewDidLoad()
dataSource = self
if let firstViewController = orderedViewControllers.first {
setViewControllers([firstViewController],
direction: .forward,
animated: true,
completion: nil)
}
}
private func newPageView(_ viewType:PageViewType) -> UIViewController {
let vc = self.storyboard?.instantiateViewController(withIdentifier: viewType.rawValue)
return vc
}
}
UIPageViewController 数据源实现:
extension MyPageViewController:UIPageViewControllerDataSource {
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let previousIndex = currentIndex - 1
guard previousIndex >= 0 else {
return nil
}
guard orderedViewControllers.count > previousIndex else {
return nil
}
return orderedViewControllers[previousIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let nextIndex = currentIndex + 1
guard orderedViewControllers.count != nextIndex else {
return nil
}
guard orderedViewControllers.count > nextIndex else {
return nil
}
return orderedViewControllers[nextIndex]
}
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return orderedViewControllers.count
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
return currentIndex
}
}
在Swift3
像这样重写 UIPageViewControllerDelegate 的 didFinishAnimating 函数:
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if completed {
if let currentViewController = pageViewController.viewControllers![0] as? WalkthroughContentViewController {
pageControl.currentPage = currentViewController.index
}
}
}
其中 WalkthroughContentViewController 是由 UIPageViewController 呈现的 UIViewController
记得在 WalkthroughContentViewController 中保留一个索引变量。另外,在 viewDidLoad 方法中设置:
delegate = self
不要忘记设置 uipageviewcontroller 委托。
func createPageViewController() {
// Create page view controller
pageViewController = storyboard?.instantiateViewController(withIdentifier: "PageViewController") as? UIPageViewController
pageViewController?.delegate = self
pageViewController?.dataSource = self
let startingViewController: ChildViewController = viewControllerAtIndex(index: 0)!
let viewControllers: Array = [startingViewController]
pageViewController?.setViewControllers(viewControllers, direction: .forward, animated: true, completion: nil)
self.addChildViewController(pageViewController!)
self.view.frame = CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height: self.view.bounds.size.height)
self.view.addSubview((pageViewController?.view)!)
self.pageViewController?.didMove(toParentViewController: self)
}
func viewControllerAtIndex(index: Int) -> ChildViewController? {
// return nil here, if there won't be any page in pageviewcontroller
// Create a new view controller and pass suitable data.
let pageContentViewController: ChildViewController = storyboard?.instantiateViewController(withIdentifier: "ChildViewController") as! ChildViewController
pageContentViewController.pageIndex = index
return pageContentViewController
}
//Also add viewControllerAfter and viewControllerBefore methods
func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
self.pendingIndex = (pendingViewControllers.first as! ChildViewController).pageIndex
}
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if completed {
self.currentIndex = self.pendingIndex!
//Perform your task here
}
}
您可以使用下一个方法:
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
guard
completed,
let viewControllerIndex = tutorialViews.index(of: pageViewController.viewControllers!.first!) else
return
}
self.currentIndex = viewControllerIndex
}
其中 tutorialViews 是页面数组 (ViewControllers)。
并像这样初始化 currentIndex:
var currentIndex = 0 {
didSet {
self.updateContentForPage(withIndex: currentIndex)
}
}
在 class -> WalkthroughPageViewController) 中创建一个方法,这样:
/* The method takes in a page index and creates the next content view controller. If the controller can
be created, we call the built-in setViewControllers method and navigate to the next view controller.*/
func forward(index: Int) {
if let nextViewController = contentViewController(at: index + 1) {
setViewControllers([nextViewController], direction: .forward, animated: true, completion: nil)
}
}
并且在控制 UIPageController 的 class 中,它将是一个控制器视图(class -> WalkthroughContentViewController)并且包含一个传递到下一页并更新 属性 "pageControl.currentPage"(它本身就是 UIpageControl),实现:
class WalkthroughContentViewController: UIViewController {
@IBOutlet var headingLabel: UILabel!
@IBOutlet var contentLabel: UILabel!
@IBOutlet var forwardButton: UIButton!
@IBOutlet var pageControl: UIPageControl!
@IBOutlet var contentImageView: UIImageView!
var index = 0
var heading = ""
var content = ""
var imageFile = ""
override func viewDidLoad() {
super.viewDidLoad()
headingLabel.text = heading
contentLabel.text = content
contentImageView.image = UIImage(named: imageFile)
// Update the 'currentPage' property of the page control.
pageControl.currentPage = index
if case 0...1 = index {
forwardButton.setTitle("NEXT", for : .normal)
} else if case 2 = index {
forwardButton.setTitle("DONE", for : .normal)
}
}
// MARK: - Actions
@IBAction func nextButtonTapped(sender: UIButton) {
switch index {
case 0...1: /* Get the parent controller & call to the "forward" method from the 'WalkthroughPageViewController'. */
let pageViewController = parent as! WalkthroughPageViewController
pageViewController.forward(index: index)
case 2: /* Dismiss the page view controller and show the main screen of the app*/
dismiss(animated: true, completion: nil)
default: break
}
}
}
只需查看 apple 的文档 (https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit) -> 第 3 节 -> 第 5 步
你可以这样获取当前索引
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if completed,
let visibleViewController = pageViewController.viewControllers?.first,
let index = parent.controllers.firstIndex(of: visibleViewController)
{
parent.currentPage = index
}
}
或者如果您将 viewController 保存在一个数组中,您可以这样做
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if completed,
let visibleViewController = pageViewController.viewControllers?.first,
let index = orderedViewControllers.firstIndex(of: visibleViewController)
{
statisticsPageDelegate?.statisticsPageViewController(statisticsPageViewController: self, didUpdatePageIndex: index)
}
}
这是完整代码
class StatisticsPageViewController: UIPageViewController,UIPageViewControllerDataSource, UIPageViewControllerDelegate {
var currentIndex: Int?
var statisticsPageDelegate: StatisticsPageViewControllerDelegate?
private var pendingIndex: Int?
required init?(coder aDecoder: NSCoder) {
super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
dataSource = self
delegate = self
if let firstViewController = orderedViewControllers.first {
setViewControllers([firstViewController],
direction: .forward,
animated: true,
completion: nil)
}
statisticsPageDelegate?.statisticsPageViewController(
statisticsPageViewController: self,
didUpdatePageCount: orderedViewControllers.count
)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.index(of:viewController) else {
return nil
}
let previousIndex = viewControllerIndex - 1
guard previousIndex >= 0 else {
return nil
}
guard orderedViewControllers.count > previousIndex else {
return nil
}
return orderedViewControllers[previousIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.index(of:viewController) else {
return nil
}
let nextIndex = viewControllerIndex + 1
let orderedViewControllersCount = orderedViewControllers.count
guard orderedViewControllersCount != nextIndex else {
return nil
}
guard orderedViewControllersCount > nextIndex else {
return nil
}
return orderedViewControllers[nextIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if completed,
let visibleViewController = pageViewController.viewControllers?.first,
let index = orderedViewControllers.firstIndex(of: visibleViewController)
{
statisticsPageDelegate?.statisticsPageViewController(statisticsPageViewController: self, didUpdatePageIndex: index)
}
}
private(set) lazy var orderedViewControllers: [UIViewController] = {
return [self.newStatisticsViewController(identifier: Identifiers.PROGRAM_VIEW_CONTROLLER),
self.newStatisticsViewController(identifier: Identifiers.LOGIN_VIEW_CONTROLLER)]
}()
private func newStatisticsViewController(identifier: String) -> UIViewController {
return UIStoryboard(name: "Main", bundle: nil) .
instantiateViewController(withIdentifier: identifier)
}
}
protocol StatisticsPageViewControllerDelegate: class {
func statisticsPageViewController(statisticsPageViewController:
StatisticsPageViewController, didUpdatePageCount count: Int)
func statisticsPageViewController(statisticsPageViewController:
StatisticsPageViewController, didUpdatePageIndex index: Int)
}
首先,让您的 UIPageViewController 实现 UIPageViewControllerDataSource 方法presentationIndex(for pageViewController: UIPageViewController) -> Int
return 每个 PageViewController 的 ViewController 的索引。
然后在您的委托中,通过传入的 PageViewController 访问数据源:
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
guard let dataSource = pageViewController.dataSource,
let currentIndex = dataSource.presentationIndex?(for: pageViewController) else { preconditionFailure() }
}
使用 viewDidAppear
将页面标记为可见,使用 viewDidDisappear
将页面标记为不可见
项目ViewController:
class PageItemViewController: UIViewController {
private(set) var isVisible: Bool = false
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
isVisible = true
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
isVisible = false
}
}
获取可见页面的索引
class PageViewController: UIPageViewController, UIPageViewControllerDelegate {
var items: [PageItemViewController] = [] {
didSet {
if let last = items.last {
setViewControllers([last], direction: .forward, animated: true, completion: nil)
}
}
}
// ...
public func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if finished {
guard let currentIndex = items.firstIndex(where: { [=11=].isVisible }) else { return }
print(currentIndex)
}
}
}
Swift 4个版本
使用这些协议(UIPageViewControllerDelegate
、UIPageViewControllerDataSource
)扩展 ViewController class 并添加以下功能帮助我使我的页面控制正常工作。
class ViewController : UIPageViewControllerDelegate,UIPageViewControllerDataSource {
func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
if let viewController = pendingViewControllers[0] as? DataViewController {
self.lastPendingViewControllerIndex = viewController.index!
}
}
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if completed {
pageControl.currentPage = self.lastPendingViewControllerIndex
if lastPendingViewControllerIndex == 4 {
self.getstartedButton.isHidden=false
} else {
self.getstartedButton.isHidden=true
}
}
}
}
将此代码添加到您的 UIPageViewController
。
var pages = [UIViewController]()
var currentIndex: Int {
guard let vc = viewControllers?.first else { return 0 }
return pages.firstIndex(of: vc) ?? 0
}