Uipageviewcontroller with Previous and Next Buttons

Using next button on PageViewController

You need to use this inside a UIPageViewController subclass

self.setViewControllers([someVC], direction: .forward, animated: true, completion: nil)

how to be back to previous VC or next VC from a view controller inside UIPageViewController?

So, in your RootPageViewController, you could have a function there that will use setViewControllers.

And that setViewControllers is described as:

// Set visible view controllers, optionally with animation. Array
should only include view controllers that will be visible after the
animation has completed.
// For transition style 'UIPageViewControllerTransitionStylePageCurl', if 'doubleSided' is
'YES' and the spine location is not
'UIPageViewControllerSpineLocationMid', two view controllers must be
included, as the latter view controller is used as the back.

So let's try to have a Next function.

func next() {
let vcs = self.viewControllerList
//or self.viewControllers
let currentPage = self.pageControl.currentPage
let nextPage = currentPage + 1

if nextPage < vcs.count {
let nextVC = vcs[nextPage]
self.setViewControllers([nextVC], direction: .forward, animated: true) { _ in
self.pageControl.currentPage = nextPage
}
}
}

As you can see, we are safely getting a viewController from the vcs you made in your code, which contains all the pages. And after we get the next viewController, if there's any, we use the setViewControllers. To make it better, we're setting the currentPage of your pageControl to tell which circle at the bottom of your pageController to be colored.

And then from your BlueVC, get a reference of your pageController. How? By accessing the self.parent and cast it as your RootPageViewController. Like so:

@IBAction func next(_ sender: Any) {
if let parentVC = self.parent as? RootPageViewController {
parentVC.next()
}
}

Now, it's your task to implement the previous function.

iOS: UIPageViewController - Use button to jump to next page

You can programmatically set the currently displayed view controller with a transition animation using setViewControllers:direction:animated:completion: on your page view controller.

Here is an example that presents view controllers with random background colors. You can adjust this to use your specific view controllers.

- (void)viewDidLoad
{
[super viewDidLoad];
self.pvc = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
self.pvc.view.frame = CGRectInset(self.view.bounds, 200, 200);
[self.view addSubview:self.pvc.view];

[self.pvc setViewControllers:@[[self randomVC]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
}

-(UIViewController*)randomVC
{
UIViewController *vc = [[UIViewController alloc] init];
UIColor *color = [UIColor colorWithRed:arc4random_uniform(255)/255.0 green:arc4random_uniform(255)/255.0 blue:arc4random_uniform(255)/255.0 alpha:1];
vc.view.backgroundColor = color;
return vc;
}

- (IBAction)previousButtonPressed:(id)sender {
[self.pvc setViewControllers:@[[self randomVC]] direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:nil];
}

- (IBAction)nextButtonPressed:(id)sender {
[self.pvc setViewControllers:@[[self randomVC]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
}

How do I navigate forward and backward within UIPageViewController using buttons?

I think what you're looking for is here. But this is another way.

UIPageViewController has an instance method transition. The snippet below will move from the first to the second page child view controller.

pageViewController.transition(from: pageViewController.viewControllers[0], to: pageViewController.viewControllers[1], duration: 0.3, options: UIViewAnimationOptions.curveEaseInOut, animations: nil, completion: nil)

PageVC currently changes pages by swiping, but I want to be able to navigate backward and forward through view controllers using two buttons

Add your buttons to page content, then disable horizontal scrolling on PageVC's scrollview or disable views' user interaction in a mannered fashion.

How Can I slide Views programmatically using buttons with existing UIPageViewController

First, PageViewController instantiates a child controller which instantiates a PageViewController.. Is that really a good idea? Then in your toFirstTapped, you instantiate a FirstViewController but do nothing with it..

If you do nothing with it, how do you expect it to work?

In any case, try the below:

protocol PageNavigationDelegate : class {
weak var pageController: PageViewController? { get set }
}

class PageViewController: UIPageViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.setViewControllers([getFirst()], direction: .forward, animated: true, completion: nil)
self.dataSource = self as UIPageViewControllerDataSource
}
}

extension PageViewController : UIPageViewControllerDataSource {

func getFirst() -> FirstViewController {
let controller = storyboard!.instantiateViewController(withIdentifier: "FirstViewController") as! FirstViewController
controller.pageController = self
return controller
}

func getSecond() -> SecondViewController {
let controller = storyboard!.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
controller.pageController = self
return controller
}

func getThird() -> ThirdViewController {
let controller = storyboard!.instantiateViewController(withIdentifier: "ThirdViewController") as! ThirdViewController
controller.pageController = self
return controller
}

@discardableResult
func goToPreviousPage() -> Bool {
let controller = self.viewControllers!.first!
if controller.isKind(of: SecondViewController.self) {
self.setViewControllers([getFirst()], direction: .reverse, animated: true, completion: nil)
return true
}

if controller.isKind(of: ThirdViewController.self) {
self.setViewControllers([getSecond()], direction: .reverse, animated: true, completion: nil)
return true
}

return false
}

@discardableResult
func goToNextPage() -> Bool {
let controller = self.viewControllers!.first!
if controller.isKind(of: FirstViewController.self) {
self.setViewControllers([getSecond()], direction: .forward, animated: true, completion: nil)
return true
}

if controller.isKind(of: SecondViewController.self) {
self.setViewControllers([getThird()], direction: .forward, animated: true, completion: nil)
return true
}

return false
}

func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {

if viewController.isKind(of: SecondViewController.self) {
return getFirst()
}

if viewController.isKind(of: ThirdViewController.self) {
return getSecond()
}

return nil
}

func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {

if viewController.isKind(of: FirstViewController.self) {
return getSecond()
}

if viewController.isKind(of: SecondViewController.self) {
return getThird()
}

return nil
}
}

class PageNavigationController : UIViewController, PageNavigationDelegate {
var pageController: PageViewController?

override func viewDidLoad() {
super.viewDidLoad()
}

@IBAction func goToPreviousController(_ sender: Any) {
pageController?.goToPreviousPage()
}

@IBAction func goToNextController(_ sender: Any) {
pageController?.goToNextPage()
}
}

class FirstViewController: PageNavigationController {

}

class SecondViewController: PageNavigationController {

}

class ThirdViewController: PageNavigationController {

}

First we created a protocol. We made sure that all our PageController's sub-controllers will implement it. This way, they can navigate to previous and next pages..

Next, we create our extension which has the goToPreviousPage and goToNextPage function.. When we instantiate each controller page, we assign self to its protocol implementation variable. That way, the controller can access the PageViewController's methods..

Finally, in our First, Second, and Third controllers, we just tell it to go forward or backward on button press.

Personally, I'd prefer to keep track of controllers in an array and just return those in my delegates.



Related Topics



Leave a reply



Submit