用于渲染一个无格式或属性文本字符
一、CATextLayer属性
- 1、 @property(copy) id string;
文本呈现,可以是一个NSString或者NSAttributedString;默认为nil - 2、 @property CFTypeRef font;
字体使用,可能是一个CTFontRef,一个CGFontRef或者一个字符串命名体,默认为Helvetica字体;仅当string不是一个NSAttributedString的时候使用; - 3、 @property CGFloat fontSize;
字体大小,默认为36;仅当string不是一个NSAttributedString的时候使用; - 4、 @property CGColorRef foregroundColor;
用来绘制文本的颜色,默认为不透明的白色;仅当string不是一个NSAttributedString的时候使用; - 5、 @property(getter=isWrapped) BOOL wrapped;
文本自适应图层大小,默认是NO; - 6、 @property(copy) NSString *truncationMode;
描述如何将字符串截断以适应图层大小,设置缩短的部位,可选择没有,开始,中间,和结束;如下:
/* Truncation modes. */
CA_EXTERN NSString * const kCATruncationNone
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_3_2);
CA_EXTERN NSString * const kCATruncationStart
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_3_2);
CA_EXTERN NSString * const kCATruncationEnd
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_3_2);
CA_EXTERN NSString * const kCATruncationMiddle
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_3_2);
- 7、 @property(copy) NSString *alignmentMode;
描述如何在该层中的单行的文本对齐,设置字体的排列格式,可选择自然,左,右,居中和自适应;默认为自然;如下:
/* Alignment modes. */
CA_EXTERN NSString * const kCAAlignmentNatural
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_3_2);
CA_EXTERN NSString * const kCAAlignmentLeft
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_3_2);
CA_EXTERN NSString * const kCAAlignmentRight
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_3_2);
CA_EXTERN NSString * const kCAAlignmentCenter
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_3_2);
CA_EXTERN NSString * const kCAAlignmentJustified
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_3_2);
8、 @property CGFloat contentsScale;
使用CATextLayer设置文本,可能会产生模糊状态,因为该默认的分辨率不是retina,设置如下代码即可:textLayer.contentsScale = [UIScreen mainScreen].scale;
二、CATextLayer与 CAGradientLayer(会员金闪闪动画字体)
代码如下:
#define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
@interface ViewController ()
{
CATextLayer *textLayer;
CAGradientLayer *gradientLayer;
UIView* bgView;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIButton* btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(0, self.view.frame.size.height - 40, self.view.frame.size.width, 40);
[btn setTitle:@"开始动画" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(clickBtn) forControlEvents:UIControlEventTouchUpInside];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[self.view addSubview:btn];
bgView = [[UIView alloc]initWithFrame:CGRectMake(0, 40, self.view.frame.size.width, self.view.frame.size.width)];
bgView.backgroundColor = [UIColor brownColor];
[self.view addSubview:bgView];
textLayer = [CATextLayer layer];
textLayer.frame = CGRectMake((bgView.frame.size.width - 200)/2, (bgView.frame.size.width - 200)/2, 200, 200);
textLayer.foregroundColor = [UIColor blackColor].CGColor;
textLayer.alignmentMode =kCAAlignmentJustified;
textLayer.wrapped =YES;
UIFont *font = [UIFont systemFontOfSize:30];
CFStringRef fontName = (__bridge CFStringRef)font.fontName;
CGFontRef fontRef =CGFontCreateWithFontName(fontName);
textLayer.font = fontRef;
textLayer.fontSize = font.pointSize;
CGFontRelease(fontRef);
NSString *text =@"习惯不曾习惯的习惯会习惯 舍得不曾舍得的舍得会舍得";
textLayer.string = text;
textLayer.contentsScale = [UIScreen mainScreen].scale;
[bgView.layer addSublayer:textLayer];
//创建背景图层
gradientLayer = [CAGradientLayer layer];
[gradientLayer setColors:[NSArray arrayWithObjects:
(id)[UIColorFromRGB(0x000000) CGColor],
(id)[UIColorFromRGB(0xFFD700) CGColor],
(id)[UIColorFromRGB(0x000000) CGColor],
(id)[UIColorFromRGB(0xFFD700) CGColor],
(id)[UIColorFromRGB(0x000000) CGColor],
(id)[UIColorFromRGB(0xFFD700) CGColor],
(id)[UIColorFromRGB(0x000000) CGColor],
(id)[UIColorFromRGB(0xFFD700) CGColor],
(id)[UIColorFromRGB(0x000000) CGColor],
(id)[UIColorFromRGB(0xFFD700) CGColor],
(id)[UIColorFromRGB(0x000000) CGColor],
(id)[[UIColor clearColor] CGColor],
nil]];
gradientLayer.frame = bgView.bounds;
[gradientLayer setLocations:[NSArray arrayWithObjects:
[NSNumber numberWithFloat:0.0],
[NSNumber numberWithFloat:0.1],
[NSNumber numberWithFloat:0.2],
[NSNumber numberWithFloat:0.3],
[NSNumber numberWithFloat:0.4],
[NSNumber numberWithFloat:0.5],
[NSNumber numberWithFloat:0.6],
[NSNumber numberWithFloat:0.7],
[NSNumber numberWithFloat:0.8],
[NSNumber numberWithFloat:0.9],
[NSNumber numberWithFloat:1.0],
nil]];
[gradientLayer setStartPoint:CGPointMake(0, 0)];
[gradientLayer setEndPoint:CGPointMake(1, 1)];
[gradientLayer setMask:textLayer]; //用progressLayer来截取渐变层
[bgView.layer addSublayer:gradientLayer];
}
- (void)clickBtn{
//动画
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
CGPoint fromPoint = textLayer.position;
CGPoint toPoint = CGPointMake(fromPoint.x + (bgView.frame.size.width - 200)/2, fromPoint.y);
animation.duration = 1;
animation.fromValue = [NSValue valueWithCGPoint:fromPoint];
animation.toValue = [NSValue valueWithCGPoint:toPoint];
animation.autoreverses = YES;
[textLayer addAnimation:animation forKey:nil];
CABasicAnimation *animation2 = [CABasicAnimation animationWithKeyPath:@"position"];
CGPoint fromPoint2 = gradientLayer.position;
CGPoint toPoint2 = CGPointMake(fromPoint.x - (bgView.frame.size.width - 200)/2, fromPoint.y);
animation2.duration = 1;
animation2.fromValue = [NSValue valueWithCGPoint:fromPoint2];
animation2.toValue = [NSValue valueWithCGPoint:toPoint2];
animation2.autoreverses = YES;
[gradientLayer addAnimation:animation2 forKey:nil];
}
三、CATextLayer与 CAShapeLayer(波浪)
- 1、 XYWaterWaveView.h文件
#import <UIKit/UIKit.h>
@interface XYWaterWaveView : UIView
/**
* 波纹振幅 默认30
*/
@property (nonatomic ,assign) CGFloat waveAmplitude;
/**
* 振幅周期 默认200
*/
@property (nonatomic ,assign) CGFloat waveCycle;
/**
* 波纹速度 默认 0.2
*/
@property (nonatomic ,assign) CGFloat waveSpeed;
/**
* 波纹高度 默认为300
*/
@property (nonatomic ,assign) CGFloat waterWaveHeight;
/**
* 波纹颜色 默认红色
*/
@property (nonatomic, strong) UIColor* waveColor;
/**
* 开始
*/
- (void)startWave;
@end
- 2、 XYWaterWaveView.m文件
#import "XYWaterWaveView.h"
@interface XYWaterWaveView()
{
CGFloat _height;
CGFloat _width;
}
/**
* 波纹偏移
*/
@property (nonatomic ,assign) CGFloat offsetX;
/**
* 波纹频率
*/
@property (nonatomic ,assign) CGFloat waveRate;
/**
* 定时器
*/
@property (nonatomic, strong) CADisplayLink *waveDisplaylink;
/**
* 波纹图层
*/
@property (nonatomic, strong) CAShapeLayer *waveLayer;
/**
* 背景图层
*/
@property (nonatomic, strong) CAShapeLayer *backLayer;
/**
* 介绍
*/
@property (nonatomic, strong) CATextLayer *textLayer;
@end
@implementation XYWaterWaveView
#pragma mark -- init
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
[self initData];
}
return self;
}
- (void)initData{
/**
Asin(rt + x)
A:waveAmplitude
r:waveRate
x:offsetX
*/
//振幅
self.waveAmplitude = 30.0f;
//周期
self.waveCycle = 200.0f;
//频率
self.waveRate = 2*M_PI/self.waveCycle;
//偏移
self.offsetX = 0.0f;
//高度
self.waterWaveHeight = 300.0f;
//速度
self.waveSpeed = 0.2f;
//颜色
self.waveColor = [UIColor redColor];
_height = self.frame.size.height;
_width = self.frame.size.width;
}
#pragma mark - set
- (void)setWaveAmplitude:(CGFloat)waveAmplitude{
_waveAmplitude = waveAmplitude;
}
- (void)setWaveCycle:(CGFloat)waveCycle{
_waveCycle = waveCycle;
_waveRate = 2*M_PI/_waveCycle;
}
- (void)setWaterWaveHeight:(CGFloat)waterWaveHeight{
_waterWaveHeight = waterWaveHeight;
NSString *text = [NSString stringWithFormat:@"%.2f%@",_waterWaveHeight/_height*100,@"%"];
_textLayer.string = text;
}
- (void)setWaveSpeed:(CGFloat)waveSpeed{
_waveSpeed = waveSpeed;
}
#pragma mark -- 开始
- (void)startWave{
if (_waveDisplaylink) {
return;
}
if (self.waveLayer == nil) {
// 创建第一个波浪Layer
_waveLayer = [CAShapeLayer layer];
_waveLayer.fillColor = self.waveColor.CGColor;
[self.layer addSublayer:_waveLayer];
}
if (self.backLayer == nil) {
_backLayer = [CAShapeLayer layer];
_backLayer.frame = self.bounds;
_backLayer.fillColor = [UIColor yellowColor].CGColor;
_backLayer.backgroundColor = [UIColor blackColor].CGColor;
[self.layer addSublayer:_backLayer];
}
if (self.textLayer == nil) {
_textLayer = [CATextLayer layer];
_textLayer.foregroundColor = [UIColor blackColor].CGColor;
_textLayer.alignmentMode =kCAAlignmentJustified;
_textLayer.wrapped =YES;
_textLayer.frame = CGRectMake((_width - 150)/2, (_height - 40)/2, 150, 40);
UIFont *font = [UIFont systemFontOfSize:40];
CFStringRef fontName = (__bridge CFStringRef)font.fontName;
CGFontRef fontRef =CGFontCreateWithFontName(fontName);
_textLayer.font = fontRef;
_textLayer.fontSize = font.pointSize;
CGFontRelease(fontRef);
NSString *text = [NSString stringWithFormat:@"%.2f%@",_waterWaveHeight/_height*100,@"%"];
_textLayer.string = text;
_textLayer.contentsScale = [UIScreen mainScreen].scale;
[self.layer addSublayer:_textLayer];
[_backLayer setMask:_textLayer];
}
// 启动定时调用
_waveDisplaylink = [CADisplayLink displayLinkWithTarget:self selector:@selector(getCurrentWave:)];
[_waveDisplaylink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}
- (void)getCurrentWave:(CADisplayLink *)dicplayLink{
// 波浪位移
self.offsetX += self.waveSpeed;
if (self.waterWaveHeight > _height - self.waveAmplitude) {
self.waterWaveHeight = _height - self.waveAmplitude;
}
[self setCurrentWaveLayerPath];
}
- (void)setCurrentWaveLayerPath{
CGMutablePathRef path = CGPathCreateMutable();
CGFloat currentWavePointY = _height - self.waterWaveHeight;
CGPathMoveToPoint(path, nil, 0, currentWavePointY);
for (float x = 0.0f; x <= _width ; x++) {
// 正弦波浪公式
CGFloat y = self.waveAmplitude * sin(self.waveRate * x + self.offsetX) + currentWavePointY;
CGPathAddLineToPoint(path, nil, x, y);
}
CGPathAddLineToPoint(path, nil, _width, _height);
CGPathAddLineToPoint(path, nil, 0, _height);
CGPathCloseSubpath(path);
self.waveLayer.path = path;
CGMutablePathRef backPath = CGPathCreateMutableCopy(path);
self.backLayer.path = backPath;
CGPathRelease(backPath);
CGPathRelease(path);
}
#pragma mark -- 停止
- (void)reset
{
[self stopWave];
[_waveLayer removeFromSuperlayer];
_waveLayer = nil;
}
- (void)stopWave{
[_waveDisplaylink invalidate];
_waveDisplaylink = nil;
}
- (void)dealloc{
[self reset];
}
@end
- 3、 ViewController调用
- (void)viewDidLoad {
[super viewDidLoad];
waterWaveView = [[XYWaterWaveView alloc]initWithFrame:self.view.bounds];
waterWaveView.backgroundColor = [UIColor clearColor];
[self.view addSubview:waterWaveView];
[waterWaveView startWave];
//振幅
UILabel* label1 = [[UILabel alloc]initWithFrame:CGRectMake(0, 20, 60, 40)];
label1.text = @"振幅";
[self.view addSubview:label1];
UISlider* slider1 = [[UISlider alloc]initWithFrame:CGRectMake(40, 20, 280, 40)];
slider1.minimumValue = 20.0;
slider1.maximumValue = 40.0;
slider1.value = 30;
[slider1 addTarget:self action:@selector(slider1:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:slider1];
//周期
UILabel* label2 = [[UILabel alloc]initWithFrame:CGRectMake(0, 80, 60, 40)];
label2.text = @"周期";
[self.view addSubview:label2];
UISlider* slider2 = [[UISlider alloc]initWithFrame:CGRectMake(40, 80, 280, 40)];
slider2.minimumValue = 100.0;
slider2.maximumValue = 300.0;
slider2.value = 200;
[slider2 addTarget:self action:@selector(slider2:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:slider2];
//速度
UILabel* label3 = [[UILabel alloc]initWithFrame:CGRectMake(0, 140, 60, 40)];
label3.text = @"速度";
[self.view addSubview:label3];
UISlider* slider3 = [[UISlider alloc]initWithFrame:CGRectMake(40, 140, 280, 40)];
slider3.minimumValue = 0.1f;
slider3.maximumValue = 0.3f;
slider3.value = 0.2f;
[slider3 addTarget:self action:@selector(slider3:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:slider3];
//高度
UILabel* label4 = [[UILabel alloc]initWithFrame:CGRectMake(0, 200, 60, 40)];
label4.text = @"高度";
[self.view addSubview:label4];
UISlider* slider4 = [[UISlider alloc]initWithFrame:CGRectMake(40, 200, 280, 40)];
slider4.minimumValue = 0;
slider4.maximumValue = self.view.frame.size.height;
slider4.value = 300;
[slider4 addTarget:self action:@selector(slider4:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:slider4];
}
- (void)slider1:(UISlider *)slider{
waterWaveView.waveAmplitude = slider.value;
}
- (void)slider2:(UISlider *)slider{
waterWaveView.waveCycle = slider.value;
}
- (void)slider3:(UISlider *)slider{
waterWaveView.waveSpeed = slider.value;
}
- (void)slider4:(UISlider *)slider{
waterWaveView.waterWaveHeight = slider.value;
}