逐帧动画
逐帧动画的实现就是将图片一帧一帧的渲染,然后在短时间内依次展示出来,即可实现动画效果。
基于NSTimer实现效果:
这种基于定时器刷新的效果,可以用于动画帧率不高,帧率间隔不十分严格的情况下。
import UIKit
class ViewController: UIViewController {
var imageView:UIImageView?
var timer:Timer?
var index:Int = 0
override func viewDidLoad() {
super.viewDidLoad()
imageView = UIImageView()
imageView?.frame = UIScreen.main.bounds
imageView?.contentMode = UIViewContentMode.scaleAspectFit
self.view.addSubview(imageView!)
index = 0
timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(ViewController.refushImage), userInfo:nil, repeats: true)
}
func refushImage(){
NSLog("%d",index)
imageView?.image = UIImage(named: "\(index).png")
index += 1
if(index == 67){
index = 0
}
}
}
基于CADisplayLink:
import UIKit
class ViewController: UIViewController {
var imageView:UIImageView?
var displaylink:CADisplayLink?
var index:Int = 0
override func viewDidLoad() {
super.viewDidLoad()
imageView = UIImageView()
imageView?.frame = UIScreen.main.bounds
imageView?.contentMode = UIViewContentMode.scaleAspectFit
self.view.addSubview(imageView!)
index = 0
displaylink = CADisplayLink.init(target: self, selector: #selector(ViewController.refushImage))
displaylink?.frameInterval = 2
displaylink?.add(to: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
}
func refushImage(){
NSLog("%d",index)
imageView?.image = UIImage(named: "\(index).png")
index += 1
if(index == 67){
// displaylink?.remove(from: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
index = 0
}
}
}
使用draw 方法:
import UIKit
class ViewController: UIViewController {
var blackHole:BlackHoleView?
var timer:Timer?
var index:Float = 0
override func viewDidLoad() {
super.viewDidLoad()
blackHole = BlackHoleView()
blackHole?.frame = UIScreen.main.bounds
blackHole?.backgroundColor = .cyan
self.view.addSubview(blackHole!)
index = 0
timer = Timer.scheduledTimer(timeInterval: 1.0/30, target: self, selector: #selector(ViewController.refushImage), userInfo:nil, repeats: true)
}
func refushImage(){
blackHole?.blackHoleIncrease(index)
index += 1
if index == 30 {
index = 0
}
}
}
BlackHoleView:
import UIKit
class BlackHoleView: UIView {
var blackHoleRadius:Float = 0
func blackHoleIncrease(_ radius: Float){
blackHoleRadius = radius
self.setNeedsDisplay()
}
override func draw(_ rect: CGRect) {//CGFloat(M_PI * 2)
let ctx:CGContext = UIGraphicsGetCurrentContext()!
//clockwise:true为顺时针绘制
ctx.addArc(center: CGPoint(x:self.center.x,y:self.center.y), radius: CGFloat(blackHoleRadius), startAngle: 0, endAngle:CGFloat(Float.pi * 2) , clockwise: false)
ctx.fillPath()
}
}
gif动画效果
gif拆分成多个单帧图片:
过程是:gif----->Data------>imageIO------>UIImage----->jpg|png
import UIKit
import ImageIO
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let gifPath = Bundle.main.path(forResource: "1", ofType: "gif")
let gifData = try! Data(contentsOf: URL(fileURLWithPath: gifPath!))
let gifDataSource = CGImageSourceCreateWithData(gifData as CFData, nil)
let gifImageCount = CGImageSourceGetCount(gifDataSource!)
for i in 0..
多张图片合成gif
import UIKit
import ImageIO
import MobileCoreServices
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var imageArray = [UIImage]()
for i in 0...66 {
imageArray.append(UIImage(named: "\(i).png")!)
}
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
let gifPath = documentDirectory! + "/plane.gif"
print(gifPath)
// string ---> CFURL
let url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, gifPath as CFString, .cfurlposixPathStyle, false)
let destion = CGImageDestinationCreateWithURL(url!, kUTTypeGIF, imageArray.count, nil)
//设置每帧之间的播放时间
let cgimagePropertiesDict = [kCGImagePropertyGIFDelayTime as String : 0.1]
let cgimagePropertiesDesDict = [kCGImagePropertyGIFDictionary as String : cgimagePropertiesDict]
for cgimage in imageArray {
//依次为gif图像对象添加每一帧元素
CGImageDestinationAddImage(destion!, (cgimage as AnyObject).cgImage!!,cgimagePropertiesDesDict as CFDictionary?)
}
//设置图像的彩色空间格式;颜色深度;执行次数
let gifProperties = [kCGImagePropertyColorModelRGB : kCGImagePropertyColorModel,
kCGImagePropertyDepth : 16,
kCGImagePropertyGIFLoopCount : 1] as [CFString : Any]
let gifDictionaryDestDic = [kCGImagePropertyGIFDictionary : gifProperties]
CGImageDestinationSetProperties(destion!,gifDictionaryDestDic as CFDictionary)
CGImageDestinationFinalize(destion!)
}
}
展示gif图片
由于iOS原生并不直接支持gif图片的展示,所以可以考虑将gif拆分成若干个单帧图片,然后用UIImageView来展示:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var images:[UIImage] = []
for i in 0...66{// 遍历本地67张图片
let imagePath = "\(i).png" // 构建图片名称
let image:UIImage = UIImage(named: imagePath)!//构建UIImage
images.append(image)// 将图片添加到数组中
}
let imageView = UIImageView()
imageView.frame = self.view.bounds
imageView.contentMode = UIViewContentMode.center
self.view.addSubview(imageView)
imageView.animationImages = images
imageView.animationDuration = 5
imageView.animationRepeatCount = 1
imageView.startAnimating()
}
}