在 极客学院 简单学习了一下 如何使用maskView设计动画效果
主要是通过CAGradientLayer 或者 带有alpha的图片来操作
//MARK:1. maskView(maskLayer)基本原理 CGFloat width = 120.f; //底图 self.baseImageView = [[UIImageView alloc]initWithFrame:CGRectMake(20, 20, width, width)]; [_baseImageView setImage:[UIImage imageNamed:@"base"]]; [self.view addSubview:_baseImageView]; //mask 是有透明的 self.maskImageView = [[UIImageView alloc]initWithFrame:CGRectMake(20, 20 + width + 20, width, width)]; [_maskImageView setImage:[UIImage imageNamed:@"mask"]]; [self.view addSubview:_maskImageView]; //使用maskView的情况 self.addImageView = [[UIImageView alloc]initWithFrame:CGRectMake(20, 20 + (width + 20) * 2, width, width)]; [_addImageView setImage:[UIImage imageNamed:@"base"]]; UIImageView *mask = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, width, width)]; [mask setImage:[UIImage imageNamed:@"mask"]]; [_addImageView setMaskView:mask];//iOS8.0之后才有 maskView不能用addSubView的方式来添加遮罩!!! /*iOS 8之前 // CALayer *layer = [CALayer layer]; // [layer setFrame:CGRectMake(0, 0, width, width)]; // [layer setContents:(id)[UIImage imageNamed:@"mask"].CGImage]; // [_addImageView.layer setMask:layer]; */ [self.view addSubview:_addImageView]; //MARK:2. maskView配合CAGradientLayer的使用 // 第一步 加载图片 UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(width + 40, 20, 200, 200)]; [imageView setImage:[UIImage imageNamed:@"base"]]; [self.view addSubview:imageView]; // 第二步 创建出CAGradientLayer CAGradientLayer *gradientLayer = [CAGradientLayer layer]; [gradientLayer setFrame:imageView.bounds];//遮罩层的区域 [gradientLayer setColors:@[(__bridge id)[UIColor clearColor].CGColor, (__bridge id)[UIColor blackColor].CGColor, (__bridge id)[UIColor clearColor].CGColor]];//渐变的颜色数组 __bridge id类型 [gradientLayer setLocations:@[@(0.25),@(0.5),@(0.75)]];//渐变的区域 整个是1 0.25就是1/4处以此类推 [gradientLayer setStartPoint:CGPointMake(0, 0)]; [gradientLayer setEndPoint:CGPointMake(1, 0)];//渐变的方向(1,0)就是横向 (1,1)就是从左上角到右下角以此类推 // 第三步 创建一个容器View 用于加载创建出的CAGradientLayer UIView *containerView = [[UIView alloc]initWithFrame:imageView.bounds]; [containerView.layer addSublayer:gradientLayer]; // 最后 设定maskView imageView.maskView = containerView; // 扩展 给maskView做动画 除了修改容器view的fram值之外 还可以动态的修改location startPoint endPoint等 实现很绚丽的动画效果 CGRect frame = containerView.frame; frame.origin.x -= 200;//这里200是图片的宽 也就是让容器View的最右边和底层图片的最左边重合 containerView.frame = frame; [UIView animateWithDuration:4.0f animations:^{ CGRect frame = containerView.frame;//改变位移 frame.origin.x += 400;//从左移动到右边 containerView.frame = frame;//重新赋值 }]; //MARK:3. maskView配合alpha通道图片的使用 // 添加背景图 UIImageView *backgroundView = [[UIImageView alloc]initWithFrame:CGRectMake(width + 40, 200 + 40, 200, 200)]; [backgroundView setImage:[UIImage imageNamed:@"background"]]; [self.view addSubview:backgroundView]; // 待切换图 UIImageView *baseView = [[UIImageView alloc]initWithFrame:backgroundView.frame]; [baseView setImage:[UIImage imageNamed:@"base"]]; [self.view addSubview:baseView]; // 创建maskView作为容器 UIView *maskView = [[UIView alloc]initWithFrame:baseView.bounds]; baseView.maskView = maskView; //maskView的subView1 UIImageView *picOne = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 400)];//100背景宽一半,400背景高两倍 1的上半部是alpha为0 [picOne setImage:[UIImage imageNamed:@"1"]]; [maskView addSubview:picOne]; //maskView的subView2 UIImageView *picTwo = [[UIImageView alloc]initWithFrame:CGRectMake(100, -200, 100, 400)];//2的下半部alpha为0 [picTwo setImage:[UIImage imageNamed:@"2"]]; [maskView addSubview:picTwo]; //做切换图片的动画 [UIView animateWithDuration:2.0f animations:^{ CGRect oneFrame = picOne.frame; oneFrame.origin.y -= 400; picOne.frame = oneFrame; CGRect twoFrame = picTwo.frame; twoFrame.origin.y += 400; picTwo.frame = twoFrame; }]; //MARK:4. 设计文本横向渐变消失的控件 [self.view setBackgroundColor:[UIColor grayColor]]; // 创建FadeString FadeString *fadeString = [[FadeString alloc]initWithFrame:CGRectMake(0, 400+40, 300, 40)]; [fadeString setCenter:CGPointMake(self.view.center.x, fadeString.center.y)]; fadeString.text = @"这个效果看起来还是不错的"; [self.view addSubview:fadeString]; // 执行动画效果 [fadeString fadeRight];
自定义的 FadeString.h
// 输入的文本 @property (nonatomic, strong) NSString *text; // 向右渐变消失的方法 - (void)fadeRight;
FadeString.m
#import "FadeString.h" @interface FadeString () @property (nonatomic, strong) UILabel *label; // 显示文字的label @property (nonatomic, strong) UIView *mask; // 作为遮罩的mask @end @implementation FadeString - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // 创建出label [self createLabel:self.bounds]; // 创建出mask [self createMask:self.bounds]; } return self; } - (void)createLabel:(CGRect)frame { self.label = [[UILabel alloc]initWithFrame:frame]; [_label setFont:[UIFont systemFontOfSize:25.0f]]; [_label setTextAlignment:NSTextAlignmentCenter]; [_label setTextColor:[UIColor whiteColor]]; [self addSubview:_label]; } - (void)createMask:(CGRect)frame { //创建出渐变的layer CAGradientLayer *gradientLayer = [CAGradientLayer layer]; [gradientLayer setFrame:frame]; [gradientLayer setColors:@[(__bridge id)[UIColor clearColor].CGColor, (__bridge id)[UIColor blackColor].CGColor, (__bridge id)[UIColor blackColor].CGColor, (__bridge id)[UIColor clearColor].CGColor]]; [gradientLayer setLocations:@[@(0.01), @(0.1), @(0.9), @(0.99)]]; [gradientLayer setStartPoint:CGPointMake(0, 0)]; [gradientLayer setEndPoint:CGPointMake(1, 0)]; // 创建并接管mask self.mask = [[UIView alloc]initWithFrame:frame]; // mask获取渐变layer [self.mask.layer addSublayer:gradientLayer]; self.maskView = _mask; } - (void)fadeRight { //当前的设计是有缺陷的 最好加上两个参数 一个动画时间 一个是否执行动画 [UIView animateWithDuration:3.f animations:^{ CGRect maskFrame = _mask.frame; maskFrame.origin.x += _mask.frame.size.width; _mask.frame = maskFrame; }]; } //MARK:重写set,get方法 @synthesize text = _text; - (void)setText:(NSString *)text { _text = text; self.label.text = text; } - (NSString *)text { return _text; } /* // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. - (void)drawRect:(CGRect)rect { // Drawing code } */ @end
极客学院的视频地址:http://www.jikexueyuan.com/course/1257.html
其中:
__bridge只做类型转换,但是不修改对象(内存)管理权;
__bridge_retained(也可以使用CFBridgingRetain)将Objective-C的对象转换为Core Foundation的对象,同时将对象(内存)的管理权交给我们,后续需要使用CFRelease或者相关方法来释放对象;
__bridge_transfer(也可以使用CFBridgingRelease)将Core Foundation的对象转换为Objective-C的对象,同时将对象(内存)的管理权交给ARC。
关于这方面的解释 https:developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html
__bridge_retained(也可以使用CFBridgingRetain)将Objective-C的对象转换为Core Foundation的对象,同时将对象(内存)的管理权交给我们,后续需要使用CFRelease或者相关方法来释放对象;
__bridge_transfer(也可以使用CFBridgingRelease)将Core Foundation的对象转换为Objective-C的对象,同时将对象(内存)的管理权交给ARC。
关于这方面的解释 https:developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html