I'm starting study swift, and use UIPageViewController to slide 3 page. I use class:
import Foundation
import UIKit
class MyPageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
var pages = [UIViewController]()
var pageIndicator : UIPageControl!
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
self.dataSource = self
let page1: UIViewController! = storyboard?.instantiateViewControllerWithIdentifier("page1")
let page2: UIViewController! = storyboard?.instantiateViewControllerWithIdentifier("page2")
let page3: UIViewController! = storyboard?.instantiateViewControllerWithIdentifier("page3")
pages.append(page1)
pages.append(page2)
pages.append(page3)
setViewControllers([page1], direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)
}
func viewControllerAtIndex(index: Int) -> UINavigationController! {
return nil
}
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.indexOf(viewController)!
pageIndicator.currentPage = currentIndex
let previousIndex = abs((currentIndex - 1) % pages.count)
return pages[previousIndex]
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.indexOf(viewController)!
pageIndicator.currentPage = currentIndex
let nextIndex = abs((currentIndex + 1) % pages.count)
return pages[nextIndex]
}
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return pages.count
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
return 0
}
}
But sliding didn't stops on the third page, and begins again with first page.
How limit slide page forward and backward?
I think your index calculation is wrong in the following line.
`
let nextIndex = abs((currentIndex + 1) % pages.count)
return pages[nextIndex]`
for the last view controller currentIndex=2 ,then nextIndex=(2+1)%3=0.
So you are returning the view controller at index 0 again.
add the following line to your method `
if(currentIndex == (pages.count-1))
{
return nil;
}
`Note:this is according to objective c.
As UIBittu already pointed out: your calculation needs a fix.
A possible (probably more readable) solution may look like this:
func indexOfViewController(viewController: UIViewController) -> Int {
guard let index = pages.indexOf(viewController) else {
return NSNotFound
}
return index
}
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
var index = indexOfViewController(viewController)
if (index == 0) || (index == NSNotFound) {
return nil
}
index--
return pages[index]
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
var index = indexOfViewController(viewController)
if (index == NSNotFound) || (index+1 == pages.count) {
return nil
}
index++
return pages[index]
}
This is different solution.
You don't need to have a full set of complex code to execute what you need.
Create a ScrollView. Set its content size width as the multiple of number of pages.
Try this code. this may help You
override func viewDidLoad() {
super.viewDidLoad()
let screensize = UIScreen.mainScreen().bounds
pagescroll.frame = CGRectMake(0, 0,screensize.width, screensize.height)
pagescroll.contentSize = CGSize(width: screensize.width*3, height: screensize.height)
pagescroll.pagingEnabled = true
page1.frame = CGRectMake(0, 0, screensize.width, screensize.height)
page2.frame = CGRectMake(screensize.width, 0, screensize.width, screensize.height)
page3.frame = CGRectMake(screensize.width*2, 0, screensize.width, screensize.height)
pagescroll.addSubview(page1)
pagescroll.addSubview(page2)
pagescroll.addSubview(page2)
self.view.addSubview(pagescroll)
// Do any additional setup after loading the view.
}
var pagescroll = UIScrollView()
var page1 = UIView()
var page2 = UIView()
var page3 = UIView()
You can also add a pagecontroller: UIPageControl according to your requirement
Related
I have a UIPageViewController and several ViewControllers in it. And I want to perform a function in UIPageViewController from a ViewController using delegate protocol. But get nil in the delegate. Can anybody determine what I'm doing wrong?
PageViewController.swift
import UIKit
class PageViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource, Storyboarded {
weak var coordinator: MainCoordinator?
lazy var orderedViewControllers: [UIViewController] = {
return [self.newInstanceVC(viewController: "FirstLoadViewController"), self.newInstanceVC(viewController: "FirstLoad2ViewController")]
}()
var pageControl = UIPageControl()
override func viewDidLoad() {
super.viewDidLoad()
let storyboardVC = newInstanceVC(viewController: "FirstLoad2ViewController") as? FirstLoad2ViewController
storyboardVC?.delegate = self
self.dataSource = self
if let firstViewController = orderedViewControllers.first {
setViewControllers([firstViewController], direction: .forward, animated: true, completion: nil)
}
self.delegate = self
configurePageControl()
}
func configurePageControl() {
pageControl = UIPageControl(frame: CGRect(x: 0, y: UIScreen.main.bounds.maxY - 50, width: UIScreen.main.bounds.width, height: 50))
pageControl.numberOfPages = orderedViewControllers.count
pageControl.currentPage = 0
//pageControl.tintColor = .red
pageControl.pageIndicatorTintColor = .systemGray5
pageControl.currentPageIndicatorTintColor = .systemGray
self.view.addSubview(pageControl)
}
//return view controller by string identifier
func newInstanceVC(viewController: String) -> UIViewController {
return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: viewController)
}
//MARK: - Setup page controllers
// view controller that appears on swiping to the -> (left)
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.firstIndex(of: viewController) else {
return nil
}
let previousIndex = viewControllerIndex - 1
guard previousIndex >= 0 else {
//return view controller from the end if it is last index from the left side (infinit scroll)
//return orderedViewControllers.last
return nil
}
guard orderedViewControllers.count >= previousIndex else {
return nil
}
return orderedViewControllers[previousIndex]
}
// view controller that appears on swiping to the <- (right)
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.firstIndex(of: viewController) else {
return nil
}
let nextIndex = viewControllerIndex + 1
guard orderedViewControllers.count != nextIndex else {
//return view controller from the begining if it is last index from the right side (infinit scroll)
//return orderedViewControllers.first
return nil
}
guard orderedViewControllers.count > nextIndex else {
return nil
}
return orderedViewControllers[nextIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
//switch the bullet of the page
let pageContentVievController = pageViewController.viewControllers![0]
self.pageControl.currentPage = orderedViewControllers.firstIndex(of: pageContentVievController)!
}
}
extension PageViewController: PageViewDelegate {
func handleButtonTap() {
coordinator?.goToMainFromPresentation()
}
}
OneOfTheViewControllers.swift
import UIKit
protocol PageViewDelegate: class {
func handleButtonTap()
}
class FirstLoad2ViewController: UIViewController, Storyboarded {
weak var coordinator: MainCoordinator?
weak var child: ChildCoordinator?
weak var delegate: PageViewDelegate?
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func toMainScreenTap(_ sender: Any) {
delegate!.handleButtonTap() //got nil for delegate here
}
}
The problem is simple, it's hiding in your viewDidLoad() method inside PageViewController
...
override func viewDidLoad() {
super.viewDidLoad()
let storyboardVC = newInstanceVC(viewController: "FirstLoad2ViewController") as? FirstLoad2ViewController
storyboardVC?.delegate = self
...
}
/// (storyboardVC) --- will be destroyed when out of viewDidLoad() scope.
So, why you getting your storyboardVC?.delegate = self nil? Because you created storyboardVC property inside viewDidLoad() method and nothing is keeping reference to it. So, at the end viewDidLoad() method it just deinitialize as well as it's PageViewDelegate delegate
I am trying to load appropriate images from an array into my UIPageViewController's Views.
I have 3 views which I cycle through in order to prevent crashes.
I keep track whether I am scrolling forward or backwards but sometimes when flipping forth and back really quick, I run into a bug that flips the direction and than I get the same view repeating for couple of scrolls.
Here is the function that updates the local variable index when scrolling completes
func pageViewController(pvc: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if completed {
let thisPage = pvc.viewControllers!.last as! PageContentViewController
let currentIndex = thisPage.pageIndex
let lastIndex = lastPage.pageIndex
if(currentIndex > urlIndex){
urlIndex += 1
}else if(currentIndex < urlIndex) {
urlIndex -= 1
}else{
}
}
}
And here is the rest of my UIPageViewController code:
override func viewDidLoad() {
super.viewDidLoad()
dataSource = self
delegate = self
}
private(set) lazy var orderedViewControllers: [PageContentViewController] = {
return [self.newPageContentViewController(),
self.newPageContentViewController(),
self.newPageContentViewController()
]
}()
private func newPageContentViewController() -> PageContentViewController {
return UIStoryboard(name: "Main", bundle: nil) .
instantiateViewControllerWithIdentifier("PageContentViewController") as! PageContentViewController
}
private func getNextViewController() -> PageContentViewController{
let scrollView = orderedViewControllers.removeAtIndex(0)
orderedViewControllers.append(scrollView)
return scrollView
}
private func getPreviousViewController() -> PageContentViewController{
let scrollView = orderedViewControllers.removeLast()
orderedViewControllers.insert(scrollView, atIndex: 0)
return scrollView
}
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController?
{
guard urlIndex > 0 else {
return nil
}
let previousUrlIndex = urlIndex - 1
return getViewControllerAtIndex(previousUrlIndex, next: false)
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController?
{
let nextUrlIndex = urlIndex + 1
guard arrayRouteName.count > nextUrlIndex else{
return nil
}
return getViewControllerAtIndex(nextUrlIndex, next: true)
}
func getViewControllerAtIndex(index: NSInteger, next: Bool) -> PageContentViewController
{
// Create a new view controller and pass suitable data.
var pageContentViewController:PageContentViewController
if(next){
pageContentViewController = getNextViewController()
}else{
pageContentViewController = getPreviousViewController()
}
pageContentViewController.localImage = arrayLocalImage[index]
pageContentViewController.pageIndex = index
pageContentViewController.view.clipsToBounds = true
return pageContentViewController
}
I have managed to fix the problem. I have removed the pageViewControllerfunction from the UIPageControllerDelegate an simply chaged my pageViewController functions in my data source to get the index from viewController like so
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController?
{
let index = ((viewController as! UIPageContentViewController).pageIndex) - 1
guard index < 0 {
return nil
}
return getViewControllerAtIndex(index, pageContentViewController: getPreviousViewController() )
}
and it behaves like it should.
I have the following PageViewController class :
class ProjectorPageViewController : UIPageViewController, UIPageViewControllerDataSource {
var randUsed : [String]?
var pageViewMatches : [SingleMatch]? {
didSet {
//irrelevant code
}
let initialcontroller = viewControlerAtIndex(0)
let viewControllers = [initialcontroller!]
setViewControllers(viewControllers, direction: .Forward, animated: true, completion: nil)
}
}
override func viewDidLoad() {
super.viewDidLoad()
dataSource = self
let pageControl = UIPageControl.appearance()
pageControl.currentPageIndicatorTintColor = UIColor.whiteColor()
pageControl.pageIndicatorTintColor = UIColor(red: (69/255.0), green: (209/255.0), blue: (153/255.0), alpha: 1.0)
}
func viewControlerAtIndex(index : Int) -> PageViewContentViewController? {
if (self.pageUsers!.count == 0 || index >= self.pageUsers!.count) {
return nil
}
let controller = PageViewContentViewController()
controller.location = pageLocations![index]
controller.image_name = pageImages![index]
controller.user_name = pageUsers![index]
controller.pageIndex = index
return controller
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
let curr_index = (viewController as! PageViewContentViewController).pageIndex
print ("attempting after with index : " + String(curr_index))
if (curr_index! < pageViewMatches!.count - 1) {
return viewControlerAtIndex(curr_index! + 1) }
else {
return nil
}
}
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
let curr_index = (viewController as! PageViewContentViewController).pageIndex
print ("attempting before with index : " + String(curr_index))
if (curr_index! > 0 ) {
return viewControlerAtIndex(curr_index! - 1)
}
else {
return nil
}
}
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
if let matches = pageViewMatches {
return matches.count
}
else {
return 0
}
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
return pageViewController.viewControllers!.indexOf((pageViewController.viewControllers?.first)!)!
}
}
The problem is that if I swipe fast enough between the pages, the page indicator becomes out of sync, and points to the wrong page. If I swipe at a moderate pace this doesn't occur. I have seen a similar post which said the solution was to implement the presentationIndexForPageViewController method, however translating this from Objective-C (unless I made a mistake in translation) did not solve the problem. Here is the post I am referring to : UIPageViewController setViewControllers, UIPageControl not showing right current number
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
let vc = pageViewController.viewControllers!.first as! PageViewContentViewController
return vc.pageIndex
}
You must return pageIndex... pageViewController.viewControllers!.indexOf((pageViewController.viewControllers?.first)!)! won't return right index
As the title states, there is a way it can return the wrong index. This messes up the index presentation dots at the bottom of the page. The way this is done is by skipping a page without releasing a finger from the screen. If this happens, it messes of the rest of the presentation dots.
here is what the bug it looks like in action.
And here is the code that was used for the UIPageViewController.
import UIKit
class PageViewController: UIPageViewController {
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return UIStatusBarStyle.LightContent
}
private(set) lazy var orderedViewControllers: [UIViewController] = {
return [self.newColoredViewController("Green"),
self.newColoredViewController("Red"),
self.newColoredViewController("Blue")]
}()
private func newColoredViewController(color: String) -> UIViewController {
return UIStoryboard(name: "Main", bundle: nil) .
instantiateViewControllerWithIdentifier("\(color)ViewController")
}
override func viewDidLoad() {
super.viewDidLoad()
dataSource = self
if let firstViewController = orderedViewControllers.first {
setViewControllers([firstViewController],
direction: .Forward,
animated: true,
completion: nil)
}
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
//MARK: UIPageViewControllerDataSource
extension PageViewController: UIPageViewControllerDataSource {
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.indexOf(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, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.indexOf(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 presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return orderedViewControllers.count
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
guard let firstViewController = viewControllers?.first,
firstViewControllerIndex = orderedViewControllers.indexOf(firstViewController) else {
return 0
}
return firstViewControllerIndex
}
}
Any help with this would be greatly appreciated, thanks.
I made a workaround because this is still not fixed!! It has been more than 4 years darn it.
Class to subclass instead of UIPageViewController:
import UIKit
class PageController: UIPageViewController {
lazy var pages: [UIViewController] = []
var newOffset: CGFloat = 20
var showReal = true
var pageControlX: CGFloat = 0 // 0 is the middle of the screen
var pageControlY: CGFloat = 200
private var scrollView: UIScrollView?
private var scrollPoints: [UIView] = []
private var oldScrollPoints: [UIView] = []
private var indexKeeper = IndexKeeper()
private var selectedColor = UIColor(white: 1, alpha: 1)
private var unselectedColor = UIColor(white: 1, alpha: 0.2)
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// whole screen scroll
scrollView = view.subviews.filter{ $0 is UIScrollView }.first! as? UIScrollView
scrollView!.frame = UIScreen.main.bounds
// get pageControl and scroll view from view's subviews
let pageControl = view.subviews.filter{ $0 is UIPageControl }.first! as! UIPageControl
oldScrollPoints = pageControl.subviews
// remove all constraint from view that are tied to pageControl
let const = view.constraints.filter { $0.firstItem as? NSObject == pageControl || $0.secondItem as? NSObject == pageControl }
view.removeConstraints(const)
// customize pageControl
pageControl.translatesAutoresizingMaskIntoConstraints = false
pageControl.frame = CGRect(x: pageControlX, y: pageControlY,
width: view.frame.width, height: 0)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
self.replacePoints()
self.updateIndex()
}
}
private func replacePoints() {
for point in scrollPoints {
point.removeFromSuperview()
}
scrollPoints = []
for oldPoint in oldScrollPoints {
let newPoint = UIView(frame: oldPoint.frame)
// make rounded
newPoint.layer.borderWidth = 0
newPoint.layer.masksToBounds = false
newPoint.layer.cornerRadius = newPoint.frame.height / 2
newPoint.clipsToBounds = true
newPoint.center = CGPoint(x: oldPoint.center.x, y: newOffset)
newPoint.backgroundColor = oldPoint.backgroundColor
oldPoint.superview?.addSubview(newPoint)
scrollPoints.append(newPoint)
oldPoint.alpha = showReal ? 1 : 0
}
}
private func offsetFromFirstPage() -> CGFloat {
var coordinates: [CGFloat] = []
for (index, page) in pages.enumerated() {
let offset = scrollView!.convert(scrollView!.bounds.origin, to: page.view!)
coordinates.append(offset.x + CGFloat(index) * view.frame.width)
}
let duplicates: [CGFloat] = coordinates.enumerated().map
{ current in
if coordinates.firstIndex(of: current.element) != coordinates.lastIndex(of: current.element) {
return current.element
} else {
return .nan
}
}
return duplicates.first(where: { !$0.isNaN }) ?? 0
}
private var lastIndex: Int = 0
private func pageIndexFrom(offset: CGFloat, visibleRatio: CGFloat=0.6) -> Int {
let adjustedOffset = (offset / view.frame.width)
if adjustedOffset > CGFloat(lastIndex) + visibleRatio {
if lastIndex + 1 < pages.count {
lastIndex += 1
}
} else if adjustedOffset < CGFloat(lastIndex) - visibleRatio {
if lastIndex - 1 >= 0 {
lastIndex -= 1
}
}
return lastIndex
}
private func updateIndex() {
let fastIndex = pages.firstIndex(of: viewControllers!.first!)!
indexKeeper.fastIndexUpdate(index: fastIndex)
let offset = offsetFromFirstPage()
let slowIndex = pageIndexFrom(offset: offset)
indexKeeper.slowIndexUpdate(index: slowIndex)
for (index, point) in scrollPoints.enumerated() {
if index == indexKeeper.finalIndex {
point.backgroundColor = selectedColor
} else {
point.backgroundColor = unselectedColor
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
self.updateIndex()
}
}
}
class IndexKeeper {
var finalIndex = 0
private var slowIndex = 0
private var fastIndex = 0
func slowIndexUpdate(index: Int) {
if index != slowIndex {
slowIndex = index
finalIndex = slowIndex
}
}
func fastIndexUpdate(index: Int) {
if index != fastIndex {
fastIndex = index
finalIndex = fastIndex
}
}
}
Example Use:
import UIKit
class PageViewController: PageController, UIPageViewControllerDataSource {
private func pageInstance(name:String) -> UIViewController {
return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: name)
}
override func viewDidLoad() {
super.viewDidLoad()
pages = [
pageInstance(name: "FirstPage"),
pageInstance(name: "SecondPage"),
pageInstance(name: "ThirdPage"),
pageInstance(name: "FourthPage")
]
dataSource = self
setViewControllers([pages.first!], direction: .forward, animated: false, completion: nil)
}
// get page before current page
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let index = pages.firstIndex(of: viewController), index > 0 else {
return nil
}
return pages[index - 1]
}
// get page after current page
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
guard let index = pages.firstIndex(of: viewController), index + 1 < pages.count else {
return nil
}
return pages[index + 1]
}
func presentationCount(for pageViewController: UIPageViewController) -> Int {
return pages.count
}
func presentationIndex(for pageViewController: UIPageViewController) -> Int {
if let vc = viewControllers?.first {
return pages.firstIndex(of: vc)!
}
return 0
}
}
I have the following code in my iOS app:
class BannerTableViewCell: UITableViewCell, UIPageViewControllerDataSource {
private var pageViewController: UIPageViewController!
private var pages: [UIViewController] = []
override func awakeFromNib() {
super.awakeFromNib()
self.backgroundColor = UIColor.clearColor()
self.backgroundView?.backgroundColor = UIColor.clearColor()
self.contentView.backgroundColor = UIColor.clearColor()
self.selectionStyle = UITableViewCellSelectionStyle.None
pageViewController = UIPageViewController();
self.pageViewController.dataSource = self
pageViewController.view.frame = CGRect(x: 0, y: 0, width: UIScreen.mainScreen().bounds.width, height: 130)
self.addSubview(pageViewController.view)
//Example data
let v1 = UIViewController()
v1.view.frame = CGRect(x: 0, y: 0, width: UIScreen.mainScreen().bounds.width, height: 130);
v1.view.backgroundColor = UIColor.blueColor()
let v2 = UIViewController()
v2.view.frame = CGRect(x: 0, y: 0, width: UIScreen.mainScreen().bounds.width, height: 130);
v2.view.backgroundColor = UIColor.greenColor()
pages.append(v1)
pages.append(v2)
}
func pageViewController(pageViewController: UIPageViewController,
viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = pages.indexOf(viewController) else {
return nil
}
let previousIndex = viewControllerIndex - 1
guard previousIndex >= 0 else {
return nil
}
guard pages.count > previousIndex else {
return nil
}
return pages[previousIndex]
}
func pageViewController(pageViewController: UIPageViewController,
viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = pages.indexOf(viewController) else {
return nil
}
let nextIndex = viewControllerIndex + 1
let orderedViewControllersCount = pages.count
guard orderedViewControllersCount != nextIndex else {
return nil
}
guard orderedViewControllersCount > nextIndex else {
return nil
}
return pages[nextIndex]
}
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return pages.count
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
return 0
}
}
I instantiate this cell in the table view, however page view controller in this cell is always empty, and the data source methods of pageViewController are not called. Do you have any idea why they are not called?
You should use the documented initializer to instantiate the UIPageViewController:
public init(transitionStyle style: UIPageViewControllerTransitionStyle, navigationOrientation: UIPageViewControllerNavigationOrientation, options: [String : AnyObject]?)
Also the ViewControllers you create at the end of awakeFromNib can be placed into the pageViewController right away.
pageViewController.setViewControllers([v1, v2], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)
A page indicator will be visible if both methods are implemented, transition style is 'UIPageViewControllerTransitionStyleScroll', and navigation orientation is 'UIPageViewControllerNavigationOrientationHorizontal'.
Both methods are called in response to a 'setViewControllers:...' call, but the presentation index is updated automatically in the case of gesture-driven navigation.
It could also be because the Page View Controller is not your Root View Controller.
You could add the following code in your segue:
let x = (UIApplication.shared.delegate as! AppDelegate).window!
x.rootViewController = yourViewController()