From 096f1d7c39cc17920675032765bf262d96d8410a Mon Sep 17 00:00:00 2001 From: Artur Wdowiarski Date: Fri, 4 Jan 2013 14:08:40 +0100 Subject: [PATCH 1/4] Fixes #7. Last cells in rows not showing again after they are pulled off when the quilt view bounces. --- TMQuiltView/TMQuiltView/TMQuiltView.m | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/TMQuiltView/TMQuiltView/TMQuiltView.m b/TMQuiltView/TMQuiltView/TMQuiltView.m index abad306..95422f9 100644 --- a/TMQuiltView/TMQuiltView/TMQuiltView.m +++ b/TMQuiltView/TMQuiltView/TMQuiltView.m @@ -466,6 +466,10 @@ - (void)layoutSubviews { // Harvest any any views that have moved off screen and add them to the reuse pool for (NSIndexPath* indexPath in [indexPathToView allKeys]) { TMQuiltViewCell *view = [indexPathToView objectForKey:indexPath]; + // Do not harvest the last cell in the column + if (*bottom == [indexPaths count] - 1) { + continue; + } if (![TMQuiltView isRect:view.frame partiallyInScrollView:self]) { // Rect intersection? [indexPathToView removeObjectForKey:indexPath]; // Limit the size on the reuse pool From 2cd1a3eaa6ad4b149dd5b4c69513dd254cf76dca Mon Sep 17 00:00:00 2001 From: Artur Wdowiarski Date: Fri, 4 Jan 2013 22:54:35 +0100 Subject: [PATCH 2/4] Fixes #7. It turned out that the previous fix was quite stupid. --- TMQuiltView/TMQuiltView/TMQuiltView.m | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/TMQuiltView/TMQuiltView/TMQuiltView.m b/TMQuiltView/TMQuiltView/TMQuiltView.m index 95422f9..7389d09 100644 --- a/TMQuiltView/TMQuiltView/TMQuiltView.m +++ b/TMQuiltView/TMQuiltView/TMQuiltView.m @@ -449,8 +449,7 @@ - (void)layoutSubviews { } (*bottom)++; } - - + // Add a new cell to the top if our top cell is below the top of the visible area (and not the first cell) while ((*top > 0) && [TMQuiltView isRect:[self rectForCellAtIndex:*top column:i] entirelyInOrBelowScrollView:self]) { if ([TMQuiltView isRect:[self rectForCellAtIndex:*top - 1 column:i] partiallyInScrollView:self]) { @@ -466,12 +465,10 @@ - (void)layoutSubviews { // Harvest any any views that have moved off screen and add them to the reuse pool for (NSIndexPath* indexPath in [indexPathToView allKeys]) { TMQuiltViewCell *view = [indexPathToView objectForKey:indexPath]; - // Do not harvest the last cell in the column - if (*bottom == [indexPaths count] - 1) { - continue; - } + if (![TMQuiltView isRect:view.frame partiallyInScrollView:self]) { // Rect intersection? [indexPathToView removeObjectForKey:indexPath]; + // Limit the size on the reuse pool if ([[self reusableViewsWithReuseIdentifier:view.reuseIdentifier] count] < 10) { [[self reusableViewsWithReuseIdentifier:view.reuseIdentifier] addObject:view]; @@ -497,6 +494,19 @@ - (void)layoutSubviews { break; } } + + // The last cell in a column might have been harvested after our scroll view bounce. + // Here we check if the last cell's frame is partially in our scroll view + if (*bottom == [indexPaths count] - 1 && [TMQuiltView isRect:[self rectForCellAtIndex:*bottom column:i] partiallyInScrollView:self]){ + NSIndexPath *indexPath = [indexPaths objectAtIndex:*bottom]; + // We check, if the last cell has actually been harvested... + if ([indexPathToView objectForKey:indexPath] == nil) { + // ... and if so, we add it back + UIView* cell = [self.dataSource quiltView:self cellAtIndexPath:indexPath]; + [self addSubview:cell]; + [indexPathToView setObject:cell forKey:indexPath]; + } + } } } From 9e4a9377ae3aeecf30576f399aaba7174f9cd306 Mon Sep 17 00:00:00 2001 From: Artur Wdowiarski Date: Wed, 9 Jan 2013 21:03:11 +0100 Subject: [PATCH 3/4] Make it possible to place tappable UIControl elements in cells for iOS < 6. --- TMQuiltView/TMQuiltView/TMQuiltView.h | 2 +- TMQuiltView/TMQuiltView/TMQuiltView.m | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/TMQuiltView/TMQuiltView/TMQuiltView.h b/TMQuiltView/TMQuiltView/TMQuiltView.h index a6a5537..edce12f 100644 --- a/TMQuiltView/TMQuiltView/TMQuiltView.h +++ b/TMQuiltView/TMQuiltView/TMQuiltView.h @@ -55,7 +55,7 @@ typedef enum { @end -@interface TMQuiltView : UIScrollView +@interface TMQuiltView : UIScrollView @property (nonatomic, assign) id dataSource; @property (nonatomic, assign) id delegate; diff --git a/TMQuiltView/TMQuiltView/TMQuiltView.m b/TMQuiltView/TMQuiltView/TMQuiltView.m index 7389d09..e73d4be 100644 --- a/TMQuiltView/TMQuiltView/TMQuiltView.m +++ b/TMQuiltView/TMQuiltView/TMQuiltView.m @@ -562,6 +562,7 @@ + (BOOL)isRect:(CGRect)rect partiallyInScrollView:(UIScrollView *)scrollView { - (UITapGestureRecognizer *)tapGestureRecognizer { if (!_tapGestureRecognizer) { _tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewTapped:)]; + _tapGestureRecognizer.delegate = self; } return _tapGestureRecognizer; } @@ -591,6 +592,13 @@ - (void)viewTapped:(UIGestureRecognizer *)recognizer { } +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { + if ([touch.view isKindOfClass:[UIControl class]]) { + // we touched a button, slider, or other UIControl + return NO; // ignore the touch + } + return YES; // handle the touch +} @end From a1acfbcdbc4463e62a1b279614bc3361ad3026de Mon Sep 17 00:00:00 2001 From: Artur Wdowiarski Date: Thu, 10 Jan 2013 18:59:06 +0100 Subject: [PATCH 4/4] Make it possible to place an MPMoviePlayer in the QuiltView and have it behaving correctly when it exits from fullscreen in iOS 6. The problem in this case was that as of iOS6 viewWillAppear is called on the controller presenting an MPMoviePlayer when the player exits fullscreen. As a result setFrame is called on the controller's view, which in our case led to the resetView being called, which in turn threw away all the cells, including the one with the MPMoviePlayer and this (finally!) caused the player to be minimalized to the outside of the controller's view. phew! --- TMQuiltView/TMQuiltView/TMQuiltView.m | 31 ++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/TMQuiltView/TMQuiltView/TMQuiltView.m b/TMQuiltView/TMQuiltView/TMQuiltView.m index e73d4be..8af2f50 100644 --- a/TMQuiltView/TMQuiltView/TMQuiltView.m +++ b/TMQuiltView/TMQuiltView/TMQuiltView.m @@ -26,7 +26,9 @@ NSString *const kDefaultReusableIdentifier = @"kTMQuiltViewDefaultReusableIdentifier"; -@interface TMQuiltView() +@interface TMQuiltView(){ + BOOL _videoPlayedInFullScreen; +} @property (nonatomic, readonly, retain) NSMutableSet *indexPaths; @property (nonatomic, readonly, retain) NSMutableDictionary *reusableViewsDictionary; @@ -126,9 +128,24 @@ - (id)initWithFrame:(CGRect)frame super.alwaysBounceVertical = YES; [self addGestureRecognizer:self.tapGestureRecognizer]; _numberOfColumms = kTMQuiltViewDefaultColumns; + _videoPlayedInFullScreen = NO; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(videoInFullScreenDidStart:) name:@"UIMoviePlayerControllerDidEnterFullscreenNotification" object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(videoInFullScreenDidEnd:) name:@"UIMoviePlayerControllerDidExitFullscreenNotification" object:nil]; + } return self; } + +- (void)videoInFullScreenDidStart:(id)notification +{ + _videoPlayedInFullScreen = YES; +} + +- (void)videoInFullScreenDidEnd:(id)notification +{ + _videoPlayedInFullScreen = NO; +} + - (void)setDelegate:(id)delegate { [super setDelegate:delegate]; @@ -397,7 +414,7 @@ - (CGRect)rectForCellAtIndex:(int)index column:(int)column { [self cellWidth], height); } -- (void)layoutSubviews { +- (void)layoutSubviews { [super layoutSubviews]; self.contentSize = CGSizeMake(self.bounds.size.width, self.contentSize.height); @@ -511,9 +528,17 @@ - (void)layoutSubviews { } - (void)setFrame:(CGRect)frame { + // If we have an MPMoviePlayer that is just exiting fullscreen, + // removing it's superview from the view hierarchy would cause + // the minimalize animation to be broken + if (_videoPlayedInFullScreen) { + _videoPlayedInFullScreen = NO; + return; + } + [super setFrame:frame]; - // We need to recompute the cell tops because their width is + // We need to recompute the cell tops because their width is // based on the bounding width, and their height is generally based // on their width. [self resetView];