From 2b620d95782193d9df7a662a25c6f4ce1c3c3086 Mon Sep 17 00:00:00 2001 From: Martin Barreto Date: Thu, 21 Jan 2016 13:09:56 -0300 Subject: [PATCH 1/3] polish code --- Sources/PagerTabStripViewController.swift | 63 +++++++++---------- ...SegmentedPagerTabStripViewController.swift | 6 +- 2 files changed, 33 insertions(+), 36 deletions(-) diff --git a/Sources/PagerTabStripViewController.swift b/Sources/PagerTabStripViewController.swift index 12b3f5f..2cad447 100644 --- a/Sources/PagerTabStripViewController.swift +++ b/Sources/PagerTabStripViewController.swift @@ -69,7 +69,25 @@ public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate return CGRectGetWidth(containerView.bounds) } - override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { + public var scrollPercentage: CGFloat { + if swipeDirection != .Right { + let module = fmod(containerView.contentOffset.x, pageWidth) + return module == 0.0 ? 1.0 : module / pageWidth + } + return 1 - fmod(containerView.contentOffset.x >= 0 ? containerView.contentOffset.x : pageWidth + containerView.contentOffset.x, pageWidth) / pageWidth + } + + public var swipeDirection: SwipeDirection { + if containerView.contentOffset.x > lastContentOffset { + return .Left + } + else if containerView.contentOffset.x < lastContentOffset { + return .Right + } + return .None + } + + public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) delegate = self datasource = self @@ -84,7 +102,7 @@ public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate override public func viewDidLoad() { super.viewDidLoad() if containerView.superview == nil { - view.addSubview(containerView!) + view.addSubview(containerView) } containerView.bounces = true containerView.alwaysBounceHorizontal = true @@ -97,16 +115,15 @@ public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate guard let dataSource = datasource else { fatalError("dataSource must not be nil") } - let childViewControllers = dataSource.childViewControllersForPagerTabStripViewController(self) - guard childViewControllers.count != 0 else { + viewControllers = dataSource.childViewControllersForPagerTabStripViewController(self) + guard viewControllers.count != 0 else { fatalError("childViewControllersForPagerTabStripViewController should provide at least one child view controller") } - viewControllers = childViewControllers } override public func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) - lastSize = containerView!.bounds.size + lastSize = containerView.bounds.size updateIfNeeded() } @@ -166,21 +183,11 @@ public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate //MARK: - Helpers public func updateIfNeeded() { - if !CGSizeEqualToSize(lastSize, containerView!.bounds.size){ + if !CGSizeEqualToSize(lastSize, containerView.bounds.size){ updateContent() } } - public func swipeDirection() -> SwipeDirection { - if containerView.contentOffset.x > lastContentOffset { - return .Left - } - else if containerView.contentOffset.x < lastContentOffset { - return .Right - } - return .None - } - public func canMoveToIndex(index index: Int) -> Bool{ return currentIndex != index && viewControllers.count > index } @@ -200,12 +207,12 @@ public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate return offsetForChildIndex(index: index) } - public func pageForContentOffset(contentOffset contentOffset: CGFloat) -> Int{ - let result = self.virtualPageForContentOffset(contentOffset: contentOffset) - return self.pageForVirtualPage(virtualPage: result) + public func pageForContentOffset(contentOffset contentOffset: CGFloat) -> Int { + let result = virtualPageForContentOffset(contentOffset: contentOffset) + return pageForVirtualPage(virtualPage: result) } - public func virtualPageForContentOffset(contentOffset contentOffset: CGFloat) -> Int{ + public func virtualPageForContentOffset(contentOffset contentOffset: CGFloat) -> Int { return Int((contentOffset + 1.5 * pageWidth) / pageWidth) - 1 } @@ -217,16 +224,6 @@ public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate return virtualPage } - public func scrollPercentage() -> CGFloat{ - if swipeDirection() != .Right { - if fmod(containerView.contentOffset.x, pageWidth) == 0.0{ - return 1.0 - } - return fmod(containerView.contentOffset.x, pageWidth) / pageWidth - } - return 1 - fmod(containerView.contentOffset.x >= 0 ? containerView!.contentOffset.x : pageWidth + containerView.contentOffset.x, pageWidth) / pageWidth; - } - public func updateContent() { if !CGSizeEqualToSize(lastSize, containerView.bounds.size) { if lastSize.width != containerView.bounds.size.width { @@ -283,11 +280,11 @@ public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate if pagerOptions.contains(.IsProgressiveIndicator) { // FIXME: - check if delegate implements? pagerTabStripViewController(pagerTabStripViewController: XLPagerTabStripViewController, updateIndicatorFromIndex fromIndex: Int, toIndex index: Int, withProgressPercentage progressPercentage: Float, indexWasChanged changed: Bool) - let scrollPercentage = self.scrollPercentage() + let scrollPercentage = self.scrollPercentage if scrollPercentage > 0 { var fromIndex = currentIndex var toIndex = currentIndex - let direction = swipeDirection() + let direction = swipeDirection if direction == .Left { if virtualPage > getPagerTabStripChildViewControllersForScrolling.count - 1 { diff --git a/Sources/SegmentedPagerTabStripViewController.swift b/Sources/SegmentedPagerTabStripViewController.swift index e6b3d9f..0e00dc6 100644 --- a/Sources/SegmentedPagerTabStripViewController.swift +++ b/Sources/SegmentedPagerTabStripViewController.swift @@ -81,11 +81,11 @@ public class SegmentedPagerTabStripViewController: PagerTabStripViewController { override public func pagerTabStripViewController(pagerTabStripViewController: PagerTabStripViewController, updateIndicatorFromIndex fromIndex: Int, toIndex: Int) throws { try super.pagerTabStripViewController(pagerTabStripViewController, updateIndicatorFromIndex: fromIndex, toIndex: toIndex) - if shouldUpdateSegmentedControl { + if shouldUpdateSegmentedControl { guard let child = viewControllers[toIndex] as? PagerTabStripChildItem else { throw PagerTabStripError.CurrentIndexIsGreaterThanChildsCount } - if let color = child.childHeaderForPagerTabStripViewController(self).color{ + if let color = child.childHeaderForPagerTabStripViewController(self).color { segmentedControl.tintColor = color } segmentedControl.selectedSegmentIndex = toIndex @@ -93,7 +93,7 @@ public class SegmentedPagerTabStripViewController: PagerTabStripViewController { } public override func pagerTabStripViewController(pagerTabStripViewController: PagerTabStripViewController, updateIndicatorFromIndex fromIndex: Int, toIndex index: Int, withProgressPercentage progressPercentage: Float, indexWasChanged changed: Bool) throws { - if shouldUpdateSegmentedControl{ + if shouldUpdateSegmentedControl { let currentIndex = (progressPercentage > 0.5) ? index : fromIndex guard let child = viewControllers[currentIndex] as? PagerTabStripChildItem else { throw PagerTabStripError.CurrentIndexIsGreaterThanChildsCount From bc124e206863fff704d24c4394aea44407bd29af Mon Sep 17 00:00:00 2001 From: Martin Barreto Date: Thu, 21 Jan 2016 14:45:43 -0300 Subject: [PATCH 2/3] polish code --- Sources/PagerTabStripViewController.swift | 70 ++++++++----------- ...SegmentedPagerTabStripViewController.swift | 4 +- 2 files changed, 32 insertions(+), 42 deletions(-) diff --git a/Sources/PagerTabStripViewController.swift b/Sources/PagerTabStripViewController.swift index 2cad447..6dcf7d5 100644 --- a/Sources/PagerTabStripViewController.swift +++ b/Sources/PagerTabStripViewController.swift @@ -137,17 +137,18 @@ public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate } public func moveToViewControllerAtIndex(index: Int, animated: Bool) { - if !isViewLoaded() || view.window == nil { + guard isViewLoaded() && view.window != nil else { currentIndex = index + return } if animated && pagerOptions.contains(.SkipIntermediateViewControllers) && abs(currentIndex - index) > 1 { - var tmpChildViewControllers = viewControllers + var tmpViewControllers = viewControllers let currentChildVC = viewControllers[currentIndex] let fromIndex = currentIndex < index ? index - 1 : index + 1 let fromChildVC = viewControllers[fromIndex] - tmpChildViewControllers[currentIndex] = fromChildVC - tmpChildViewControllers[fromIndex] = currentChildVC - pagerTabStripChildViewControllersForScrolling = tmpChildViewControllers + tmpViewControllers[currentIndex] = fromChildVC + tmpViewControllers[fromIndex] = currentChildVC + pagerTabStripChildViewControllersForScrolling = tmpViewControllers containerView.setContentOffset(CGPointMake(pageOffsetForChildIndex(index: fromIndex), 0), animated: false) (navigationController?.view ?? view).userInteractionEnabled = false containerView.setContentOffset(CGPointMake(pageOffsetForChildIndex(index: index), 0), animated: true) @@ -188,11 +189,11 @@ public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate } } - public func canMoveToIndex(index index: Int) -> Bool{ + public func canMoveToIndex(index index: Int) -> Bool { return currentIndex != index && viewControllers.count > index } - public func pageOffsetForChildIndex(index index: Int) -> CGFloat{ + public func pageOffsetForChildIndex(index index: Int) -> CGFloat { return CGFloat(index) * CGRectGetWidth(containerView.bounds) } @@ -220,25 +221,23 @@ public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate if virtualPage < 0 { return 0 } - if virtualPage > viewControllers.count - 1 { return viewControllers.count - 1 } + if virtualPage > viewControllers.count - 1 { + return viewControllers.count - 1 + } return virtualPage } public func updateContent() { - if !CGSizeEqualToSize(lastSize, containerView.bounds.size) { - if lastSize.width != containerView.bounds.size.width { - lastSize = containerView.bounds.size - containerView.contentOffset = CGPointMake(pageOffsetForChildIndex(index: currentIndex), 0) - } - else { - lastSize = containerView.bounds.size - } + if lastSize.width != containerView.bounds.size.width { + lastSize = containerView.bounds.size + containerView.contentOffset = CGPointMake(pageOffsetForChildIndex(index: currentIndex), 0) } + lastSize = containerView.bounds.size - let childViewControllers = getPagerTabStripChildViewControllersForScrolling - containerView.contentSize = CGSizeMake(CGRectGetWidth(containerView.bounds) * CGFloat(childViewControllers.count), containerView.contentSize.height) + let pagerViewControllers = pagerTabStripChildViewControllersForScrolling ?? viewControllers + containerView.contentSize = CGSizeMake(CGRectGetWidth(containerView.bounds) * CGFloat(pagerViewControllers.count), containerView.contentSize.height) - for (index, childController) in childViewControllers.enumerate(){ + for (index, childController) in pagerViewControllers.enumerate(){ let pageOffsetForChild = pageOffsetForChildIndex(index: index) if fabs(containerView.contentOffset.x - pageOffsetForChild) < CGRectGetWidth(containerView.bounds) { if childController.parentViewController == nil { @@ -287,9 +286,9 @@ public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate let direction = swipeDirection if direction == .Left { - if virtualPage > getPagerTabStripChildViewControllersForScrolling.count - 1 { - fromIndex = getPagerTabStripChildViewControllersForScrolling.count - 1 - toIndex = getPagerTabStripChildViewControllersForScrolling.count + if virtualPage > pagerViewControllers.count - 1 { + fromIndex = pagerViewControllers.count - 1 + toIndex = pagerViewControllers.count } else { if scrollPercentage >= 0.5 { @@ -307,7 +306,7 @@ public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate } else { if scrollPercentage > 0.5 { - fromIndex = min(toIndex + 1, getPagerTabStripChildViewControllersForScrolling.count - 1) + fromIndex = min(toIndex + 1, pagerViewControllers.count - 1) } else { toIndex = fromIndex - 1 @@ -315,11 +314,11 @@ public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate } } - try! delegate?.pagerTabStripViewController(self, updateIndicatorFromIndex: fromIndex, toIndex: toIndex, withProgressPercentage: Float(pagerOptions.contains(.IsElasticIndicatorLimit) ? scrollPercentage : (toIndex < 0 || toIndex >= getPagerTabStripChildViewControllersForScrolling.count ? CGFloat(0) : scrollPercentage)), indexWasChanged: changeCurrentIndex) + try! delegate?.pagerTabStripViewController(self, updateIndicatorFromIndex: fromIndex, toIndex: toIndex, withProgressPercentage: Float(pagerOptions.contains(.IsElasticIndicatorLimit) ? scrollPercentage : (toIndex < 0 || toIndex >= pagerViewControllers.count ? CGFloat(0) : scrollPercentage)), indexWasChanged: changeCurrentIndex) } } else{ - try! delegate?.pagerTabStripViewController(self, updateIndicatorFromIndex: min(oldCurrentIndex, getPagerTabStripChildViewControllersForScrolling.count - 1), toIndex: newCurrentIndex) + try! delegate?.pagerTabStripViewController(self, updateIndicatorFromIndex: min(oldCurrentIndex, pagerViewControllers.count - 1), toIndex: newCurrentIndex) } } @@ -361,12 +360,7 @@ public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate public func scrollViewDidEndScrollingAnimation(scrollView: UIScrollView) { if containerView == scrollView { pagerTabStripChildViewControllersForScrolling = nil - if let navigationController = navigationController { - navigationController.view.userInteractionEnabled = true - } - else{ - view.userInteractionEnabled = true - } + (navigationController?.view ?? view).userInteractionEnabled = true updateContent() } } @@ -376,21 +370,17 @@ public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate public override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator) pageBeforeRotate = currentIndex - coordinator.animateAlongsideTransition(nil) { (context) -> Void in - self.currentIndex = self.pageBeforeRotate - self.updateIfNeeded() + coordinator.animateAlongsideTransition(nil) { [weak self] _ in + guard let me = self else { return } + me.currentIndex = me.pageBeforeRotate + me.updateIfNeeded() } } - public override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) { - pageBeforeRotate = currentIndex - } + //MARK: Private private var pagerTabStripChildViewControllersForScrolling : [UIViewController]? - private var getPagerTabStripChildViewControllersForScrolling : [UIViewController] { - return pagerTabStripChildViewControllersForScrolling ?? viewControllers - } private var lastPageNumber = 0 private var lastContentOffset: CGFloat = 0.0 private var pageBeforeRotate = 0 diff --git a/Sources/SegmentedPagerTabStripViewController.swift b/Sources/SegmentedPagerTabStripViewController.swift index 0e00dc6..7762fe4 100644 --- a/Sources/SegmentedPagerTabStripViewController.swift +++ b/Sources/SegmentedPagerTabStripViewController.swift @@ -47,7 +47,7 @@ public class SegmentedPagerTabStripViewController: PagerTabStripViewController { } } - func reloadSegmentedControl() throws -> Void { + func reloadSegmentedControl() throws { segmentedControl.removeAllSegments() for (index, item) in viewControllers.enumerate(){ guard let child = item as? PagerTabStripChildItem else { @@ -70,7 +70,7 @@ public class SegmentedPagerTabStripViewController: PagerTabStripViewController { } } - func segmentedControlChanged(sender: UISegmentedControl) -> Void{ + func segmentedControlChanged(sender: UISegmentedControl) { let index = sender.selectedSegmentIndex try! pagerTabStripViewController(self, updateIndicatorFromIndex: currentIndex, toIndex: index) shouldUpdateSegmentedControl = false From 6f5bde24137c757751165a11bcab31c30dcb62d9 Mon Sep 17 00:00:00 2001 From: Martin Barreto Date: Thu, 21 Jan 2016 16:07:07 -0300 Subject: [PATCH 3/3] clean up PagerTabStripViewController --- Sources/BarPagerTabStripViewController.swift | 18 +- Sources/BarView.swift | 2 +- Sources/PagerTabStripViewController.swift | 180 ++++++++---------- ...SegmentedPagerTabStripViewController.swift | 30 ++- 4 files changed, 109 insertions(+), 121 deletions(-) diff --git a/Sources/BarPagerTabStripViewController.swift b/Sources/BarPagerTabStripViewController.swift index 30e1dbe..2bac275 100644 --- a/Sources/BarPagerTabStripViewController.swift +++ b/Sources/BarPagerTabStripViewController.swift @@ -24,7 +24,7 @@ import Foundation -public class BarPagerTabStripViewController: PagerTabStripViewController { +public class BarPagerTabStripViewController: PagerTabStripViewController, PagerTabStripViewControllerDataSource, PagerTabStripViewControllerIsProgressiveDelegate { @IBOutlet lazy public var barView: BarView! = { [unowned self] in let barView = BarView(frame: CGRectMake(0, 0, self.view.frame.size.width, 5.0)) @@ -34,6 +34,18 @@ public class BarPagerTabStripViewController: PagerTabStripViewController { return barView }() + public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { + super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) + delegate = self + datasource = self + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + delegate = self + datasource = self + } + public override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) if barView.superview == nil { @@ -53,11 +65,11 @@ public class BarPagerTabStripViewController: PagerTabStripViewController { // MARK: - PagerTabStripViewControllerDelegate - public override func pagerTabStripViewController(pagerTabStripViewController: PagerTabStripViewController, updateIndicatorFromIndex fromIndex: Int, toIndex: Int) throws { + public func pagerTabStripViewController(pagerTabStripViewController: PagerTabStripViewController, updateIndicatorFromIndex fromIndex: Int, toIndex: Int) throws { barView.moveToIndex(index: toIndex, animated: true) } - public override func pagerTabStripViewController(pagerTabStripViewController: PagerTabStripViewController, updateIndicatorFromIndex fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: Float, indexWasChanged: Bool) throws { + public func pagerTabStripViewController(pagerTabStripViewController: PagerTabStripViewController, updateIndicatorFromIndex fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool) throws { barView.moveToIndex(fromIndex: fromIndex, toIndex: toIndex, progressPercentage: progressPercentage) } } diff --git a/Sources/BarView.swift b/Sources/BarView.swift index bcf8aa2..ba10ae6 100644 --- a/Sources/BarView.swift +++ b/Sources/BarView.swift @@ -72,7 +72,7 @@ public class BarView: UIView { updateSelectedBarPositionWithAnimation(animated) } - public func moveToIndex(fromIndex fromIndex: Int, toIndex: Int, progressPercentage: Float) { + public func moveToIndex(fromIndex fromIndex: Int, toIndex: Int, progressPercentage: CGFloat) { selectedIndex = (progressPercentage > 0.5) ? toIndex : fromIndex var newFrame = selectedBar.frame diff --git a/Sources/PagerTabStripViewController.swift b/Sources/PagerTabStripViewController.swift index 6dcf7d5..595761b 100644 --- a/Sources/PagerTabStripViewController.swift +++ b/Sources/PagerTabStripViewController.swift @@ -36,8 +36,12 @@ public protocol PagerTabStripChildItem { public protocol PagerTabStripViewControllerDelegate: class { func pagerTabStripViewController(pagerTabStripViewController: PagerTabStripViewController, updateIndicatorFromIndex fromIndex: Int, toIndex: Int) throws - - func pagerTabStripViewController(pagerTabStripViewController: PagerTabStripViewController, updateIndicatorFromIndex fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: Float, indexWasChanged: Bool) throws + +} + +public protocol PagerTabStripViewControllerIsProgressiveDelegate : PagerTabStripViewControllerDelegate { + + func pagerTabStripViewController(pagerTabStripViewController: PagerTabStripViewController, updateIndicatorFromIndex fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool) throws } public protocol PagerTabStripViewControllerDataSource: class { @@ -48,8 +52,7 @@ public protocol PagerTabStripViewControllerDataSource: class { //MARK: PagerTabStripViewController -public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate, PagerTabStripViewControllerDataSource, PagerTabStripViewControllerDelegate { - +public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate { @IBOutlet lazy public var containerView: UIScrollView! = { [unowned self] in let containerView = UIScrollView(frame: CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), CGRectGetHeight(self.view.bounds))) @@ -86,18 +89,6 @@ public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate } return .None } - - public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { - super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) - delegate = self - datasource = self - } - - required public init?(coder aDecoder: NSCoder) { - super.init(coder: aDecoder) - delegate = self - datasource = self - } override public func viewDidLoad() { super.viewDidLoad() @@ -173,14 +164,6 @@ public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate return [] } - //MARK: - PagerTabStripViewControllerDelegate - - public func pagerTabStripViewController(pagerTabStripViewController: PagerTabStripViewController, updateIndicatorFromIndex fromIndex: Int, toIndex: Int) throws { - } - - public func pagerTabStripViewController(pagerTabStripViewController: PagerTabStripViewController, updateIndicatorFromIndex fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: Float, indexWasChanged: Bool) throws { - } - //MARK: - Helpers public func updateIfNeeded() { @@ -197,7 +180,7 @@ public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate return CGFloat(index) * CGRectGetWidth(containerView.bounds) } - public func offsetForChildIndex(index index: Int) -> CGFloat{ + public func offsetForChildIndex(index: Int) -> CGFloat{ return (CGFloat(index) * CGRectGetWidth(containerView.bounds)) + ((CGRectGetWidth(containerView.bounds) - CGRectGetWidth(view.bounds)) * 0.5) } @@ -205,19 +188,19 @@ public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate guard let index = viewControllers.indexOf(viewController) else { throw PagerTabStripError.ViewControllerNotContainedInPagerTabStripChildViewControllers } - return offsetForChildIndex(index: index) + return offsetForChildIndex(index) } - public func pageForContentOffset(contentOffset contentOffset: CGFloat) -> Int { - let result = virtualPageForContentOffset(contentOffset: contentOffset) - return pageForVirtualPage(virtualPage: result) + public func pageForContentOffset(contentOffset: CGFloat) -> Int { + let result = virtualPageForContentOffset(contentOffset) + return pageForVirtualPage(result) } - public func virtualPageForContentOffset(contentOffset contentOffset: CGFloat) -> Int { + public func virtualPageForContentOffset(contentOffset: CGFloat) -> Int { return Int((contentOffset + 1.5 * pageWidth) / pageWidth) - 1 } - public func pageForVirtualPage(virtualPage virtualPage: Int) -> Int{ + public func pageForVirtualPage(virtualPage: Int) -> Int{ if virtualPage < 0 { return 0 } @@ -237,27 +220,22 @@ public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate let pagerViewControllers = pagerTabStripChildViewControllersForScrolling ?? viewControllers containerView.contentSize = CGSizeMake(CGRectGetWidth(containerView.bounds) * CGFloat(pagerViewControllers.count), containerView.contentSize.height) - for (index, childController) in pagerViewControllers.enumerate(){ + for (index, childController) in pagerViewControllers.enumerate() { let pageOffsetForChild = pageOffsetForChildIndex(index: index) if fabs(containerView.contentOffset.x - pageOffsetForChild) < CGRectGetWidth(containerView.bounds) { - if childController.parentViewController == nil { + if let _ = childController.parentViewController { + childController.view.frame = CGRectMake(offsetForChildIndex(index), 0, CGRectGetWidth(view.bounds), CGRectGetHeight(containerView.bounds)) + childController.view.autoresizingMask = [.FlexibleHeight, .FlexibleWidth] + } + else { addChildViewController(childController) childController.beginAppearanceTransition(true, animated: false) - - let childPosition = offsetForChildIndex(index: index) - childController.view.frame = CGRectMake(childPosition, 0, CGRectGetWidth(view.bounds), CGRectGetHeight(containerView.bounds)) + childController.view.frame = CGRectMake(offsetForChildIndex(index), 0, CGRectGetWidth(view.bounds), CGRectGetHeight(containerView.bounds)) childController.view.autoresizingMask = [.FlexibleHeight, .FlexibleWidth] - containerView.addSubview(childController.view) childController.didMoveToParentViewController(self) childController.endAppearanceTransition() } - else { - let childPosition = offsetForChildIndex(index: index) - childController.view.frame = CGRectMake(childPosition, 0, CGRectGetWidth(view.bounds), CGRectGetHeight(containerView.bounds)) - childController.view.autoresizingMask = [.FlexibleHeight, .FlexibleWidth] - - } } else { if let _ = childController.parentViewController { @@ -271,75 +249,37 @@ public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate } let oldCurrentIndex = currentIndex - let virtualPage = virtualPageForContentOffset(contentOffset: containerView.contentOffset.x) - let newCurrentIndex = pageForVirtualPage(virtualPage: virtualPage) + let virtualPage = virtualPageForContentOffset(containerView.contentOffset.x) + let newCurrentIndex = pageForVirtualPage(virtualPage) currentIndex = newCurrentIndex let changeCurrentIndex = newCurrentIndex != oldCurrentIndex - if pagerOptions.contains(.IsProgressiveIndicator) { - // FIXME: - check if delegate implements? pagerTabStripViewController(pagerTabStripViewController: XLPagerTabStripViewController, updateIndicatorFromIndex fromIndex: Int, toIndex index: Int, withProgressPercentage progressPercentage: Float, indexWasChanged changed: Bool) + if let progressiveDeledate = self as? PagerTabStripViewControllerIsProgressiveDelegate where pagerOptions.contains(.IsProgressiveIndicator) { - let scrollPercentage = self.scrollPercentage - if scrollPercentage > 0 { - var fromIndex = currentIndex - var toIndex = currentIndex - let direction = swipeDirection - - if direction == .Left { - if virtualPage > pagerViewControllers.count - 1 { - fromIndex = pagerViewControllers.count - 1 - toIndex = pagerViewControllers.count - } - else { - if scrollPercentage >= 0.5 { - fromIndex = max(toIndex - 1, 0) - } - else { - toIndex = fromIndex + 1 - } - } - } - else if direction == .Right { - if virtualPage < 0 { - fromIndex = 0 - toIndex = -1 - } - else { - if scrollPercentage > 0.5 { - fromIndex = min(toIndex + 1, pagerViewControllers.count - 1) - } - else { - toIndex = fromIndex - 1 - } - } - } - - try! delegate?.pagerTabStripViewController(self, updateIndicatorFromIndex: fromIndex, toIndex: toIndex, withProgressPercentage: Float(pagerOptions.contains(.IsElasticIndicatorLimit) ? scrollPercentage : (toIndex < 0 || toIndex >= pagerViewControllers.count ? CGFloat(0) : scrollPercentage)), indexWasChanged: changeCurrentIndex) - } + let (fromIndex, toIndex, scrollPercentage) = progressiveIndicatorData(virtualPage) + try! progressiveDeledate.pagerTabStripViewController(self, updateIndicatorFromIndex: fromIndex, toIndex: toIndex, withProgressPercentage: scrollPercentage, indexWasChanged: changeCurrentIndex) } else{ try! delegate?.pagerTabStripViewController(self, updateIndicatorFromIndex: min(oldCurrentIndex, pagerViewControllers.count - 1), toIndex: newCurrentIndex) } } - + public func reloadPagerTabStripView() { - if isViewLoaded() { - for childController in viewControllers { - if let _ = childController.parentViewController { - childController.view.removeFromSuperview() - childController.willMoveToParentViewController(nil) - childController.removeFromParentViewController() - } + guard isViewLoaded() else { return } + for childController in viewControllers { + if let _ = childController.parentViewController { + childController.view.removeFromSuperview() + childController.willMoveToParentViewController(nil) + childController.removeFromParentViewController() } - - viewControllers = datasource?.childViewControllersForPagerTabStripViewController(self) ?? [] - containerView.contentSize = CGSizeMake(CGRectGetWidth(containerView.bounds) * CGFloat(viewControllers.count), containerView.contentSize.height) - if currentIndex >= viewControllers.count { - currentIndex = viewControllers.count - 1 - } - containerView.contentOffset = CGPointMake(pageOffsetForChildIndex(index: currentIndex), 0) - updateContent() } + viewControllers = datasource?.childViewControllersForPagerTabStripViewController(self) ?? [] + containerView.contentSize = CGSizeMake(CGRectGetWidth(containerView.bounds) * CGFloat(viewControllers.count), containerView.contentSize.height) + if currentIndex >= viewControllers.count { + currentIndex = viewControllers.count - 1 + } + containerView.contentOffset = CGPointMake(pageOffsetForChildIndex(index: currentIndex), 0) + updateContent() } //MARK: - UIScrollDelegate @@ -352,7 +292,7 @@ public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate public func scrollViewWillBeginDragging(scrollView: UIScrollView) { if containerView == scrollView { - lastPageNumber = pageForContentOffset(contentOffset: scrollView.contentOffset.x) + lastPageNumber = pageForContentOffset(scrollView.contentOffset.x) lastContentOffset = scrollView.contentOffset.x } } @@ -380,6 +320,44 @@ public class PagerTabStripViewController: UIViewController, UIScrollViewDelegate //MARK: Private + private func progressiveIndicatorData(virtualPage: Int) -> (Int, Int, CGFloat) { + let count = viewControllers.count + var fromIndex = currentIndex + var toIndex = currentIndex + let direction = swipeDirection + + if direction == .Left { + if virtualPage > count - 1 { + fromIndex = count - 1 + toIndex = count + } + else { + if self.scrollPercentage >= 0.5 { + fromIndex = max(toIndex - 1, 0) + } + else { + toIndex = fromIndex + 1 + } + } + } + else if direction == .Right { + if virtualPage < 0 { + fromIndex = 0 + toIndex = -1 + } + else { + if self.scrollPercentage > 0.5 { + fromIndex = min(toIndex + 1, count - 1) + } + else { + toIndex = fromIndex - 1 + } + } + } + let scrollPercentage = pagerOptions.contains(.IsElasticIndicatorLimit) ? self.scrollPercentage : ((toIndex < 0 || toIndex >= count) ? 0.0 : self.scrollPercentage) + return (fromIndex, toIndex, scrollPercentage) + } + private var pagerTabStripChildViewControllersForScrolling : [UIViewController]? private var lastPageNumber = 0 private var lastContentOffset: CGFloat = 0.0 diff --git a/Sources/SegmentedPagerTabStripViewController.swift b/Sources/SegmentedPagerTabStripViewController.swift index 7762fe4..53d510a 100644 --- a/Sources/SegmentedPagerTabStripViewController.swift +++ b/Sources/SegmentedPagerTabStripViewController.swift @@ -25,10 +25,22 @@ import Foundation -public class SegmentedPagerTabStripViewController: PagerTabStripViewController { +public class SegmentedPagerTabStripViewController: PagerTabStripViewController, PagerTabStripViewControllerDataSource, PagerTabStripViewControllerDelegate { @IBOutlet lazy public var segmentedControl: UISegmentedControl! = UISegmentedControl() + public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { + super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) + delegate = self + datasource = self + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + delegate = self + datasource = self + } + var shouldUpdateSegmentedControl = true public override func viewDidLoad() { @@ -79,8 +91,7 @@ public class SegmentedPagerTabStripViewController: PagerTabStripViewController { // MARK: - PagerTabStripViewControllerDelegate - override public func pagerTabStripViewController(pagerTabStripViewController: PagerTabStripViewController, updateIndicatorFromIndex fromIndex: Int, toIndex: Int) throws { - try super.pagerTabStripViewController(pagerTabStripViewController, updateIndicatorFromIndex: fromIndex, toIndex: toIndex) + public func pagerTabStripViewController(pagerTabStripViewController: PagerTabStripViewController, updateIndicatorFromIndex fromIndex: Int, toIndex: Int) throws { if shouldUpdateSegmentedControl { guard let child = viewControllers[toIndex] as? PagerTabStripChildItem else { throw PagerTabStripError.CurrentIndexIsGreaterThanChildsCount @@ -92,19 +103,6 @@ public class SegmentedPagerTabStripViewController: PagerTabStripViewController { } } - public override func pagerTabStripViewController(pagerTabStripViewController: PagerTabStripViewController, updateIndicatorFromIndex fromIndex: Int, toIndex index: Int, withProgressPercentage progressPercentage: Float, indexWasChanged changed: Bool) throws { - if shouldUpdateSegmentedControl { - let currentIndex = (progressPercentage > 0.5) ? index : fromIndex - guard let child = viewControllers[currentIndex] as? PagerTabStripChildItem else { - throw PagerTabStripError.CurrentIndexIsGreaterThanChildsCount - } - if let color = child.childHeaderForPagerTabStripViewController(self).color{ - segmentedControl.tintColor = color - } - segmentedControl.selectedSegmentIndex = min(currentIndex, viewControllers.count - 1) - } - } - // MARK: - UIScrollViewDelegate public override func scrollViewDidEndScrollingAnimation(scrollView: UIScrollView) {