1

I have a UIViewController and I added UIPageViewController by programmatically. How to stop the bounce (scrolling) the UIViewController if we are at 0 index or last index? I mean bounce.

You can check this link: How to create PageView with UITabBar or Segment Control using swift?

And here is my code:

import UIKit

class ViewController: UIViewController {

fileprivate var pageViewController:UIPageViewController!
@IBOutlet weak var paginationView:UIView!
@IBOutlet var btnYourGroup: UIButton!
@IBOutlet var btnSharedBy: UIButton!
@IBOutlet var sliderViewLeadingConst: NSLayoutConstraint!

fileprivate var selectedIndex : Int? {
    didSet {
        var leading:CGFloat = 0
        if selectedIndex == 0 {
            leading = 0
        }
        else {
            leading = self.view.frame.size.width/2
        }

        self.sliderViewLeadingConst.constant = leading

        UIView.animate(withDuration: 0.2, animations: {

            self.view.layoutIfNeeded()
        })
    }
}

override func viewDidLoad() {
    super.viewDidLoad()

    //SetUp Pagination
    setupPagination()

    for view in self.pageViewController.view.subviews {
        if let scrollView = view as? UIScrollView {
            scrollView.delegate = self
            break
        }
    }

    //btnSharedBy.titleColor(for: UIControlState)
    btnSharedBy.setTitleColor(UIColor.lightGray, for: UIControlState())
}

private func setupPagination() {

    let startVC = self.viewControllerAtIndex(index: 0)
    let vc = [startVC]
    self.pageViewController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
    self.pageViewController.setViewControllers(vc, direction: .reverse, animated: true, completion: nil)
    self.pageViewController.dataSource = self
    self.pageViewController.delegate = self
    self.pageViewController.view.frame.size = self.paginationView.frame.size
    self.paginationView.addSubview(self.pageViewController.view)
}

@IBAction func mainCateogryTapped(sender:UIButton) {
    loadNextController(index:sender.tag)
}

fileprivate func viewControllerAtIndex(index:Int) -> PageContentViewController {

    let feedsVC = self.storyboard?.instantiateViewController(withIdentifier: "PageContentViewController") as! PageContentViewController
    feedsVC.pageIndex = index
    return feedsVC
}

fileprivate func loadNextController(index:Int) {

    if selectedIndex == index {
        return
    }

    let nextViewController = viewControllerAtIndex(index:index)
    selectedIndex = index

    if index == 0 {
        btnSharedBy.setTitleColor(UIColor.lightGray, for: UIControlState())
        btnYourGroup.setTitleColor(UIColor.white, for: UIControlState())
        self.pageViewController?.setViewControllers([nextViewController], direction: UIPageViewControllerNavigationDirection.reverse, animated: true, completion: nil)
    } else if index == 1 {
        btnSharedBy.setTitleColor(UIColor.white, for: UIControlState())
        btnYourGroup.setTitleColor(UIColor.lightGray, for: UIControlState())
        self.pageViewController?.setViewControllers([nextViewController], direction: UIPageViewControllerNavigationDirection.forward, animated: true, completion: nil)
    }

    else {

    }
  }
}
extension ViewController: UIPageViewControllerDataSource {

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

    var index = (viewController as! PageContentViewController).pageIndex

    if index == 0 {
        return nil
    }
    index = index - 1
    return viewControllerAtIndex(index:index)

}

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

    var index = (viewController as! PageContentViewController).pageIndex

    index = index + 1
    if index == 2 {
        //self.pageViewController.
        return nil
    }
    return viewControllerAtIndex(index:index)
}

func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {

    let vc : PageContentViewController = pendingViewControllers[0] as! PageContentViewController
    selectedIndex = vc.pageIndex
  }
}

extension ViewController : UIPageViewControllerDelegate {

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
    if completed {
        let vc = previousViewControllers.first as! PageContentViewController

        if 0 == vc.pageIndex {
            selectedIndex = 1
            btnSharedBy.setTitleColor(UIColor.white, for: UIControlState())
            btnYourGroup.setTitleColor(UIColor.lightGray, for: UIControlState())

        }

        else {
            btnYourGroup.setTitleColor(UIColor.white, for: UIControlState())
            btnSharedBy.setTitleColor(UIColor.lightGray, for: UIControlState())
            selectedIndex = 0
        }
    }

    else if !completed {
        let pageContentView = previousViewControllers[0] as! PageContentViewController;
        self.selectedIndex = pageContentView.pageIndex
    }
  }
}

//ScrollView Delegate
extension ViewController : UIScrollViewDelegate {

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let point = scrollView.contentOffset
    var percentComplete: CGFloat
    percentComplete = fabs(point.x - view.frame.size.width)/view.frame.size.width
    //NSLog("percentComplete: %f", percentComplete)

        if(0.8 > percentComplete)
        {
            //selectedIndex = 1
            scrollView.bounces = false
        }

        else
        {
            scrollView.bounces = true

        }
    }
}

How can I stop bouncing problem at first and last index with button indicator also?

halfer
  • 19,824
  • 17
  • 99
  • 186
Kishor Pahalwani
  • 1,010
  • 1
  • 23
  • 53

1 Answers1

2

You might be able to walk the page view controller's subviews, looking for it's scroll view, and set bounces to false. This is a fragile solution however, and ill advised. (It's generally a bad idea to mess with a view controller's views, especially if there isn't a public interface to find them.)

The thread below has code that walks a page view controller's subviews and finds the scroll view. It would be easy to adapt that code to set the bounces property to false:

Progress of UIPageViewController

Community
  • 1
  • 1
Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • OK Thanks I will try this. But it would better if you can see my code once and tell me where I have to change. Thanks – Kishor Pahalwani Feb 02 '17 at 05:41
  • Put the changes I suggested in viewDidLoad. I'm not going to write it for you. I found you a link to code that finds the scroll view. It should be simple to adapt that code to change the bounces property of the scroll view to false. – Duncan C Feb 02 '17 at 11:49
  • Ok I will check. Thanks – Kishor Pahalwani Feb 02 '17 at 12:09
  • If we press buttons and scroll the view, it fails. How can we stop please help. Thanks – Kishor Pahalwani Feb 02 '17 at 13:39
  • "It fails" is not at all helpful. Be specific about what happens, both from the user perspective, and what you see in Xcode, or there's no way we can help you. You also need to update your question to append your new code at the end. – Duncan C Feb 02 '17 at 14:34
  • I edited my code just now. In ScrollViewDelegate method I put the condition its working fine while scrolling but when I press my buttons then scrollView bounce is becoming false. Thanks – Kishor Pahalwani Feb 03 '17 at 05:10