diff --git a/NYSegmentedControl/NYSegmentLabel.h b/NYSegmentedControl/NYSegmentLabel.h index 31c5a19..86a6391 100644 --- a/NYSegmentedControl/NYSegmentLabel.h +++ b/NYSegmentedControl/NYSegmentLabel.h @@ -14,5 +14,6 @@ @property (nonatomic, strong) UIColor *alternativeTextColor; @property (nonatomic, assign) CGRect maskFrame; @property (nonatomic, assign) CGFloat maskCornerRadius; +@property(nonatomic, strong) UIFont *alternativeFont; @end \ No newline at end of file diff --git a/NYSegmentedControl/NYSegmentLabel.m b/NYSegmentedControl/NYSegmentLabel.m index 2f28519..78e18ad 100644 --- a/NYSegmentedControl/NYSegmentLabel.m +++ b/NYSegmentedControl/NYSegmentLabel.m @@ -9,8 +9,114 @@ #import "NYSegmentLabel.h" +@interface NYSegmentLabel () +@property(nonatomic, strong) NSDictionary *normalAttributes; +@property(nonatomic, strong) NSDictionary *alternativeAttributes; +@end + @implementation NYSegmentLabel +- (instancetype)init { + self = [super init]; + if (self) { + [self commonInit]; + } + + return self; +} + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + [self commonInit]; + } + + return self; +} + +- (id)initWithCoder:(NSCoder *)coder { + self = [super initWithCoder:coder]; + if (self) { + [self commonInit]; + } + + return self; +} + +- (void)commonInit { + _alternativeTextColor = self.textColor; + _alternativeFont = self.font; + + [self setupAlternativeAttributes]; +} + +- (void)drawRect:(CGRect)rect { + CGSize size = [self.text sizeWithAttributes:self.normalAttributes]; + + // Centered rect + CGRect drawRect = CGRectMake(rect.origin.x, + rect.origin.y + (rect.size.height - size.height)/2, + rect.size.width, + (size.height)); + + // Get current context + CGContextRef context = UIGraphicsGetCurrentContext(); + CGContextSaveGState(context); + + if (!CGRectIsEmpty(self.maskFrame)) { + // Frames to draw normal text within + CGRect beforeMaskFrame = CGRectMake(0, 0, CGRectGetMinX(self.maskFrame), CGRectGetHeight(self.frame)); + CGRect afterMaskFrame = CGRectMake(CGRectGetMaxX(self.maskFrame), 0, CGRectGetWidth(self.frame) - CGRectGetMaxX(self.maskFrame), CGRectGetHeight(self.frame)); + CGRect rects[2] = {beforeMaskFrame, afterMaskFrame}; + + // Clip to those frames + CGContextClipToRects(context, rects, 2); + } + + [self.text drawInRect:drawRect withAttributes:self.normalAttributes]; + + // Restore state + CGContextRestoreGState(context); + + if (!CGRectIsEmpty(self.maskFrame)) { + context = UIGraphicsGetCurrentContext(); + + // Clip to mask + CGContextClipToRect(context, self.maskFrame); + + // Draw masked text + [self.text drawInRect:drawRect withAttributes:self.alternativeAttributes]; + } +} + +#pragma mark - Private + +- (void)setupAlternativeAttributes { + NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; + paragraphStyle.alignment = NSTextAlignmentCenter; + + NSDictionary *alternativeAttributes = @{ NSFontAttributeName: self.alternativeFont, + NSForegroundColorAttributeName : self.alternativeTextColor, + NSParagraphStyleAttributeName: paragraphStyle + }; + + self.alternativeAttributes = alternativeAttributes; +} + +- (void)setupNormalAttributes { + NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; + paragraphStyle.alignment = NSTextAlignmentCenter; + + NSDictionary *normalAttributes = @{ NSFontAttributeName: self.font, + NSForegroundColorAttributeName : self.textColor, + NSParagraphStyleAttributeName: paragraphStyle + }; + + self.normalAttributes = normalAttributes; +} + +#pragma mark - Setters + - (void)setMaskFrame:(CGRect)maskFrame { _maskFrame = maskFrame; @@ -23,57 +129,28 @@ - (void)setMaskCornerRadius:(CGFloat)maskCornerRadius { [self setNeedsDisplay]; } -- (void)drawRect:(CGRect)rect { - CGContextRef context = UIGraphicsGetCurrentContext(); +- (void)setTextColor:(UIColor *)textColor { + [super setTextColor:textColor]; - // Draw text normally - [super drawTextInRect:rect]; - - if (self.alternativeTextColor) { - CGImageRef mask = NULL; - - // Create a mask from the text - mask = CGBitmapContextCreateImage(context); - - CGContextSaveGState(context); - CGContextTranslateCTM(context, 0, self.frame.size.height); - CGContextScaleCTM(context, 1.0, (CGFloat) -1.0); - - // Clip the current context to our mask - CGContextClipToMask(context, rect, mask); - - // Set fill color - CGContextSetFillColorWithColor(context, [self.alternativeTextColor CGColor]); - - // Path from mask - CGPathRef path; - - if (CGRectIsEmpty(self.maskFrame)) { - path = CGPathCreateMutable(); - } else { - UIBezierPath *roundRectBezierPath = [UIBezierPath bezierPathWithRoundedRect:self.maskFrame - cornerRadius:self.maskCornerRadius]; - path = CGPathCreateCopy([roundRectBezierPath CGPath]); - } - - CGContextAddPath(context, path); - - // Fill the path - CGContextFillPath(context); - CFRelease(path); - - // Clean up - CGContextRestoreGState(context); - CGImageRelease(mask); - } + [self setupNormalAttributes]; } -- (UIColor *)alternativeTextColor { - if (!_alternativeTextColor) { - _alternativeTextColor = self.textColor; - } - - return _alternativeTextColor; +- (void)setAlternativeTextColor:(UIColor *)alternativeTextColor { + _alternativeTextColor = alternativeTextColor; + + [self setupAlternativeAttributes]; +} + +- (void)setAlternativeFont:(UIFont *)alternativeFont { + _alternativeFont = alternativeFont; + + [self setupAlternativeAttributes]; +} + +- (void)setFont:(UIFont *)font { + [super setFont:font]; + + [self setupNormalAttributes]; } @end diff --git a/NYSegmentedControl/NYSegmentedControl.m b/NYSegmentedControl/NYSegmentedControl.m index 50dbcd4..a1d6f5c 100644 --- a/NYSegmentedControl/NYSegmentedControl.m +++ b/NYSegmentedControl/NYSegmentedControl.m @@ -174,14 +174,13 @@ - (void)layoutSubviews { if (self.stylesTitleForSelectedSegment) { if (self.selectedSegmentIndex == i) { - segment.titleLabel.font = self.selectedTitleFont; segment.titleLabel.maskFrame = segment.titleLabel.bounds; - } else { - segment.titleLabel.font = self.titleFont; } + segment.titleLabel.font = self.titleFont; segment.titleLabel.alternativeTextColor = self.selectedTitleTextColor; segment.titleLabel.textColor = self.titleTextColor; + segment.titleLabel.alternativeFont = self.selectedTitleFont; } else { segment.titleLabel.font = self.titleFont; segment.titleLabel.textColor = self.titleTextColor; @@ -262,8 +261,6 @@ - (void)moveSelectedSegmentIndicatorToSegmentAtIndex:(NSUInteger)index animated: duration:self.segmentIndicatorAnimationDuration options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ - previousSegment.titleLabel.font = self.titleFont; - previousSegment.titleLabel.textColor = self.titleTextColor; previousSegment.titleLabel.maskFrame = CGRectZero; } completion:nil]; @@ -272,12 +269,6 @@ - (void)moveSelectedSegmentIndicatorToSegmentAtIndex:(NSUInteger)index animated: duration:self.segmentIndicatorAnimationDuration options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ - selectedSegment.titleLabel.font = self.selectedTitleFont; - selectedSegment.titleLabel.textColor = self.selectedTitleTextColor; - - if (self.drawsSegmentIndicatorGradientBackground) { - //selectedSegment.titleLabel.shadowColor = [UIColor darkGrayColor]; - } } completion:nil]; } @@ -312,7 +303,6 @@ - (void)moveSelectedSegmentIndicatorToSegmentAtIndex:(NSUInteger)index animated: self.selectedSegmentIndicator.frame = [self indicatorFrameForSegment:selectedSegment]; if (self.stylesTitleForSelectedSegment) { - selectedSegment.titleLabel.font = self.selectedTitleFont; selectedSegment.titleLabel.maskFrame = selectedSegment.titleLabel.bounds; } } @@ -326,12 +316,6 @@ - (void)panGestureRecognized:(UIPanGestureRecognizer *)panGestureRecognizer { if (self.stylesTitleForSelectedSegment) { // Style the segment the center of the indicator is covering [self.segments enumerateObjectsUsingBlock:^(NYSegment *segment, NSUInteger index, BOOL *stop) { - if (CGRectContainsPoint(segment.frame, self.selectedSegmentIndicator.center)) { - segment.titleLabel.font = self.selectedTitleFont; - } else { - segment.titleLabel.font = self.titleFont; - } - CGRect segmentFrame = segment.frame; CGRect intersection = CGRectIntersection(segmentFrame, self.selectedSegmentIndicator.frame); CGAffineTransform transform = CGAffineTransformMakeTranslation(-CGRectGetMinX(segmentFrame), -CGRectGetMinY(segmentFrame));