美文网首页
两个动画来理解maskView

两个动画来理解maskView

作者: 乌黑的太阳 | 来源:发表于2016-06-07 15:37 被阅读180次

属性说明

maskView是UIView的一个属性,对应的CALayer也有一个mask,他们两个的作用是一样的,同样的一个东西。这个属性类似一个遮罩,设置maskView后,原本的view只能看到maskView不透明的部分。这个属性用来做动画可以实现一些很好玩的东西。

下面介绍两个动画一个swift版,一个oc版

oc版

很简单,主要是利用设置maskView后,原本的view只能看到maskView不透明的部分。


maskView.gif
#import "HZSGradientProgressView.h"

@interface HZSGradientProgressView ()

@property (nonatomic, strong) UIView *mask;

@end

@implementation HZSGradientProgressView

+ (Class)layerClass {
    return [CAGradientLayer class];
}

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self commonInit];
    }
    return self;
}

- (instancetype)init {
    return [self initWithFrame:CGRectZero];
}

- (void)commonInit {
    CAGradientLayer *gradientLayer = (CAGradientLayer *)self.layer;
    NSArray *colors = [NSArray arrayWithObjects:(__bridge id)[UIColor redColor].CGColor,
                                                    (__bridge id)[UIColor orangeColor].CGColor,
                                                    (__bridge id)[UIColor yellowColor].CGColor,
                                                    (__bridge id)[UIColor greenColor].CGColor,
                                                    (__bridge id)[UIColor blueColor].CGColor,
                                                    (__bridge id)[UIColor purpleColor].CGColor,
                                                    nil];
    gradientLayer.startPoint = CGPointMake(0.0, 0.5);
    gradientLayer.endPoint = CGPointMake(1.0, 0.5);
    gradientLayer.colors = colors;
    
    _mask = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, self.bounds.size.height)];
    _mask.backgroundColor = [UIColor blackColor];
    self.maskView = _mask;
    
    _value = 0.0;
}

- (void)setValue:(CGFloat)value {
    if (value == _value) return;
    
    value = MAX(value, 0);
    value = MIN(value, 1);
    _value = value;
    _mask.frame = CGRectMake(0, 0, self.bounds.size.width * _value, self.bounds.size.height);
    [self colorsAnimation];
}

- (void)colorsAnimation {
    CAGradientLayer *gradientLayer = (CAGradientLayer *)self.layer;
    NSArray *colors = gradientLayer.colors;
    if (colors == nil) return;
    
    NSMutableArray *temp = [colors mutableCopy];
    id last = colors.lastObject;
    [temp removeLastObject];
    [temp insertObject:last atIndex:0];
    
    gradientLayer.colors = temp;
}
swift版

这个实现也很方便,主要是利用了视差,有两个imageView都添加在同一个view上面,最上面的那个imageView设置maskView,如果maskView的透明度是0,则看不到最上面的imageView了,只能看到底下的view;如果maskView不透明了,则就能看到最上层的imageview了。这样就造成了切换效果。这么细碎地切换是因为maskView赋值的那个view有n个小碎片似的的子视图,遍历控制每个子视图的alpha就有这个效果了。


maskView2.gif

用的分类实现

import Foundation

private var isFadingKey = "isFadingKey"
private var durationKey = "durationKey"

extension UIView {
    private(set) var isFading: Bool {
        get {
            guard let result = objc_getAssociatedObject(self, &isFadingKey) else { return false }
            
            return (result as! NSNumber).boolValue
        }
        set {
            objc_setAssociatedObject(self, &isFadingKey, NSNumber(bool: newValue), .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    var maskAnimationDuration: NSTimeInterval {
        get {
            guard let result = objc_getAssociatedObject(self, &durationKey) else { return 0.1 }
            
            return (result as! NSNumber).doubleValue
        }
        set {
            objc_setAssociatedObject(self, &durationKey, NSNumber(double: newValue), .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
   
    func fadeAnimation(reverse: Bool, complete: (() -> Void)?) {
        if isFading { return }
        
        isFading = true
        
        configureMaskView()
        
        var subs: [UIView]
        if reverse {
            subs = self.maskView!.subviews.reverse()
        } else {
            subs = self.maskView!.subviews
        }
        
        let currentAlpha = subs[0].alpha
        
        for (index, sub) in subs.enumerate() {
            UIView.animateWithDuration(maskAnimationDuration, delay: Double(index)*maskAnimationDuration, options: [.CurveEaseOut], animations: {
                sub.alpha = (currentAlpha == 0 ? 1 : 0)
                }, completion: { (finish) in
                    if index == 14 {
                        if let closure = complete {
                            closure()
                        }
                        self.isFading = false
                    }
            })
        }
        
    }
    
    
    
    private func configureMaskView() {
        guard self.maskView == nil else { return }
        
        let mask = UIView(frame: self.bounds)
        let itemWidth = self.width/15
        for index in 0...14 {
            let sub = UIView(frame: CGRect(x: CGFloat(index)*itemWidth, y: 0, width: itemWidth, height: self.height))
            sub.backgroundColor = UIColor.blackColor()
            mask.addSubview(sub)
        }
        self.maskView = mask
    }
}

相关文章

  • 两个动画来理解maskView

    属性说明 maskView是UIView的一个属性,对应的CALayer也有一个mask,他们两个的作用是一样的,...

  • 使用 maskView 设计动画

    技术点: maskView(maskLayer)基本原理 maskView配合CAGradientLayer的使用...

  • iOS开发随手记-持续更新

    目录 maskView动画原理 :遮罩 button倒计时闪烁解决 改变从xib拖出来约束,没有动画效果解决办法:...

  • 绘制圆角

    通过MaskView 来实现圆角功能 image 扩展

  • iOS浅谈UIView的maskView属性

    使用maskView来实现下面的效果: 效果图首先我们要知道,maskView的定义,这是一个视图的遮罩视图,要实...

  • maskView使用进阶(配合CAGradientLayer,C

    上一篇文章介绍了maskView的原理和基本使用接下来介绍下maskView的进阶使用 一.利用maskView使...

  • MaskView

    UIView在iOS 8.0之后新增的属性maskView的alpha=1时显示view的部分,alpha=0时不...

  • iOS的Core Animation的一点总结记录

    前言 iOS核心动画框架Core Animation,可以从“动画”的两个字上进行理解。何为“动画”?首先,它是一...

  • UIView

    1. maskView 直接改变view的透明度可以通过以下语句来实现self.view.alpha = 0.5 ...

  • maskView初识

    在很多地方看到maskView,一直不明白是什么东西,效果可以做的那么好.如下图:图片来源:http://m.jb...

网友评论

      本文标题:两个动画来理解maskView

      本文链接:https://www.haomeiwen.com/subject/sbiddttx.html