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)