美文网首页
浅谈swift动画(二)

浅谈swift动画(二)

作者: 元宝是只小肥猫 | 来源:发表于2018-11-10 15:42 被阅读10次

    逐帧动画

    逐帧动画的实现就是将图片一帧一帧的渲染,然后在短时间内依次展示出来,即可实现动画效果。

    基于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 方法:

    Simulator Screen Shot - iPhone 8 Plus - 2018-11-10 at 11.48.49.png
    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..<gifImageCount {
                let imageref = CGImageSourceCreateImageAtIndex(gifDataSource!, i, nil)
                let image = UIImage(cgImage: imageref!, scale: UIScreen.main.scale, orientation: .up)
                let imageData = UIImagePNGRepresentation(image)
                let docs = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
                let imagePath = docs! + "/\(i).png"
                try? imageData?.write(to: URL(fileURLWithPath: imagePath))
                print("\(imagePath)")
            }
        }
    }
    

    多张图片合成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()
        }
    
    }
    

    相关文章

      网友评论

          本文标题:浅谈swift动画(二)

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