| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- //
- // DLSlideView.m
- // DLSlideController
- //
- // Created by Dongle Su on 14-12-7.
- // Copyright (c) 2014年 dongle. All rights reserved.
- //
- #import "DLSlideView.h"
- #define kPanSwitchOffsetThreshold 50.0f
- @implementation DLSlideView{
- NSInteger oldIndex_;
- NSInteger panToIndex_;
- UIPanGestureRecognizer *pan_;
- CGPoint panStartPoint_;
-
- UIViewController *oldCtrl_;
- UIViewController *willCtrl_;
-
- BOOL isSwitching_;
- }
- - (void)commonInit{
- oldIndex_ = -1;
- isSwitching_ = NO;
-
- pan_ = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panHandler:)];
- [self addGestureRecognizer:pan_];
- }
- - (id)initWithCoder:(NSCoder *)aDecoder{
- if (self = [super initWithCoder:aDecoder]) {
- [self commonInit];
- }
- return self;
- }
- - (id)initWithFrame:(CGRect)frame{
- if (self = [super initWithFrame:frame]) {
- [self commonInit];
- }
- return self;
- }
- - (NSInteger)selectedIndex{
- return oldIndex_;
- }
- - (void)setSelectedIndex:(NSInteger)selectedIndex{
- if (selectedIndex != oldIndex_) {
- [self switchTo:selectedIndex];
- }
- }
- //- (void)setViewControllers:(NSArray *)vcs{
- // _viewControllers = vcs;
- //}
- - (void)removeOld{
- [self removeCtrl:oldCtrl_];
- [oldCtrl_ endAppearanceTransition];
- oldCtrl_ = nil;
- oldIndex_ = -1;
- }
- - (void)removeWill{
- [willCtrl_ beginAppearanceTransition:NO animated:NO];
- [self removeCtrl:willCtrl_];
- [willCtrl_ endAppearanceTransition];
- willCtrl_ = nil;
- panToIndex_ = -1;
- }
- - (void)showAt:(NSInteger)index{
- if (oldIndex_ != index) {
- //[self removeAt:oldIndex_];
- [self removeOld];
-
- UIViewController *vc = [self.dataSource DLSlideView:self controllerAt:index];
- [self.baseViewController addChildViewController:vc];
- vc.view.frame = self.bounds;
- [self addSubview:vc.view];
- [vc didMoveToParentViewController:self.baseViewController];
- oldIndex_ = index;
- oldCtrl_ = vc;
-
- if (self.delegate && [self.delegate respondsToSelector:@selector(DLSlideView:didSwitchTo:)]) {
- [self.delegate DLSlideView:self didSwitchTo:index];
- }
- }
- }
- - (void)removeCtrl:(UIViewController *)ctrl{
- UIViewController *vc = ctrl;
- [vc willMoveToParentViewController:nil];
- [vc.view removeFromSuperview];
- [vc removeFromParentViewController];
- }
- //- (void)removeAt:(int)index{
- // if (oldIndex_ == index) {
- // oldIndex_ = -1;
- // }
- //
- // if (index >= 0 && index <= [self.dataSource numberOfControllersInDLSlideView:self]) {
- // UIViewController *vc = [self.dataSource DLSlideView:self controllerAt:index];
- // [vc willMoveToParentViewController:nil];
- // [vc.view removeFromSuperview];
- // [vc removeFromParentViewController];
- // }
- //}
- - (void)switchTo:(NSInteger)index{
- if (index == oldIndex_) {
- return;
- }
- if (isSwitching_) {
- return;
- }
- if (oldCtrl_ != nil && oldCtrl_.parentViewController == self.baseViewController) {
- isSwitching_ = YES;
- //UIViewController *oldvc = [self.dataSource DLSlideView:self controllerAt:oldIndex_];;
- UIViewController *oldvc = oldCtrl_;
- UIViewController *newvc = [self.dataSource DLSlideView:self controllerAt:index];
-
- [oldvc willMoveToParentViewController:nil];
- [self.baseViewController addChildViewController:newvc];
-
- CGRect nowRect = oldvc.view.frame;
- CGRect leftRect = CGRectMake(nowRect.origin.x-nowRect.size.width, nowRect.origin.y, nowRect.size.width, nowRect.size.height);
- CGRect rightRect = CGRectMake(nowRect.origin.x+nowRect.size.width, nowRect.origin.y, nowRect.size.width, nowRect.size.height);
-
- CGRect newStartRect;
- CGRect oldEndRect;
- if (index > oldIndex_) {
- newStartRect = rightRect;
- oldEndRect = leftRect;
- }
- else{
- newStartRect = leftRect;
- oldEndRect = rightRect;
- }
-
- newvc.view.frame = newStartRect;
- [newvc willMoveToParentViewController:self.baseViewController];
-
- [self.baseViewController transitionFromViewController:oldvc toViewController:newvc duration:0.4 options:0 animations:^{
- newvc.view.frame = nowRect;
- oldvc.view.frame = oldEndRect;
- } completion:^(BOOL finished) {
- [oldvc removeFromParentViewController];
- [newvc didMoveToParentViewController:self.baseViewController];
-
- if (self.delegate && [self.delegate respondsToSelector:@selector(DLSlideView:didSwitchTo:)]) {
- [self.delegate DLSlideView:self didSwitchTo:index];
- }
-
- isSwitching_ = NO;
- }];
-
- oldIndex_ = index;
- oldCtrl_ = newvc;
- }
- else{
- [self showAt:index];
- }
-
- willCtrl_ = nil;
- panToIndex_ = -1;
- }
- - (void)repositionForOffsetX:(CGFloat)offsetx{
- float x = 0.0f;
-
- if (panToIndex_ < oldIndex_) {
- x = self.bounds.origin.x - self.bounds.size.width + offsetx;
- }
- else if(panToIndex_ > oldIndex_){
- x = self.bounds.origin.x + self.bounds.size.width + offsetx;
- }
-
- //UIViewController *oldvc = [self.dataSource DLSlideView:self controllerAt:oldIndex_];
- UIViewController *oldvc = oldCtrl_;
- oldvc.view.frame = CGRectMake(self.bounds.origin.x + offsetx, self.bounds.origin.y, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds));
-
- if (panToIndex_ >= 0 && panToIndex_ < [self.dataSource numberOfControllersInDLSlideView:self]) {
- //UIViewController *vc = [self.dataSource DLSlideView:self controllerAt:panToIndex_];
- UIViewController *vc = willCtrl_;
- vc.view.frame = CGRectMake(x, self.bounds.origin.y, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds));
- // if (vc.parentViewController == nil) {
- //
- // [self.baseViewController addChildViewController:vc];
- // [vc willMoveToParentViewController:self.baseViewController];
- // [vc beginAppearanceTransition:YES animated:YES];
- // [self addSubview:vc.view];
- // //[vc didMoveToParentViewController:self.baseViewController];
- // }
- }
-
- if (self.delegate && [self.delegate respondsToSelector:@selector(DLSlideView:switchingFrom:to:percent:)]) {
- [self.delegate DLSlideView:self switchingFrom:oldIndex_ to:panToIndex_ percent:fabs(offsetx)/self.bounds.size.width];
- }
- }
- - (void)backToOldWithOffset:(CGFloat)offsetx{
- NSTimeInterval animatedTime = 0;
- animatedTime = 0.3;
-
- //animatedTime = fabs(self.frame.size.width - fabs(offsetx)) / self.frame.size.width * 0.35;
- [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
- [UIView animateWithDuration:animatedTime animations:^{
- [self repositionForOffsetX:0];
- } completion:^(BOOL finished) {
- if (panToIndex_ >= 0 && panToIndex_ < [self.dataSource numberOfControllersInDLSlideView:self] && panToIndex_ != oldIndex_) {
- //[self removeAt:panToIndex_];
- [oldCtrl_ beginAppearanceTransition:YES animated:NO];
- [self removeWill];
- [oldCtrl_ endAppearanceTransition];
- }
- if (self.delegate && [self.delegate respondsToSelector:@selector(DLSlideView:switchCanceled:)]) {
- [self.delegate DLSlideView:self switchCanceled:oldIndex_];
- }
- }];
-
- // [UIView animateWithDuration:animatedTime delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
- // float pantox = 0.0f;
- // if (offsetx > 0) {
- // pantox = -self.bounds.size.width;
- // }
- // else{
- // pantox = self.bounds.size.width;
- // }
- //
- // //UIViewController *oldvc = [self.dataSource DLSlideView:self controllerAt:oldIndex_];;
- // UIViewController *oldvc = oldCtrl_;
- // oldvc.view.frame = CGRectMake(0, self.bounds.origin.y, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds));
- // if (panToIndex_ >= 0 && panToIndex_ < [self.dataSource numberOfControllersInDLSlideView:self]) {
- // //UIViewController *vc = [self.dataSource DLSlideView:self controllerAt:panToIndex_];
- // UIViewController *vc = willCtrl_;
- // vc.view.frame = CGRectMake(pantox, self.bounds.origin.y, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds));
- // }
- // } completion:^(BOOL finished) {
- // if (panToIndex_ >= 0 && panToIndex_ < [self.dataSource numberOfControllersInDLSlideView:self] && panToIndex_ != oldIndex_) {
- // //[self removeAt:panToIndex_];
- // [self removeWill];
- // }
- // }];
-
- }
- - (void)panHandler:(UIPanGestureRecognizer *)pan{
- if (oldIndex_ < 0) {
- return;
- }
-
- CGPoint point = [pan translationInView:self];
-
- if (pan.state == UIGestureRecognizerStateBegan) {
- panStartPoint_ = point;
- //[oldCtrl_ willMoveToParentViewController:nil];
- [oldCtrl_ beginAppearanceTransition:NO animated:YES];
- }
- else if (pan.state == UIGestureRecognizerStateChanged){
- NSInteger panToIndex = -1;
- float offsetx = point.x - panStartPoint_.x;
-
- if (offsetx > 0) {
- panToIndex = oldIndex_ - 1;
- }
- else if(offsetx < 0){
- panToIndex = oldIndex_ + 1;
- }
-
- // fix bug #5
- if (panToIndex != panToIndex_) {
- if (willCtrl_) {
- [self removeWill];
- }
- }
-
- if (panToIndex < 0 || panToIndex >= [self.dataSource numberOfControllersInDLSlideView:self]) {
- panToIndex_ = panToIndex;
- [self repositionForOffsetX:offsetx/2.0f];
- }
- else{
- if (panToIndex != panToIndex_) {
- //fix bug #5
- // if (willCtrl_) {
- // [self removeWill];
- // }
- willCtrl_ = [self.dataSource DLSlideView:self controllerAt:panToIndex];
- [self.baseViewController addChildViewController:willCtrl_];
- [willCtrl_ willMoveToParentViewController:self.baseViewController];
- [willCtrl_ beginAppearanceTransition:YES animated:YES];
- [self addSubview:willCtrl_.view];
- panToIndex_ = panToIndex;
- }
- [self repositionForOffsetX:offsetx];
- }
- }
- else if (pan.state == UIGestureRecognizerStateEnded){
- float offsetx = point.x - panStartPoint_.x;
-
- if (panToIndex_ >= 0 && panToIndex_ < [self.dataSource numberOfControllersInDLSlideView:self] && panToIndex_ != oldIndex_) {
- if (fabs(offsetx) > kPanSwitchOffsetThreshold) {
- NSTimeInterval animatedTime = 0;
- animatedTime = fabs(self.frame.size.width - fabs(offsetx)) / self.frame.size.width * 0.4;
- [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
- [UIView animateWithDuration:animatedTime animations:^{
- [self repositionForOffsetX:offsetx > 0 ? self.bounds.size.width : -self.bounds.size.width];
- } completion:^(BOOL finished) {
- //[self removeAt:oldIndex_];
- [self removeOld];
-
- if (panToIndex_ >= 0 && panToIndex_ < [self.dataSource numberOfControllersInDLSlideView:self]) {
- [willCtrl_ endAppearanceTransition];
- [willCtrl_ didMoveToParentViewController:self.baseViewController];
- oldIndex_ = panToIndex_;
- oldCtrl_ = willCtrl_;
- willCtrl_ = nil;
- panToIndex_ = -1;
- }
- if (self.delegate && [self.delegate respondsToSelector:@selector(DLSlideView:didSwitchTo:)]) {
- [self.delegate DLSlideView:self didSwitchTo:oldIndex_];
- }
- }];
- }
- else{
- [self backToOldWithOffset:offsetx];
- }
- }
- else{
- [self backToOldWithOffset:offsetx];
- }
- }
- }
- @end
|