Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow the setting of a mask for the current page indicator as an alternative to a normal image. #23

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions SMPageControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ typedef NS_ENUM(NSUInteger, SMPageControlTapBehavior) {
- (void)setImage:(UIImage *)image forPage:(NSInteger)pageIndex;
- (void)setCurrentImage:(UIImage *)image forPage:(NSInteger)pageIndex;
- (void)setImageMask:(UIImage *)image forPage:(NSInteger)pageIndex;
- (void)setCurrentImageMask:(UIImage *)image forPage:(NSInteger)pageIndex;

- (UIImage *)imageForPage:(NSInteger)pageIndex;
- (UIImage *)currentImageForPage:(NSInteger)pageIndex;
Expand Down
99 changes: 81 additions & 18 deletions SMPageControl.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
typedef NS_ENUM(NSUInteger, SMPageControlImageType) {
SMPageControlImageTypeNormal = 1,
SMPageControlImageTypeCurrent,
SMPageControlImageTypeMask
SMPageControlImageTypeMask,
SMPageControlImageTypeCurrentMask
};

typedef NS_ENUM(NSUInteger, SMPageControlStyleDefaults) {
Expand All @@ -39,7 +40,9 @@ @interface SMPageControl ()
@property (strong, readonly, nonatomic) NSMutableDictionary *pageImages;
@property (strong, readonly, nonatomic) NSMutableDictionary *currentPageImages;
@property (strong, readonly, nonatomic) NSMutableDictionary *pageImageMasks;
@property (strong, readonly, nonatomic) NSMutableDictionary *currentPageImageMasks;
@property (strong, readonly, nonatomic) NSMutableDictionary *cgImageMasks;
@property (strong, readonly, nonatomic) NSMutableDictionary *cgCurrentImageMasks;
@property (strong, readwrite, nonatomic) NSArray *pageRects;

// Page Control used for stealing page number localizations for accessibility labels
Expand All @@ -60,8 +63,10 @@ @implementation SMPageControl
@synthesize pageNames = _pageNames;
@synthesize pageImages = _pageImages;
@synthesize currentPageImages = _currentPageImages;
@synthesize currentPageImageMasks = _currentPageImageMasks;
@synthesize pageImageMasks = _pageImageMasks;
@synthesize cgImageMasks = _cgImageMasks;
@synthesize cgCurrentImageMasks = _cgCurrentImageMasks;

+ (void)initialize
{
Expand Down Expand Up @@ -157,7 +162,9 @@ - (void)_renderPages:(CGContextRef)context rect:(CGRect)rect
fillColor = _currentPageIndicatorTintColor ? _currentPageIndicatorTintColor : [UIColor whiteColor];
image = _currentPageImages[indexNumber];
if (nil == image) {
image = _currentPageIndicatorImage;
if (nil == _currentPageImageMasks[indexNumber]) {
image = _currentPageIndicatorImage;
}
}
} else {
fillColor = _pageIndicatorTintColor ? _pageIndicatorTintColor : [[UIColor whiteColor] colorWithAlphaComponent:0.3f];
Expand All @@ -169,24 +176,30 @@ - (void)_renderPages:(CGContextRef)context rect:(CGRect)rect

// If no finished images have been set, try a masking image
if (nil == image) {
maskingImage = (__bridge CGImageRef)_cgImageMasks[indexNumber];
UIImage *originalImage = _pageImageMasks[indexNumber];
maskSize = originalImage.size;

if (i == _displayedPage) {
maskingImage = (__bridge CGImageRef)_cgCurrentImageMasks[indexNumber];
UIImage *originalImage = _currentPageImageMasks[indexNumber];
maskSize = originalImage.size;
} else {
maskingImage = (__bridge CGImageRef)_cgImageMasks[indexNumber];
UIImage *originalImage = _pageImageMasks[indexNumber];
maskSize = originalImage.size;
}

// If no per page mask is set, try for a global page mask!
if (nil == maskingImage) {
maskingImage = _pageImageMask;
maskSize = _pageIndicatorMaskImage.size;
}
}

[fillColor set];
CGRect indicatorRect;
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)];
indicatorRect = CGRectMake(centeredXOffset, yOffset, image.size.width, image.size.height);
indicatorRect = 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);
Expand All @@ -195,11 +208,11 @@ - (void)_renderPages:(CGContextRef)context rect:(CGRect)rect
} else {
yOffset = [self _topOffsetForHeight:_indicatorDiameter rect:rect];
CGFloat centeredXOffset = xOffset + floorf((_measuredIndicatorWidth - _indicatorDiameter) / 2.0f);
indicatorRect = CGRectMake(centeredXOffset, yOffset, _indicatorDiameter, _indicatorDiameter);
indicatorRect = CGRectMake(centeredXOffset, yOffset, _indicatorDiameter, _indicatorDiameter);
CGContextFillEllipseInRect(context, indicatorRect);
}

