Skip to content

Commit

Permalink
Add features & fixes
Browse files Browse the repository at this point in the history
1. Feature to programatically move to any view controller is added
2. Feature to update the tabs is added
3. Readme is updated & function comments are updated to support latest xcode version
  • Loading branch information
nrlnishan committed Jun 1, 2017
1 parent 5c9dbd4 commit 0354211
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 58 deletions.
14 changes: 14 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,20 @@ called when transiton to another view controller is completed
```
optional func didMoveToControllerAtIndex(index:Int)
```

**Additional**

You can also change the page programatically. Suppose you want to display 3rd page.
```
viewpager.displayViewController(atIndex: 2) // Since index starts from 0
```

Also, you can update any of the viewpager tab. Just update the ViewPagerTab array which you are providing through the datasource. and then call
```
viewpager.invalidateTabs()
```


## Customization ##
You can perform lots of customization. If you want to look under the hoods, all the **public variables** inside ViewPagerOptions.swift file is customizable.

Expand Down
103 changes: 50 additions & 53 deletions ViewPager-Swift/Core/ViewPagerController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@ import UIKit

@objc protocol ViewPagerControllerDataSource {

// Number of pages to be displayed
/// Number of pages to be displayed
func numberOfPages() -> Int

// ViewController for required page position
/// ViewController for required page position
func viewControllerAtPosition(position:Int) -> UIViewController

// Tab structure of the pages
/// Tab structure of the pages
func tabsForPages() -> [ViewPagerTab]

//ViewController to start from
/// ViewController to start from
@objc optional func startViewPagerAtIndex()->Int
}

Expand Down Expand Up @@ -59,9 +59,7 @@ class ViewPagerController:UIViewController {
MARK:- Viewpager tab setup
---------------------------*/

/**
* Prepares the container for holding all the tabviews.
*/
/// Prepares the container for holding all the tabviews.
fileprivate func setupTabContainerView() {

// Creating container for Tab View
Expand All @@ -87,9 +85,7 @@ class ViewPagerController:UIViewController {
}


/**
* Creates and adds each tabs according to the options provided in tabcontainer.
*/
///Creates and adds each tabs according to the options provided in tabcontainer.
fileprivate func setupTabs() {

var totalWidth:CGFloat = 0
Expand Down Expand Up @@ -154,15 +150,14 @@ class ViewPagerController:UIViewController {
}
}

/**
* Sets up indicator for the page if enabled in ViewPagerOption. This method shows either tabIndicator
* or Highlights current tab or both.
*/
func setupCurrentPageIndicator(currentIndex: Int, previousIndex: Int) {

/// Sets up indicator for the page if enabled in ViewPagerOption. This method shows either tabIndicator or Highlights current tab or both.
fileprivate func setupCurrentPageIndicator(currentIndex: Int, previousIndex: Int) {

if options.isTabHighlightAvailable! {

self.tabsViewList[previousIndex].removeHighlight(options: self.options)

UIView.animate(withDuration: 0.8, animations: {

self.tabsViewList[currentIndex].addHighlight(options: self.options)
Expand Down Expand Up @@ -190,6 +185,8 @@ class ViewPagerController:UIViewController {
isIndicatorAdded = true
}

self.tabContainer.bringSubview(toFront: tabIndicator)

UIView.animate(withDuration: 0.5, animations: {

self.tabContainer.scrollRectToVisible(tabIndicatorFrame, animated: false)
Expand All @@ -203,9 +200,7 @@ class ViewPagerController:UIViewController {
MARK:- Tab setup helpers
---------------------------*/

/**
* Gesture recognizer for determining which tabview was tapped
*/
/// Gesture recognizer for determining which tabview was tapped
func tabContainerTapped(_ recognizer:UITapGestureRecognizer) {

let tapLocation = recognizer.location(in: self.tabContainer)
Expand All @@ -215,15 +210,11 @@ class ViewPagerController:UIViewController {

if tabViewIndex != currentPageIndex {

let prev = currentPageIndex
setupCurrentPageIndicator(currentIndex: tabViewIndex ?? 0, previousIndex: currentPageIndex)
displayViewController(atIndex: tabViewIndex ?? 0, inForwardDirection: tabViewIndex ?? 0 > prev)
displayViewController(atIndex: tabViewIndex ?? 0)
}
}

/**
* Determines the orientation change and sets up the tab size and its indicator size accordingly.
*/
/// Determines the orientation change and sets up the tab size and its indicator size accordingly.
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {

DispatchQueue.main.async {
Expand All @@ -249,9 +240,7 @@ class ViewPagerController:UIViewController {

}

/**
* Determines maximum width between two provided value and returns it
*/
/// Determines maximum width between two provided value and returns it
fileprivate func getMaximumWidth(maxWidth:CGFloat, withWidth currentWidth:CGFloat) -> CGFloat {

return (maxWidth > currentWidth) ? maxWidth : currentWidth
Expand Down Expand Up @@ -289,12 +278,10 @@ class ViewPagerController:UIViewController {

}

/**
* Returns UIViewController for page at provided index.
*/
/// Returns UIViewController for page at provided index.
fileprivate func getPageItemViewController(atIndex index:Int) -> UIViewController? {

if index < dataSource.numberOfPages() {
if index >= 0 && index < dataSource.numberOfPages() {

let pageItemViewController = dataSource.viewControllerAtPosition(position: index)
pageItemViewController.view.tag = index
Expand All @@ -304,35 +291,54 @@ class ViewPagerController:UIViewController {
return nil
}

/**
* Sets the visible view controller with the view controller at provided index.
*/
fileprivate func displayViewController(atIndex index:Int,inForwardDirection:Bool) {

/// Displays the UIViewController provided at given index in datasource.
///
/// - Parameter index: position of the view controller to be displayed. 0 is first UIViewController
func displayViewController(atIndex index:Int) {

let chosenViewController = getPageItemViewController(atIndex: index)!
delegate?.willMoveToControllerAtIndex?(index: index)
pageViewController!.setViewControllers([chosenViewController], direction: inForwardDirection ? .forward : .reverse, animated: true, completion: { (isCompleted) in

let previousIndex = currentPageIndex
let direction:UIPageViewControllerNavigationDirection = (index > previousIndex ) ? .forward : .reverse
setupCurrentPageIndicator(currentIndex: index, previousIndex: currentPageIndex)

pageViewController!.setViewControllers([chosenViewController], direction: direction, animated: true, completion: { (isCompleted) in

if isCompleted {
self.delegate?.didMoveToControllerAtIndex?(index: index)
}
})
}

/// Invalidate the current tabs shown and reloads the new tabs provided in datasource.
func invalidateTabs() {

// Removing all the tabs from tabContainer
_ = tabsViewList.map({ $0.removeFromSuperview() })

tabsList.removeAll()
tabsViewList.removeAll()

setupTabs()
setupCurrentPageIndicator(currentIndex: currentPageIndex, previousIndex: currentPageIndex)
}

}

// MARK:- UIPageViewController Delegates

extension ViewPagerController: UIPageViewControllerDelegate {

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {

if completed {
if completed && finished {

let pageIndex = pageViewController.viewControllers?.first?.view.tag
setupCurrentPageIndicator(currentIndex: pageIndex!, previousIndex: currentPageIndex)
delegate?.didMoveToControllerAtIndex?(index: pageIndex!)
}

}

func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
Expand All @@ -341,31 +347,22 @@ extension ViewPagerController: UIPageViewControllerDelegate {
delegate?.willMoveToControllerAtIndex?(index: pageIndex!)
}


}

// MARK:- UIPageViewController Datasource

extension ViewPagerController:UIPageViewControllerDataSource {

/**
* ViewController the user will navigate to in backward direction
*/
/* ViewController the user will navigate to in backward direction */
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {

if viewController.view.tag > 0 {
return getPageItemViewController(atIndex: viewController.view.tag - 1)
}
return nil
return getPageItemViewController(atIndex: viewController.view.tag - 1)
}

/**
* ViewController the user will navigate to in forward direction
*/
/* ViewController the user will navigate to in forward direction */
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {

if viewController.view.tag + 1 < dataSource.numberOfPages() {
return getPageItemViewController(atIndex: viewController.view.tag + 1)
}
return nil
return getPageItemViewController(atIndex: viewController.view.tag + 1)
}

}
Expand Down
4 changes: 2 additions & 2 deletions ViewPager-Swift/Core/ViewPagerTab.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ enum ViewPagerTabType {

class ViewPagerTab:NSObject {

let title:String!
let image:UIImage?
var title:String!
var image:UIImage?

init(title:String, image:UIImage?) {
self.title = title
Expand Down
10 changes: 7 additions & 3 deletions ViewPager-Swift/MainViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class MainViewController: UIViewController {
ViewPagerTab(title: "Water", image: UIImage(named: "water"))
]

let tabs = [
var tabs = [
ViewPagerTab(title: "Fries", image: UIImage(named: "fries")),
ViewPagerTab(title: "Hamburger", image: UIImage(named: "hamburger")),
ViewPagerTab(title: "Beer", image: UIImage(named: "pint")),
Expand All @@ -40,6 +40,7 @@ class MainViewController: UIViewController {
ViewPagerTab(title: "Sandwich", image: UIImage(named: "sandwich"))
]

var viewPager:ViewPagerController!

override func viewDidLoad() {
super.viewDidLoad()
Expand All @@ -56,7 +57,7 @@ class MainViewController: UIViewController {
options.tabViewPaddingRight = 20
options.isTabHighlightAvailable = true

let viewPager = ViewPagerController()
viewPager = ViewPagerController()
viewPager.options = options
viewPager.dataSource = self
viewPager.delegate = self
Expand All @@ -65,7 +66,6 @@ class MainViewController: UIViewController {
self.view.addSubview(viewPager.view)
viewPager.didMove(toParentViewController: self)
}

}


Expand All @@ -84,6 +84,10 @@ extension MainViewController: ViewPagerControllerDataSource {
func tabsForPages() -> [ViewPagerTab] {
return tabs
}

func startViewPagerAtIndex() -> Int {
return 0
}
}

extension MainViewController: ViewPagerControllerDelegate {
Expand Down

0 comments on commit 0354211

Please sign in to comment.