注册 登录
主题 : 遮罩动画
级别: 圣骑士

状态: 连续签到 - [137天]
UID: 83792
精华: 0
发帖: 415
可可豆: 2307 CB
威望: 1893 点
在线时间: 1253(时)
注册时间: 2011-07-27
最后登录: 2019-03-15
0 楼:  发表于: 2019-01-11 15:55    发自: Web Page
来源于 显示问题 分类

遮罩动画   

复制代码
  1. //
  2. // MaskedAnimateView.m
  3. // ix-dev-kit
  4. //
  5. // Created by iXcoder(ixcoder@qq.com) on 2019/1/11.
  6. // Copyright ? 2019年 iXcoder(ixcoder.com). All rights reserved.
  7. //
  8. #import "MaskedAnimateView.h"
  9. #import <CoreGraphics/CoreGraphics.h>
  10. @interface MaskedAnimateView ()
  11. @property (nonatomic, weak) CAShapeLayer *mask;
  12. @property (nonatomic, strong) NSArray<NSNumber *> *starts, *ends;
  13. @property (nonatomic) NSTimeInterval duration;
  14. @property (nonatomic, strong) CAAnimationGroup *expand, *close;
  15. @end
  16. @implementation MaskedAnimateView
  17. - (instancetype)initWithFrame:(CGRect)frame
  18. {
  19. if (self = [super initWithFrame:frame]) {
  20. self.alpha = 0;
  21. }
  22. return self;
  23. }
  24. - (void)beginCoverAnimWith:(NSTimeInterval)duration
  25. begining:(NSArray<NSNumber *> *)starts
  26. ending:(NSArray<NSNumber *> *)ends
  27. {
  28. CGFloat start = starts[0].doubleValue / 360 + 0.5;
  29. CGFloat end = starts[1].doubleValue / 360 + 0.5;
  30. self.mask.strokeStart = start;
  31. self.mask.strokeEnd = end;
  32. self.alpha = 1.0;
  33. self.starts = starts;
  34. self.ends = ends;
  35. self.duration = duration;
  36. [self.mask addAnimation:self.expand forKey:@"expand"];
  37. }
  38. - (void)dismissWith:(void(^)(void))completion
  39. {
  40. [self.mask addAnimation:self.close forKey:@"close"];
  41. }
  42. - (void)beginCoverAnimWith:(NSTimeInterval)duration from:(CoveredPosition)position
  43. {
  44. NSArray<NSNumber *> *starts = nil, *ends = nil;
  45. switch (position) {
  46. case CoveredPositionLeft:
  47. {
  48. starts = @[@-180, @-180];
  49. ends = @[@-180, @0];
  50. break;
  51. }
  52. case CoveredPositionCenter:
  53. {
  54. starts = @[@-90, @-90];
  55. ends = @[@-180, @0];
  56. break;
  57. }
  58. case CoveredPositionRight:
  59. {
  60. starts = @[@0, @0];
  61. ends = @[@-180, @0];
  62. break;
  63. }
  64. }
  65. [self beginCoverAnimWith:duration begining:starts ending:ends];
  66. }
  67. #pragma mark - getter & setter methods
  68. - (CAShapeLayer *)mask
  69. {
  70. if (!_mask) {
  71. CAShapeLayer *shape = [CAShapeLayer layer];
  72. shape.frame = self.bounds;
  73. CGFloat maxSide = MAX(self.bounds.size.width, self.bounds.size.height);
  74. CGPoint center = CGPointMake(CGRectGetWidth(self.bounds) / 2.0
  75. , CGRectGetHeight(self.bounds) / 2.0);
  76. UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:maxSide / 2.0 startAngle:-M_PI endAngle:M_PI clockwise:YES];
  77. shape.lineWidth = maxSide;
  78. shape.path = path.CGPath;
  79. shape.fillColor = UIColor.clearColor.CGColor;
  80. shape.strokeColor = UIColor.whiteColor.CGColor;
  81. shape.strokeStart = 0;
  82. shape.strokeEnd = 0;
  83. self.layer.mask = shape;
  84. _mask = shape;
  85. }
  86. return _mask;
  87. }
  88. - (CAAnimationGroup *)expand
  89. {
  90. if (!_expand) {
  91. CABasicAnimation *backward = [CABasicAnimation animationWithKeyPath:@"strokeStart"];
  92. backward.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
  93. backward.duration = self.duration;
  94. backward.toValue = @(self.ends[0].doubleValue / 360 + 0.5);
  95. CABasicAnimation *forward = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
  96. forward.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
  97. forward.duration = self.duration;
  98. forward.toValue = @(self.ends[1].doubleValue / 360 + 0.5);
  99. _expand = [CAAnimationGroup animation];
  100. _expand.animations = @[backward, forward];
  101. _expand.duration = self.duration;
  102. _expand.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
  103. _expand.removedOnCompletion = NO;
  104. _expand.fillMode = kCAFillModeBoth;
  105. }
  106. return _expand;
  107. }
  108. - (CAAnimationGroup *)close
  109. {
  110. if (!_close) {
  111. CABasicAnimation *backward = [CABasicAnimation animationWithKeyPath:@"strokeStart"];
  112. backward.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
  113. backward.duration = self.duration;
  114. backward.toValue = @(self.starts[0].doubleValue / 360 + 0.5);
  115. CABasicAnimation *forward = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
  116. forward.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
  117. forward.duration = self.duration;
  118. forward.toValue = @(self.starts[1].doubleValue / 360 + 0.5);
  119. _close = [CAAnimationGroup animation];
  120. _close.animations = @[backward, forward];
  121. _close.duration = self.duration;
  122. _close.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
  123. _close.removedOnCompletion = NO;
  124. _close.fillMode = kCAFillModeBoth;
  125. }
  126. return _close;
  127. }
  128. @end



Usage:
复制代码
  1. self.coverView1 = [[MaskedAnimateView alloc] initWithFrame:CGRectMake(20, 100, 300, 300)];
  2. self.coverView1.layer.cornerRadius = 150;
  3. self.coverView1.clipsToBounds = YES;
  4. self.coverView1.backgroundColor = [UIColor redColor];
  5. [self.view addSubview:self.coverView1];
  6. [self.coverView1 beginCoverAnimWith:2.0 from:CoveredPositionLeft];
  7. [self.coverView1 dismissWith:^{
  8. }];


有勇气踏出一步,就要要有勇气接受踏出所带来的一切
级别: 新手上路
UID: 578913
精华: 0
发帖: 52
可可豆: 177 CB
威望: 187 点
在线时间: 373(时)
注册时间: 2016-08-21
最后登录: 2019-01-18
1 楼:  发表于: 2019-01-11 16:46    发自: Web Page
太长了,发个博客啊

CocoaChina社区转载内容已尽可能注明出处,如未能核实来源或转发内容图片有权利瑕疵的,请及时联系社区进行修改或删除【联系方式QQ : 3442093904 邮箱:support@cocoachina.com】文章内容为作者独立观点,不代表CocoaChina社区立场。版权归原作者所有,如申请授权请联系作者,因文章侵权CocoaChina社区不承担任何法律及连带责任。

描述
快速回复

关注本帖(如果有新回复会站内信通知您)

发帖、回帖都会得到可观的积分奖励。查看论坛积分规则

按"Ctrl+Enter"直接提交
    顶部