[pageRects addObject:[NSValue valueWithCGRect:indicatorRect]];
[pageRects addObject:[NSValue valueWithCGRect:indicatorRect]];
maskingImage = NULL;
xOffset += _measuredIndicatorWidth + _indicatorMargin;
}
Expand Down Expand Up @@ -287,15 +300,18 @@ - (void)_setImage:(UIImage *)image forPage:(NSInteger)pageIndex type:(SMPageCont
case SMPageControlImageTypeMask:
dictionary = self.pageImageMasks;
break;
case SMPageControlImageTypeCurrentMask:
dictionary = self.currentPageImageMasks;
break;
default:
break;
}
if (image) {
dictionary[@(pageIndex)] = image;
} else {
[dictionary removeObjectForKey:@(pageIndex)];
}
if (image) {
dictionary[@(pageIndex)] = image;
} else {
[dictionary removeObjectForKey:@(pageIndex)];
}
}

- (void)setImage:(UIImage *)image forPage:(NSInteger)pageIndex
Expand All @@ -310,6 +326,25 @@ - (void)setCurrentImage:(UIImage *)image forPage:(NSInteger)pageIndex
[self _updateMeasuredIndicatorSizes];
}

- (void)setCurrentImageMask:(UIImage *)image forPage:(NSInteger)pageIndex
{
[self _setImage:image forPage:pageIndex type:SMPageControlImageTypeCurrentMask];

if (nil == image) {
[self.cgCurrentImageMasks removeObjectForKey:@(pageIndex)];
return;
}

CGImageRef maskImage = [self createMaskForImage:image];

if (maskImage) {
self.cgCurrentImageMasks[@(pageIndex)] = (__bridge id)maskImage;
CGImageRelease(maskImage);
[self _updateMeasuredIndicatorSizeWithSize:image.size];
[self setNeedsDisplay];
}
}

- (void)setImageMask:(UIImage *)image forPage:(NSInteger)pageIndex
{
[self _setImage:image forPage:pageIndex type:SMPageControlImageTypeMask];
Expand Down Expand Up @@ -346,6 +381,9 @@ - (id)_imageForPage:(NSInteger)pageIndex type:(SMPageControlImageType)type
case SMPageControlImageTypeMask:
dictionary = _pageImageMasks;
break;
case SMPageControlImageTypeCurrentMask:
dictionary = _currentPageImageMasks;
break;
default:
break;
}
Expand All @@ -368,6 +406,11 @@ - (UIImage *)imageMaskForPage:(NSInteger)pageIndex
return [self _imageForPage:pageIndex type:SMPageControlImageTypeMask];
}

- (UIImage *)currentImageMaskForPage:(NSInteger)pageIndex
{
return [self _imageForPage:pageIndex type:SMPageControlImageTypeCurrentMask];
}

- (CGSize)sizeThatFits:(CGSize)size
{
CGSize sizeThatFits = [self sizeForNumberOfPages:self.numberOfPages];
Expand Down Expand Up @@ -430,7 +473,7 @@ - (CGImageRef)createMaskForImage:(UIImage *)image CF_RETURNS_RETAINED
CGContextDrawImage(context, CGRectMake(0, 0, pixelsWide, pixelsHigh), image.CGImage);
CGImageRef maskImage = CGBitmapContextCreateImage(context);
CGContextRelease(context);

return maskImage;
}

Expand Down Expand Up @@ -463,7 +506,7 @@ - (void)_updateMeasuredIndicatorSizes
if (self.pageIndicatorMaskImage) {
[self _updateMeasuredIndicatorSizeWithSize:self.pageIndicatorMaskImage.size];
}

if ([self respondsToSelector:@selector(invalidateIntrinsicContentSize)]) {
[self invalidateIntrinsicContentSize];
}
Expand Down Expand Up @@ -681,6 +724,16 @@ - (NSMutableDictionary *)pageImageMasks
return _pageImageMasks;
}

- (NSMutableDictionary *)currentPageImageMasks
{
if (nil != _currentPageImageMasks) {
return _currentPageImageMasks;
}

_currentPageImageMasks = [[NSMutableDictionary alloc] init];
return _currentPageImageMasks;
}

- (NSMutableDictionary *)cgImageMasks
{
if (nil != _cgImageMasks) {
Expand All @@ -691,6 +744,16 @@ - (NSMutableDictionary *)cgImageMasks
return _cgImageMasks;
}

- (NSMutableDictionary *)cgCurrentImageMasks
{
if (nil != _cgCurrentImageMasks) {
return _cgCurrentImageMasks;
}

_cgCurrentImageMasks = [[NSMutableDictionary alloc] init];
return _cgCurrentImageMasks;
}

#pragma mark - UIAccessibility

- (void)setName:(NSString *)name forPage:(NSInteger)pageIndex
Expand Down