From ccf049f87a5aa8b25010089c89f6f7399a632924 Mon Sep 17 00:00:00 2001 From: Tony DiPasquale Date: Thu, 23 Apr 2015 18:55:40 -0400 Subject: [PATCH] Resize the GIF with aspect ratio We can use the contentMode of the UIImageView to resize the GIF keeping the aspect ratio if the content mode is set to do so. --- Source/Animatable.swift | 3 ++- Source/Animator.swift | 13 +++++++++++-- Source/UIImageExtension.swift | 14 ++++++++------ 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/Source/Animatable.swift b/Source/Animatable.swift index 1df1e13..881fc96 100644 --- a/Source/Animatable.swift +++ b/Source/Animatable.swift @@ -1,6 +1,7 @@ -/// Protocol that requires its members to have a `layer` and a `frame` property. +/// Protocol that requires its members to have a `layer`, `frame`, and `contentMode` property. /// Classes confirming to this protocol can serve as a delegate to `Animator`. protocol Animatable { var layer: CALayer { get } var frame: CGRect { get } + var contentMode: UIViewContentMode { get } } diff --git a/Source/Animator.swift b/Source/Animator.swift index 98a87d0..6cdc0dd 100644 --- a/Source/Animator.swift +++ b/Source/Animator.swift @@ -57,8 +57,17 @@ class Animator: NSObject { let frameDuration = CGImageSourceGIFFrameDuration(imageSource, index) let frameImageRef = CGImageSourceCreateImageAtIndex(imageSource, index, nil) - let frame = UIImage(CGImage: frameImageRef)?.resize(size) - let animatedFrame = AnimatedFrame(image: frame, duration: frameDuration) + + let image = UIImage(CGImage: frameImageRef) + let scaledImage: UIImage? + + switch delegate.contentMode { + case .ScaleAspectFit: scaledImage = image?.resizeAspectFit(size) + case .ScaleAspectFill: scaledImage = image?.resizeAspectFill(size) + default: scaledImage = image?.resize(size) + } + + let animatedFrame = AnimatedFrame(image: scaledImage, duration: frameDuration) return (accumulatedFrames + [animatedFrame], accumulatedDuration + frameDuration) } diff --git a/Source/UIImageExtension.swift b/Source/UIImageExtension.swift index 870833f..e176461 100644 --- a/Source/UIImageExtension.swift +++ b/Source/UIImageExtension.swift @@ -50,14 +50,19 @@ extension UIImage { } private extension CGSize { + /// Calculates the aspect ratio of the size. + /// + /// :returns: aspectRatio The aspect ratio of the size. + var aspectRatio: CGFloat { + if height == 0 { return 1 } + return width / height + } + /// Finds a new size constrained by a size keeping the aspect ratio. /// /// :param: size The contraining size. /// :returns: size A new size that fits inside the contraining size with the same aspect ratio. func sizeConstrainedBySize(size: CGSize) -> CGSize { - if height == 0 { return size } - - let aspectRatio = width / height let aspectWidth = round(aspectRatio * size.height) let aspectHeight = round(size.width / aspectRatio) @@ -73,9 +78,6 @@ private extension CGSize { /// :param: size The contraining size. /// :returns: size A new size that fills the contraining size keeping the same aspect ratio. func sizeFillingSize(size: CGSize) -> CGSize { - if height == 0 { return size } - - let aspectRatio = width / height let aspectWidth = round(aspectRatio * size.height) let aspectHeight = round(size.width / aspectRatio)