I have a subclass of UIView called dpCurvedLabel . It uses CATextLayers for curved text around an arc. It works fine, except that I cannot get it completely as a parent representation of the layers. I want the center point for the arc to be in the very center of the view (even if the view is smaller), so all text characters are at the same distance from the center.
I can get it CLOSE, but it always has at least a few pixels. It seems that the amount it turns off is determined by the size of the frame that I give each CATextLayer . Something is wrong with math, but I canβt understand that. My code is:
dpCurvedLabel.h
dpCurvedLabel.m
#import "dpCurvedLabel.h" @implementation dpCurvedLabel - (id)initWithFrame:(CGRect)frame arcSize:(CGFloat)arcSize radius:(CGFloat)radius text:(NSString *)text font:(UIFont *)font textColor:(UIColor *)textColor { self = [super initWithFrame:frame]; if (self) { // Initialization code self.opaque = NO; self.clipsToBounds = NO; self.arcSize = arcSize; self.radius = radius; self.text = text; self.font = font; self.textColor = textColor; } return self; } - (void)layoutSublayersOfLayer:(CALayer *)layer { [super layoutSublayersOfLayer:layer]; NSLog(@"laying out sublayers!"); [dpCurvedLabel makeCurvedText:layer arcSize:self.arcSize radius:self.radius text:self.text font:self.font textColor:self.textColor]; } + (void)makeCurvedText:(CALayer *)layer arcSize:(CGFloat)arcSize radius:(CGFloat)radius text:(NSString *)text font:(UIFont *)font textColor:(UIColor *)textColor { layer.sublayers = nil; layer.masksToBounds = NO; CGFloat arcStart = 0; CGFloat shiftH = 0; CGFloat shiftV = 0; BOOL clockwise = YES; BOOL debugMode = YES; CGFloat xcenter = CGRectGetMidX(layer.bounds); CGFloat ycenter = CGRectGetMidY(layer.bounds); CGFloat angle = arcStart; CGFloat angleStep = arcSize / text.length; for ( NSUInteger i = 0; i < text.length; ++i ) { NSRange range = { .location = i, .length = 1 }; NSString *c = [text substringWithRange:range]; CGFloat yoffset = sin( degreesToRadians(angle) ) * radius; CGFloat xoffset = cos( degreesToRadians(angle) ) * radius; CGFloat rotAngle = 90 - angle; if ( clockwise ) { yoffset = -yoffset; rotAngle = -90 + angle; } CATextLayer* tl = [[CATextLayer alloc] init]; tl.masksToBounds = NO; tl.wrapped = NO; tl.truncationMode = kCATruncationNone; if ( debugMode ) { tl.borderWidth = 1; tl.cornerRadius = 3; tl.borderColor = [UIColor whiteColor].CGColor; } // Text layer frame determined here. Effects how arc is centered. CGSize charSize = CGSizeMake(20, 20); tl.frame = CGRectMake( shiftH + xcenter - xoffset, shiftV + ycenter + yoffset, charSize.width, charSize.height ); // ******* tl.font = (__bridge CFTypeRef)(font.fontName); tl.fontSize = font.pointSize; tl.foregroundColor = textColor.CGColor; tl.string = c; tl.alignmentMode = @"center"; tl.transform = CATransform3DMakeAffineTransform( CGAffineTransformMakeRotation( degreesToRadians(rotAngle) ) ); [layer addSublayer:tl]; angle += angleStep; } if ( debugMode ) { layer.backgroundColor = RGBA(0x00, 0x00, 0x00, .6).CGColor; } } - (void)rotateContinously { CABasicAnimation *rotationAnimation; rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 2.0 /* full rotation*/ * 1 * 1 ]; rotationAnimation.duration = 5; rotationAnimation.cumulative = YES; rotationAnimation.repeatCount = INT_MAX; [self.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"]; } @end
What happened to math here? Why won't this text self-center?
source share