简体   繁体   English

用其他颜色动画填充UIImageView

[英]Fill UIImageView with other color animated

I'm having a imageview and I want that imageview to animate with a color. 我有一个imageview,我想让imageview以彩色动画。 So my image is first a green one and then I want to animate it to a orange one. 所以我的图像首先是绿色图像,然后我想将其设置为橙色图像。

This is my code: 这是我的代码:

class TestView: UIView {

    func startAnimate(){

        let size:CGSize = self.bounds.size

        let layer = UIImageView(image: UIImage(named: "LaunchIcon"))
        layer.frame = self.bounds

        let initialRect:CGRect = CGRect.init(x: 0, y: size.height, width: size.width, height: 0)
        let finalRect:CGRect = CGRect.init(x: 0, y: size.height, width: size.width, height: size.height)

        let sublayer = CALayer()
        sublayer.frame = initialRect
        sublayer.backgroundColor = UIColor.orange.cgColor
        sublayer.opacity = 0.5


        let mask:CAShapeLayer = CAShapeLayer()
        mask.frame = self.bounds
        mask.path = UIBezierPath(rect: self.bounds).cgPath
        mask.fillColor = UIColor.black.cgColor

        layer.layer.addSublayer(sublayer)
        layer.layer.mask = mask

        self.layer.addSublayer(layer.layer)

        let boundsAnim:CABasicAnimation  = CABasicAnimation(keyPath: "bounds")
        boundsAnim.toValue = NSValue.init(cgRect:finalRect)

        let animationGroup = CAAnimationGroup()
        animationGroup.animations = [boundsAnim]
        animationGroup.isRemovedOnCompletion = false
        animationGroup.duration = 2
        animationGroup.fillMode = kCAFillModeForwards

        sublayer.add(animationGroup, forKey: nil)
    }
}

My result: 我的结果:

在此输入图像描述

The first problem is that the orange is taking the whole frame and not just my image. 第一个问题是橙色占据了整个画面,而不仅仅是我的画面。 The second problem is that it doesn't fill to the top. 第二个问题是它没有填满顶部。

Some of the issues with your code: 您的代码存在的一些问题:

  1. You add a rectangular mask to a layer, which is not affecting rendering at all. 您将一个矩形mask添加到图层,这根本不会影响渲染。 You never change it's frame, position, shape or anything else, so it's purpose is unclear. 你永远不会改变它的框架,位置,形状或其他任何东西,所以它的目的不明确。

  2. sublayer is supposed to be visible inside your glass shape only, right? sublayer应该只在你的玻璃形状内可见,对吧? But in code you define it as a rectengular and it is a subview, so there is no reason it would be trimmed by the shape of your glass image. 但是在代码中你将它定义为一个rectengular,它是一个子视图,所以没有理由它会被你的玻璃图像的形状修剪。

  3. Please don't call view s as layer , it's confusing for anyone who is reading your code. 请不要将view作为图层调用,对于正在阅读代码的任何人来说都会让人感到困惑。 If it's not a layer, don't call it layer , simple as that. 如果它不是一个图层,请不要将其称为图层 ,这样简单。

let layer = UIImageView(image: UIImage(named: "LaunchIcon")) let layer = UIImageView(image:UIImage(named:“LaunchIcon”))

  1. You don't need CAAnimationGroup if you're wrapping a single CABasicAnimation 如果要包装单个CABasicAnimation则不需要CAAnimationGroup

Working solution: 工作方案:

In fact you don't need to use CoreAnimation here, you can implement this with a higher level plain UIKit . 实际上你不需要在这里使用CoreAnimation,你可以用更高级别的普通UIKit来实现UIKit Your best friends in this case are mask property of UIView and animateWithDuration method: 在这种情况下,你最好的朋友是UIViewanimateWithDuration方法的掩码属性:

class GlassView: UIView {

    let liquidView = UIView() //is going to be animated from bottom to top
    let shapeView = UIImageView() //is going to mask everything with alpha mask

    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }

    func setup() {
        self.backgroundColor = UIColor.darkGray
        self.liquidView.backgroundColor = UIColor.orange

        self.shapeView.contentMode = .scaleAspectFit
        self.shapeView.image = UIImage(named: "glass")

        self.addSubview(liquidView)
        self.mask = shapeView

        layoutIfNeeded()
        reset()
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        liquidView.frame = self.bounds
        shapeView.frame = self.bounds            
    }

    func reset() {
        liquidView.frame.origin.y = bounds.height
    }

    func animate() {
        reset()
        UIView.animate(withDuration: 1) {
            self.liquidView.frame.origin.y = 0
        }
    }
}

Output: 输出:

在此输入图像描述

used mask 用过面具

Implementation details: 实施细节:

The view's alpha channel determines how much of the view's content and background shows through. 视图的alpha通道决定了视图的内容和背景的显示量。 Fully or partially opaque pixels allow the underlying content to show through but fully transparent pixels block that content. 完全或部分不透明的像素允许底层内容显示但完全透明的像素阻止该内容。

Make sure your mask image is .png and contains a shape on a transparent background. 确保您的蒙版图像是.png并包含透明背景上的形状。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM