Skip to content

Commit 15ea274

Browse files
author
lixian
committedJul 5, 2015
raw_version
1 parent 719ee67 commit 15ea274

File tree

11 files changed

+841
-1
lines changed

11 files changed

+841
-1
lines changed
 

‎LxTabBarController.swift

+221
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
//
2+
// LxTabBarController.swift
3+
// LxTabBarControllerDemo
4+
//
5+
6+
import UIKit
7+
8+
enum LxTabBarControllerInteractionStopReason {
9+
10+
case Finished, Cancelled, Failed
11+
}
12+
13+
let LxTabBarControllerDidSelectViewControllerNotification = "LxTabBarControllerDidSelectViewControllerNotification"
14+
15+
private enum LxTabBarControllerSwitchType {
16+
17+
case Unknown, Last, Next
18+
}
19+
20+
let TRANSITION_DURATION = 0.2
21+
private var _switchType = LxTabBarControllerSwitchType.Unknown
22+
23+
class Transition: NSObject, UIViewControllerAnimatedTransitioning {
24+
25+
func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval {
26+
return TRANSITION_DURATION
27+
}
28+
29+
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
30+
31+
let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!
32+
let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!
33+
34+
transitionContext.containerView().insertSubview(toViewController.view, aboveSubview: fromViewController.view)
35+
36+
switch _switchType {
37+
38+
case .Last:
39+
toViewController.view.frame.origin.x = -toViewController.view.frame.size.width
40+
case .Next:
41+
toViewController.view.frame.origin.x = toViewController.view.frame.size.width
42+
case .Unknown:
43+
break
44+
}
45+
46+
UIView.animateWithDuration(TRANSITION_DURATION, animations: { () -> Void in
47+
48+
switch _switchType {
49+
50+
case .Last:
51+
fromViewController.view.frame.origin.x = fromViewController.view.frame.size.width
52+
case .Next:
53+
fromViewController.view.frame.origin.x = -fromViewController.view.frame.size.width
54+
case .Unknown:
55+
break
56+
}
57+
toViewController.view.frame = transitionContext.containerView().bounds
58+
59+
}) { (finished) -> Void in
60+
transitionContext.completeTransition(!transitionContext.transitionWasCancelled())
61+
}
62+
}
63+
}
64+
65+
class LxTabBarController: UITabBarController,UITabBarControllerDelegate,UIGestureRecognizerDelegate {
66+
67+
var panToSwitchGestureRecognizerEnabled: Bool {
68+
69+
get {
70+
return _panToSwitchGestureRecognizer.enabled
71+
}
72+
set {
73+
_panToSwitchGestureRecognizer.enabled = newValue
74+
}
75+
}
76+
77+
var recognizeOtherGestureSimultaneously = false
78+
var isTranslating = false
79+
var panGestureRecognizerBeginBlock = { () -> Void in }
80+
var panGestureRecognizerStopBlock = { (stopReason: LxTabBarControllerInteractionStopReason) -> Void in }
81+
82+
let _panToSwitchGestureRecognizer = UIPanGestureRecognizer()
83+
var _interactiveTransition: UIPercentDrivenInteractiveTransition?
84+
85+
convenience init () {
86+
self.init(nibName: nil, bundle: nil)
87+
setup()
88+
}
89+
90+
required init(coder aDecoder: NSCoder) {
91+
super.init(coder: aDecoder)
92+
setup()
93+
}
94+
95+
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
96+
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
97+
// setup()
98+
}
99+
100+
func setup() {
101+
102+
self.delegate = self
103+
104+
_panToSwitchGestureRecognizer.addTarget(self, action: "panGestureRecognizerTriggerd:")
105+
_panToSwitchGestureRecognizer.delegate = self
106+
_panToSwitchGestureRecognizer.cancelsTouchesInView = false
107+
_panToSwitchGestureRecognizer.maximumNumberOfTouches = 1
108+
view.addGestureRecognizer(_panToSwitchGestureRecognizer)
109+
}
110+
111+
func tabBarController(tabBarController: UITabBarController, interactionControllerForAnimationController animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
112+
113+
return animationController is Transition ? _interactiveTransition : nil
114+
}
115+
116+
func tabBarController(tabBarController: UITabBarController, animationControllerForTransitionFromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
117+
118+
return Transition()
119+
}
120+
121+
func panGestureRecognizerTriggerd(pan: UIPanGestureRecognizer) {
122+
123+
var progress = pan.translationInView(pan.view!).x / pan.view!.bounds.size.width
124+
125+
if progress > 0 {
126+
_switchType = .Last
127+
}
128+
else if progress < 0 {
129+
_switchType = .Next
130+
}
131+
else {
132+
_switchType = .Unknown
133+
}
134+
135+
progress = abs(progress)
136+
progress = max(0, progress)
137+
progress = min(1, progress)
138+
139+
switch pan.state {
140+
141+
case .Began:
142+
isTranslating = true
143+
_interactiveTransition = UIPercentDrivenInteractiveTransition()
144+
switch _switchType {
145+
146+
case .Last:
147+
selectedIndex = max(0, selectedIndex - 1)
148+
selectedViewController = viewControllers![selectedIndex] as? UIViewController
149+
panGestureRecognizerBeginBlock()
150+
case .Next:
151+
selectedIndex = min(viewControllers!.count, selectedIndex + 1)
152+
selectedViewController = viewControllers![selectedIndex] as? UIViewController
153+
panGestureRecognizerBeginBlock()
154+
case .Unknown:
155+
break
156+
}
157+
case .Changed:
158+
_interactiveTransition?.updateInteractiveTransition(CGFloat(progress))
159+
case .Failed:
160+
isTranslating = false
161+
panGestureRecognizerStopBlock(.Failed)
162+
default:
163+
164+
if abs(progress) > 0.5 {
165+
166+
_interactiveTransition?.finishInteractiveTransition()
167+
panGestureRecognizerStopBlock(.Finished)
168+
}
169+
else {
170+
_interactiveTransition?.cancelInteractiveTransition()
171+
panGestureRecognizerStopBlock(.Cancelled)
172+
}
173+
174+
_interactiveTransition = nil
175+
isTranslating = false
176+
}
177+
}
178+
179+
func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
180+
181+
if gestureRecognizer == _panToSwitchGestureRecognizer {
182+
183+
return !isTranslating
184+
}
185+
else {
186+
return true
187+
}
188+
}
189+
190+
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
191+
192+
if gestureRecognizer == _panToSwitchGestureRecognizer || otherGestureRecognizer == _panToSwitchGestureRecognizer {
193+
194+
return recognizeOtherGestureSimultaneously
195+
}
196+
else {
197+
return false
198+
}
199+
}
200+
201+
func tabBarController(tabBarController: UITabBarController, shouldSelectViewController viewController: UIViewController) -> Bool {
202+
203+
let viewControllerIndex = find(tabBarController.viewControllers as! [UIViewController], viewController)
204+
205+
if viewControllerIndex > selectedIndex {
206+
_switchType = .Next
207+
}
208+
else if viewControllerIndex < selectedIndex {
209+
_switchType = .Last
210+
}
211+
else {
212+
_switchType = .Unknown
213+
}
214+
return true
215+
}
216+
217+
func tabBarController(tabBarController: UITabBarController, didSelectViewController viewController: UIViewController) {
218+
219+
NSNotificationCenter.defaultCenter().postNotificationName(LxTabBarControllerDidSelectViewControllerNotification, object: nil)
220+
}
221+
}

0 commit comments

Comments
 (0)
Please sign in to comment.