From f192839e5ace66222ddb7c68fb15f760e1f35ed8 Mon Sep 17 00:00:00 2001 From: Matt Thomas Date: Tue, 7 Feb 2012 21:16:22 -0500 Subject: [PATCH] Added pan and tap gesture support Pan now tracks the movement of the finger and tap will bring the viewController to the foreground --- Source/CAFCardStackController.m | 132 +++++++++++++++++++++++++++----- 1 file changed, 113 insertions(+), 19 deletions(-) diff --git a/Source/CAFCardStackController.m b/Source/CAFCardStackController.m index acc1153..53ce4e1 100644 --- a/Source/CAFCardStackController.m +++ b/Source/CAFCardStackController.m @@ -10,13 +10,26 @@ #import "UIView+ImageExtensions.h" -@implementation CAFCardStackController +const CGFloat CAFCardStackControllerDefaultAnimationDuration = 0.3; + +@interface CAFCardStackController () +- (void)didReceivePanGesture:(UIPanGestureRecognizer *)panGesture; +- (void)didReceiveTapGesture:(UITapGestureRecognizer *)tapGesture; +@end + + +@implementation CAFCardStackController { + NSMutableDictionary *_viewControllerIDMap; + NSMutableDictionary *_viewIDMap; +} - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization + _viewControllerIDMap = [[NSMutableDictionary alloc] init]; + _viewIDMap = [[NSMutableDictionary alloc] init]; } return self; } @@ -54,30 +67,77 @@ - (NSArray *)cardViewControllers #pragma mark - Instance Methods - (void)addCardViewController:(UIViewController *)viewController { - UIView *addedView = viewController.view; - addedView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; - addedView.frame = CGRectMake(0.0, 0.0, 768.0, 1004.0); - - UIImage *viewImage = [addedView caf_imageRepresentation]; - UIImageView *imageView = [[UIImageView alloc] initWithImage:viewImage]; - imageView.contentMode = UIViewContentModeScaleAspectFit; - imageView.frame = CGRectMake(0.0, 0.0, 384.0, 502.0); - [self.view addSubview:imageView]; - -// [self addChildViewController:viewController]; -// -// UIView *addedView = viewController.view; -// [self.view addSubview:addedView]; -// addedView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; -// addedView.frame = self.view.bounds; +// if (viewController +// && ![_cardViewControllers containsObject:viewController]) { +// +// [_cardViewControllers addObject:viewController]; +// [_viewControllerDictionary setObject:viewController +// forKey:uniqueString]; // -// [viewController didMoveToParentViewController:self]; +// +// UIView *addedView = viewController.view; +// addedView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; +// addedView.frame = self.view.bounds; +// UIImage *viewImage = [addedView caf_imageRepresentation]; +// UIImageView *imageView = [[UIImageView alloc] initWithImage:viewImage]; +// imageView.contentMode = UIViewContentModeScaleAspectFit; +// CGFloat scale = 0.45; +// imageView.frame = CGRectMake(60.0, +// 60.0, +// roundf(addedView.frame.size.width * scale), +// roundf(addedView.frame.size.height * scale)); +// [self.view addSubview:imageView]; +// } + + if (viewController + && ![self.childViewControllers containsObject:viewController]) { + CFUUIDRef uniqueID = CFUUIDCreate(kCFAllocatorDefault); + CFStringRef uniqueStringRef = CFUUIDCreateString(kCFAllocatorDefault, + uniqueID); + NSString *uniqueString = (__bridge NSString *)uniqueStringRef; + + [_viewControllerIDMap setObject:viewController forKey:uniqueString]; + [self addChildViewController:viewController]; + + UIView *addedView = viewController.view; + [_viewIDMap setObject:addedView forKey:uniqueString]; + + addedView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; + addedView.frame = self.view.bounds; + addedView.alpha = 0.0f; + addedView.transform = CGAffineTransformMakeScale(0.45f, 0.45f); + [self.view addSubview:addedView]; + [UIView animateWithDuration:CAFCardStackControllerDefaultAnimationDuration + animations:^{ + addedView.alpha = 1.0f; + } + completion:^(BOOL finished) { + [viewController didMoveToParentViewController:self]; + }]; + + UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self + action:@selector(didReceivePanGesture:)]; + [addedView addGestureRecognizer:panGestureRecognizer]; + + UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self + action:@selector(didReceiveTapGesture:)]; + [addedView addGestureRecognizer:tapGestureRecognizer]; + } } - (void)focusCardViewController:(UIViewController *)viewController { - + UIView *view = viewController.view; + NSArray *gestureRecognizers = view.gestureRecognizers; + for (UIGestureRecognizer *gestureRecognizer in gestureRecognizers) { + [view removeGestureRecognizer:gestureRecognizer]; + } + [UIView animateWithDuration:CAFCardStackControllerDefaultAnimationDuration + animations:^{ + view.transform = CGAffineTransformIdentity; + view.frame = self.view.bounds; + }]; } @@ -92,4 +152,38 @@ - (void)removeCardViewController:(UIViewController *)viewController } + +#pragma mark - Private Methods +- (void)didReceivePanGesture:(UIPanGestureRecognizer *)panGesture +{ + CGPoint translate = [panGesture translationInView:self.view]; + + if (panGesture.state == UIGestureRecognizerStateBegan || panGesture.state == UIGestureRecognizerStateChanged) { + UIView *view = panGesture.view; + CGPoint translation = [panGesture translationInView:view.superview]; + [view setCenter:CGPointMake(view.center.x + translation.x, view.center.y + translation.y)]; + [panGesture setTranslation:CGPointZero inView:view.superview]; + } else if (panGesture.state == UIGestureRecognizerStateEnded) { + CGRect newFrame = panGesture.view.frame; + newFrame.origin.x += translate.x; + newFrame.origin.y += translate.y; + + panGesture.view.frame = newFrame; + } +} + + +- (void)didReceiveTapGesture:(UITapGestureRecognizer *)tapGesture +{ + if (tapGesture.state == UIGestureRecognizerStateEnded) { + UIView *currentView = tapGesture.view; + NSArray *viewIDs = [_viewIDMap allKeysForObject:currentView]; + if ([viewIDs count] == 1) { + NSString *viewID = [viewIDs lastObject]; + UIViewController *currentViewController = [_viewControllerIDMap objectForKey:viewID]; + [self focusCardViewController:currentViewController]; + } + } +} + @end