From 3efd54141f4a5deef0e8b8fb5110f7b428a91709 Mon Sep 17 00:00:00 2001 From: teejay Date: Tue, 3 Sep 2013 09:07:17 -0700 Subject: [PATCH] Makes individual indicators tappable --- SMPageControl.h | 2 ++ SMPageControl.m | 49 +++++++++++++++++++++++++++++++++++++------------ 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/SMPageControl.h b/SMPageControl.h index 2f4f47f..65d60f2 100755 --- a/SMPageControl.h +++ b/SMPageControl.h @@ -38,6 +38,8 @@ typedef NS_ENUM(NSUInteger, SMPageControlVerticalAlignment) { @property (nonatomic) BOOL hidesForSinglePage; // hide the the indicator if there is only one page. default is NO @property (nonatomic) BOOL defersCurrentPageDisplay; // if set, clicking to a new page won't update the currently displayed page until -updateCurrentPageDisplay is called. default is NO +@property (nonatomic) BOOL individualPageTaps; // if set to True, taping individual indicators will change to that specified page, rather than simply incrementing or decrementing the values. + - (void)updateCurrentPageDisplay; // update page display to match the currentPage. ignored if defersCurrentPageDisplay is NO. setting the page value directly will update immediately - (CGRect)rectForPageIndicator:(NSInteger)pageIndex; diff --git a/SMPageControl.m b/SMPageControl.m index eefbe62..94d81fb 100755 --- a/SMPageControl.m +++ b/SMPageControl.m @@ -29,6 +29,7 @@ @interface SMPageControl () @property (nonatomic, readonly) NSMutableDictionary *currentPageImages; @property (nonatomic, readonly) NSMutableDictionary *pageImageMasks; @property (nonatomic, readonly) NSMutableDictionary *cgImageMasks; +@property NSMutableArray *pageRects; // Page Control used for stealing page number localizations for accessibility labels // I'm not sure I love this technique, but it's the best way to get exact translations for all the languages @@ -54,7 +55,8 @@ @implementation SMPageControl - (void)_initialize { _numberOfPages = 0; - + _individualPageTaps = NO; + self.backgroundColor = [UIColor clearColor]; _measuredIndicatorWidth = DEFAULT_INDICATOR_WIDTH; _measuredIndicatorHeight = DEFAULT_INDICATOR_WIDTH; @@ -105,6 +107,8 @@ - (void)drawRect:(CGRect)rect - (void)_renderPages:(CGContextRef)context rect:(CGRect)rect { + _pageRects = [@[] mutableCopy]; + if (_numberOfPages < 2 && _hidesForSinglePage) { return; } @@ -149,22 +153,25 @@ - (void)_renderPages:(CGContextRef)context rect:(CGRect)rect } [fillColor set]; - + CGRect imageRect; if (image) { yOffset = [self _topOffsetForHeight:image.size.height rect:rect]; CGFloat centeredXOffset = xOffset + floorf((_measuredIndicatorWidth - image.size.width) / 2.0f); [image drawAtPoint:CGPointMake(centeredXOffset, yOffset)]; + imageRect = CGRectMake(centeredXOffset, yOffset, image.size.width, image.size.height); } else if (maskingImage) { yOffset = [self _topOffsetForHeight:maskSize.height rect:rect]; CGFloat centeredXOffset = xOffset + floorf((_measuredIndicatorWidth - maskSize.width) / 2.0f); - CGRect imageRect = CGRectMake(centeredXOffset, yOffset, maskSize.width, maskSize.height); + imageRect = CGRectMake(centeredXOffset, yOffset, maskSize.width, maskSize.height); CGContextDrawImage(context, imageRect, maskingImage); } else { yOffset = [self _topOffsetForHeight:_indicatorDiameter rect:rect]; CGFloat centeredXOffset = xOffset + floorf((_measuredIndicatorWidth - _indicatorDiameter) / 2.0f); - CGContextFillEllipseInRect(context, CGRectMake(centeredXOffset, yOffset, _indicatorDiameter, _indicatorDiameter)); + imageRect = CGRectMake(centeredXOffset, yOffset, _indicatorDiameter, _indicatorDiameter); + CGContextFillEllipseInRect(context, imageRect); } + [_pageRects addObject:[NSValue valueWithCGRect:imageRect]]; maskingImage = NULL; xOffset += _measuredIndicatorWidth + _indicatorMargin; } @@ -412,14 +419,32 @@ - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint point = [touch locationInView:self]; - CGSize size = [self sizeForNumberOfPages:self.numberOfPages]; - CGFloat left = [self _leftOffset]; - CGFloat middle = left + (size.width / 2.0f); - if (point.x < middle) { - [self setCurrentPage:self.currentPage - 1 sendEvent:YES canDefer:YES]; - } else { - [self setCurrentPage:self.currentPage + 1 sendEvent:YES canDefer:YES]; - } + + if (self.individualPageTaps) { + __block NSInteger pageTouched = -1; + [self.pageRects enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + CGRect indicatorRect = [obj CGRectValue]; + if (CGRectContainsPoint(indicatorRect, point)) { + pageTouched = idx; + *stop = YES; + } + }]; + + if (pageTouched != -1) { + [self setCurrentPage:pageTouched sendEvent:YES canDefer:YES]; + return; + } + } + + CGSize size = [self sizeForNumberOfPages:self.numberOfPages]; + CGFloat left = [self _leftOffset]; + CGFloat middle = left + (size.width / 2.0f); + if (point.x < middle) { + [self setCurrentPage:self.currentPage - 1 sendEvent:YES canDefer:YES]; + } else { + [self setCurrentPage:self.currentPage + 1 sendEvent:YES canDefer:YES]; + } + } #pragma mark - Accessors