我有一个UIView
名为dpCurvedLabel
. 它用于CATextLayers
围绕弧线弯曲文本。它工作得很好,除了我不能让它在图层父视图中完全居中。我希望弧的中心点位于视图的中心(即使视图较小),因此所有文本字符与中心的距离相同。
我可以让它关闭,但它总是至少有几个像素。它“关闭”的数量似乎受到我给每个CATextLayer
. 数学有问题,但我不知道是什么问题。我的代码:
// instantiate a dpCurvedLabel in a super view
dpCurvedLabel *curvedLabel = [[dpCurvedLabel alloc]
initWithFrame:CGRectMake(0, 0, 200, 200) arcSize:360 radius:50
text:@"curve curve curve " font:[UIFont fontWithName:@"HelveticaNeue" size:18]
textColor:[UIColor whiteColor]];
// You can animate a rotation to see a more pronounced effect
// [curvedLabel rotateContinously];
[self addSubview:curvedLabel];
dpCurvedLabel.h
#import <UIKit/UIKit.h>
@interface dpCurvedLabel : UIView
@property CGFloat arcSize;
@property CGFloat radius;
@property (strong) NSString *text;
@property (strong) UIFont *font;
@property (strong) UIColor *textColor;
- (id)initWithFrame:(CGRect)frame arcSize:(CGFloat)arcSize radius:(CGFloat)radius
text:(NSString *)text font:(UIFont *)font
textColor:(UIColor *)textColor;
- (void)rotateContinously;
+ (void)makeCurvedText:(CALayer *)layer arcSize:(CGFloat)arcSize radius:(CGFloat)radius
text:(NSString *)text font:(UIFont *)font textColor:(UIColor *)textColor;
@end
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
这里的数学有什么问题?为什么这个文本不会以自身为中心?