前几天圣诞节打开爱奇艺看个了电影,发现一个还不错的点击效果,就是播放视频页面单击屏幕会在点击处出现一个圣诞老人的小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
}()
}
网友评论