Skip to content

Instantly share code, notes, and snippets.

@svyatoslav-zubrin
Last active January 21, 2019 14:18
Show Gist options
  • Save svyatoslav-zubrin/eb0ea26cdf1bcfc8ce27c83321bf2dbf to your computer and use it in GitHub Desktop.
Save svyatoslav-zubrin/eb0ea26cdf1bcfc8ce27c83321bf2dbf to your computer and use it in GitHub Desktop.
Record gif from animated view
import ImageIO
import MobileCoreServices
class MyAnimatedViewTToBeRecordedAsGif: UIView {
private var timer: Timer!
private var isRecording = false
private var images = [UIImage]()
private var timeInterval: TimeInterval = 0.05 // 20 frames per sec
func startRecordingGif() {
guard !isRecording else { return }
timer = Timer(timeInterval: timeInterval, target: self, selector: #selector(recordFrame), userInfo: nil, repeats: true)
RunLoop.current.add(timer, forMode: .defaultRunLoopMode)
isRecording = true
setupRecordingGif()
timer.fire()
}
private func stopRecordingGif() {
guard isRecording else { return }
isRecording = false
timer.invalidate()
finalizeRecordigGif()
}
@objc func recordFrame() {
guard images.count <= Int(21 / timeInterval) else { // 21 sec - duration of the animation
stopRecordingGif()
return
}
images.append(capture())
}
// capturing 'self'
private func capture() -> UIImage {
UIGraphicsBeginImageContextWithOptions(bounds.size, isOpaque, 0)
defer { UIGraphicsEndImageContext() }
drawHierarchy(in: bounds, afterScreenUpdates: true)
return UIGraphicsGetImageFromCurrentImageContext() ?? UIImage()
}
private func setupRecordingGif() {
images = []
}
private func finalizeRecordigGif() {
let fileProperties: CFDictionary = [kCGImagePropertyGIFDictionary as String: [kCGImagePropertyGIFLoopCount as String: 0]] as CFDictionary
let frameProperties: CFDictionary = [kCGImagePropertyGIFDictionary as String: [(kCGImagePropertyGIFDelayTime as String): timeInterval]] as CFDictionary
let documentsDirectoryURL: URL? = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
let fileURL: URL? = documentsDirectoryURL?.appendingPathComponent("animated.gif")
if let url = fileURL as CFURL? {
if let destination = CGImageDestinationCreateWithURL(url, kUTTypeGIF, images.count, nil) {
CGImageDestinationSetProperties(destination, fileProperties)
for image in images {
if let cgImage = image.cgImage {
CGImageDestinationAddImage(destination, cgImage, frameProperties)
}
}
if !CGImageDestinationFinalize(destination) {
print("Failed to finalize the image destination")
}
print("Url = \(fileURL)")
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment