iOS 点击屏幕出现icon小动画

2020-12-28  本文已影响0人  姜小舟

前几天圣诞节打开爱奇艺看个了电影,发现一个还不错的点击效果,就是播放视频页面单击屏幕会在点击处出现一个圣诞老人的小icon动画(短时间第二次点击前一次的消失并在新点击处出现)。觉得挺好的就自己动手写了一个。

一共涉及两个点:

  • 动图播放
  • 单击处显示

先看效果吧:


效果图

废话不说直接上代码了.

动图播放

动图播放我是swift按照播放gif图片写的一个UIImageView的扩展

import UIKit
import ImageIO

extension UIImageView {
    //MARK:工程内gif(外部调用方法)
    public func gif(name:String){
        guard let path = Bundle.main.path(forResource: name, ofType: "gif") else {
            print("SwiftGif: Source for the image does not exist")
            return
        }
        self.kyl_startGifWithFilePath(filePath: path)
    }
    //MARK:实现动图效果
    func kyl_startGifWithFilePath(filePath:String) {
        //1.加载GIF图片,并转化为data类型
        guard let data = NSData(contentsOfFile: filePath) else {return}
        //2.从data中读取数据,转换为CGImageSource
        guard let imageSource = CGImageSourceCreateWithData(data, nil) else {return}
        let imageCount = CGImageSourceGetCount(imageSource)
        //3.遍历所有图片
        var images = [UIImage]()
        var totalDuration : TimeInterval = 0
        for i in 0..<imageCount {
            //3.1取出图片
            guard let cgImage = CGImageSourceCreateImageAtIndex(imageSource, i, nil) else {continue}
            let image = UIImage(cgImage: cgImage)
            images.append(image)
            if 0 == I {
                self.image = image
            }
            //3.2取出持续时间
            guard let properties = CGImageSourceCopyPropertiesAtIndex(imageSource, i, nil) as? NSDictionary  else {continue}
            guard let gifDict = properties[kCGImagePropertyGIFDictionary]  as? NSDictionary else  {continue}
            guard let frameDuration = gifDict[kCGImagePropertyGIFDelayTime] as? NSNumber else {continue}
            totalDuration += frameDuration.doubleValue
            
        }
        
        //4.设置imageview的属性
        self.animationImages = images
        self.animationDuration = totalDuration
        self.animationRepeatCount = 0
        
        
        
    }
    
    public func gifStartAnimating() {
        //5.开始播放
        self.startAnimating()
    }
    
    public func gifStopAnimating() {
        self.stopAnimating()
    }
}

单击处显示

这一步主要点在于如何获取点击位置,可以在UIApplication子类重写func sendEvent(_ event: UIEvent),App全局出现获取,或者在个别UIViewController中重写此方法仅在个别UIViewController获取显示。

class SubApplication: UIApplication {

    //点击屏幕跳出gif小icon,可用于遇到节日时点击屏幕出现相应动画特效
    override func sendEvent(_ event: UIEvent) {
        TouchAppearIconManager.shared.sendEvent(event)
        super.sendEvent(event)
    }
}

具体小工具类显示代码如下

import UIKit

//点击屏幕跳出gif小icon,可用于遇到节日时点击屏幕出现相应动画特效
/*
 在UIApplication子类重写 func sendEvent(_ event: UIEvent)全局出现
 或者在个别要求页面重写 func sendEvent(_ event: UIEvent)
 如:
 override func sendEvent(_ event: UIEvent) {
     TouchAppearIconManager.shared.sendEvent(event)
     super.sendEvent(event)
 }
 */
class TouchAppearIconManager: NSObject {
    public static let shared: TouchAppearIconManager = TouchAppearIconManager()
    public var isAnimate = false
    var isMoved = false
    
    //MARK:外部调用
    public func sendEvent(_ event: UIEvent) {
        if event.type == .touches {
            if let touch = event.allTouches?.first {
                if touch.phase == .began {
                    self.isMoved = false
                }

                if touch.phase == .moved {
                    self.isMoved = true
                }

                if touch.phase == .ended && touch.tapCount == 1 && !self.isMoved && event.allTouches?.count == 1 {
                    let location = touch.location(in: UIApplication.shared.windows[0])
                    showIcon(location)
                }
            }
        }
    }
    
    //真正展示icon
    private func showIcon(_ center: CGPoint?) {
        if let c = center {
            if c.y < NAVBAR_HEIGHT {
                return
            }
            if let _ = self.iconImageView.superview {
                self.iconImageView.removeFromSuperview()
            }
            isAnimate = true
            iconImageView.alpha = 0.0
            iconImageView.stopAnimating()
            UIApplication.shared.windows[0].addSubview(iconImageView)
            UIApplication.shared.windows[0].bringSubviewToFront(iconImageView)
            iconImageView.center = c
            
            UIView.animate(withDuration: 0.25, animations: {
                self.iconImageView.alpha = 1.0
                self.iconImageView.gifStartAnimating()
            }, completion: {[weak self] (bool) in
                guard let `self` = self else { return }
                UIView.animate(withDuration: 0.25, delay: self.iconImageView.animationDuration, options: .curveEaseIn, animations: {
                     self.iconImageView.alpha = 0.0
                     self.isAnimate = false
                 }, completion:  {[weak self] (bool) in
                     guard let `self` = self else { return }
                     if !self.isAnimate {
                         self.iconImageView.stopAnimating()
                     }
                })
            })
        }
    }

    private lazy var iconImageView: UIImageView = {
        let iv = UIImageView.init(frame: CGRect.init(x: 0, y: 0, width: 40, height: 40))
        iv.contentMode = .scaleAspectFit
        iv.gif(name: "new_year")
        return iv
    }()
}
上一篇 下一篇

猜你喜欢

热点阅读