Improve configurability of the animator
This commit is contained in:
parent
5b7de2ed2d
commit
e029225c05
|
@ -8,7 +8,7 @@ public class Animator {
|
||||||
var shouldResizeFrames = false
|
var shouldResizeFrames = false
|
||||||
|
|
||||||
/// Responsible for loading individual frames and resizing them if necessary.
|
/// Responsible for loading individual frames and resizing them if necessary.
|
||||||
var frameStore: FrameStore?
|
private var frameStore: FrameStore?
|
||||||
|
|
||||||
/// Tracks whether the display link is initialized.
|
/// Tracks whether the display link is initialized.
|
||||||
private var displayLinkInitialized: Bool = false
|
private var displayLinkInitialized: Bool = false
|
||||||
|
|
|
@ -76,7 +76,6 @@ extension GIFAnimatable {
|
||||||
animator?.prepareForAnimation(withGIFData: imageData, size: frame.size, contentMode: contentMode)
|
animator?.prepareForAnimation(withGIFData: imageData, size: frame.size, contentMode: contentMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Stop animating and free up GIF data from memory.
|
/// Stop animating and free up GIF data from memory.
|
||||||
public func prepareForReuse() {
|
public func prepareForReuse() {
|
||||||
animator?.prepareForReuse()
|
animator?.prepareForReuse()
|
||||||
|
@ -92,6 +91,20 @@ extension GIFAnimatable {
|
||||||
animator?.stopAnimating()
|
animator?.stopAnimating()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether the frame images should be resized or not. The default is `false`, which means that the frame images retain their original size.
|
||||||
|
///
|
||||||
|
/// - parameter resize: Boolean value indicating whether individual frames should be resized.
|
||||||
|
public func setShouldResizeFrames(_ resize: Bool) {
|
||||||
|
animator?.shouldResizeFrames = resize
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the number of frames that should be buffered. Default is 50. A high number will result in more memory usage and less CPU load, and vice versa.
|
||||||
|
///
|
||||||
|
/// - parameter frames: The number of frames to buffer.
|
||||||
|
public func setFrameBufferCount(_ frames: Int) {
|
||||||
|
animator?.frameBufferCount = frames
|
||||||
|
}
|
||||||
|
|
||||||
/// Updates the image with a new frame if necessary.
|
/// Updates the image with a new frame if necessary.
|
||||||
public func updateImageIfNeeded() {
|
public func updateImageIfNeeded() {
|
||||||
if var imageContainer = self as? ImageContainer {
|
if var imageContainer = self as? ImageContainer {
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>132</string>
|
<string>119</string>
|
||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
<string></string>
|
<string></string>
|
||||||
</dict>
|
</dict>
|
||||||
|
|
|
@ -595,6 +595,106 @@
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="item">
|
||||||
|
<div>
|
||||||
|
<code>
|
||||||
|
<a name="/s:FE4GifuPS_13GIFAnimatable21setShouldResizeFramesFSbT_"></a>
|
||||||
|
<a name="//apple_ref/swift/Method/setShouldResizeFrames(_:)" class="dashAnchor"></a>
|
||||||
|
<a class="token" href="#/s:FE4GifuPS_13GIFAnimatable21setShouldResizeFramesFSbT_">setShouldResizeFrames(_:)</a>
|
||||||
|
</code>
|
||||||
|
<span class="declaration-note">
|
||||||
|
Extension method
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="height-container">
|
||||||
|
<div class="pointer-container"></div>
|
||||||
|
<section class="section">
|
||||||
|
<div class="pointer"></div>
|
||||||
|
<div class="abstract">
|
||||||
|
<p>Whether the frame images should be resized or not. The default is <code>false</code>, which means that the frame images retain their original size.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="declaration">
|
||||||
|
<h4>Declaration</h4>
|
||||||
|
<div class="language">
|
||||||
|
<p class="aside-title">Swift</p>
|
||||||
|
<pre class="highlight"><code><span class="kd">public</span> <span class="kd">func</span> <span class="nf">setShouldResizeFrames</span><span class="p">(</span><span class="n">_</span> <span class="nv">resize</span><span class="p">:</span> <span class="kt">Bool</span><span class="p">)</span></code></pre>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4>Parameters</h4>
|
||||||
|
<table class="graybox">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>
|
||||||
|
<em>resize</em>
|
||||||
|
</code>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>
|
||||||
|
<p>Boolean value indicating whether individual frames should be resized.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="item">
|
||||||
|
<div>
|
||||||
|
<code>
|
||||||
|
<a name="/s:FE4GifuPS_13GIFAnimatable19setFrameBufferCountFSiT_"></a>
|
||||||
|
<a name="//apple_ref/swift/Method/setFrameBufferCount(_:)" class="dashAnchor"></a>
|
||||||
|
<a class="token" href="#/s:FE4GifuPS_13GIFAnimatable19setFrameBufferCountFSiT_">setFrameBufferCount(_:)</a>
|
||||||
|
</code>
|
||||||
|
<span class="declaration-note">
|
||||||
|
Extension method
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="height-container">
|
||||||
|
<div class="pointer-container"></div>
|
||||||
|
<section class="section">
|
||||||
|
<div class="pointer"></div>
|
||||||
|
<div class="abstract">
|
||||||
|
<p>Sets the number of frames that should be buffered. Default is 50. A high number will result in more memory usage and less CPU load, and vice versa.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="declaration">
|
||||||
|
<h4>Declaration</h4>
|
||||||
|
<div class="language">
|
||||||
|
<p class="aside-title">Swift</p>
|
||||||
|
<pre class="highlight"><code><span class="kd">public</span> <span class="kd">func</span> <span class="nf">setFrameBufferCount</span><span class="p">(</span><span class="n">_</span> <span class="nv">frames</span><span class="p">:</span> <span class="kt">Int</span><span class="p">)</span></code></pre>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4>Parameters</h4>
|
||||||
|
<table class="graybox">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>
|
||||||
|
<em>frames</em>
|
||||||
|
</code>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>
|
||||||
|
<p>The number of frames to buffer.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
<li class="item">
|
<li class="item">
|
||||||
<div>
|
<div>
|
||||||
<code>
|
<code>
|
||||||
|
|
|
@ -595,6 +595,106 @@
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="item">
|
||||||
|
<div>
|
||||||
|
<code>
|
||||||
|
<a name="/s:FE4GifuPS_13GIFAnimatable21setShouldResizeFramesFSbT_"></a>
|
||||||
|
<a name="//apple_ref/swift/Method/setShouldResizeFrames(_:)" class="dashAnchor"></a>
|
||||||
|
<a class="token" href="#/s:FE4GifuPS_13GIFAnimatable21setShouldResizeFramesFSbT_">setShouldResizeFrames(_:)</a>
|
||||||
|
</code>
|
||||||
|
<span class="declaration-note">
|
||||||
|
Extension method
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="height-container">
|
||||||
|
<div class="pointer-container"></div>
|
||||||
|
<section class="section">
|
||||||
|
<div class="pointer"></div>
|
||||||
|
<div class="abstract">
|
||||||
|
<p>Whether the frame images should be resized or not. The default is <code>false</code>, which means that the frame images retain their original size.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="declaration">
|
||||||
|
<h4>Declaration</h4>
|
||||||
|
<div class="language">
|
||||||
|
<p class="aside-title">Swift</p>
|
||||||
|
<pre class="highlight"><code><span class="kd">public</span> <span class="kd">func</span> <span class="nf">setShouldResizeFrames</span><span class="p">(</span><span class="n">_</span> <span class="nv">resize</span><span class="p">:</span> <span class="kt">Bool</span><span class="p">)</span></code></pre>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4>Parameters</h4>
|
||||||
|
<table class="graybox">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>
|
||||||
|
<em>resize</em>
|
||||||
|
</code>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>
|
||||||
|
<p>Boolean value indicating whether individual frames should be resized.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="item">
|
||||||
|
<div>
|
||||||
|
<code>
|
||||||
|
<a name="/s:FE4GifuPS_13GIFAnimatable19setFrameBufferCountFSiT_"></a>
|
||||||
|
<a name="//apple_ref/swift/Method/setFrameBufferCount(_:)" class="dashAnchor"></a>
|
||||||
|
<a class="token" href="#/s:FE4GifuPS_13GIFAnimatable19setFrameBufferCountFSiT_">setFrameBufferCount(_:)</a>
|
||||||
|
</code>
|
||||||
|
<span class="declaration-note">
|
||||||
|
Extension method
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="height-container">
|
||||||
|
<div class="pointer-container"></div>
|
||||||
|
<section class="section">
|
||||||
|
<div class="pointer"></div>
|
||||||
|
<div class="abstract">
|
||||||
|
<p>Sets the number of frames that should be buffered. Default is 50. A high number will result in more memory usage and less CPU load, and vice versa.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="declaration">
|
||||||
|
<h4>Declaration</h4>
|
||||||
|
<div class="language">
|
||||||
|
<p class="aside-title">Swift</p>
|
||||||
|
<pre class="highlight"><code><span class="kd">public</span> <span class="kd">func</span> <span class="nf">setFrameBufferCount</span><span class="p">(</span><span class="n">_</span> <span class="nv">frames</span><span class="p">:</span> <span class="kt">Int</span><span class="p">)</span></code></pre>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4>Parameters</h4>
|
||||||
|
<table class="graybox">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>
|
||||||
|
<em>frames</em>
|
||||||
|
</code>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>
|
||||||
|
<p>The number of frames to buffer.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
<li class="item">
|
<li class="item">
|
||||||
<div>
|
<div>
|
||||||
<code>
|
<code>
|
||||||
|
|
|
@ -63,6 +63,8 @@
|
||||||
<p>Gifu adds protocol-based, performance-aware animated GIF support to UIKit. (It’s also a <a href="https://goo.gl/maps/CCeAc">prefecture in Japan</a>).</p>
|
<p>Gifu adds protocol-based, performance-aware animated GIF support to UIKit. (It’s also a <a href="https://goo.gl/maps/CCeAc">prefecture in Japan</a>).</p>
|
||||||
|
|
||||||
<p>⚠ <strong>Swift 2.3</strong> support is on the <a href="https://github.com/kaishin/Gifu/tree/swift2.3">swift2.3</a> branch. <strong>This branch will not be getting any future updates</strong>.</p>
|
<p>⚠ <strong>Swift 2.3</strong> support is on the <a href="https://github.com/kaishin/Gifu/tree/swift2.3">swift2.3</a> branch. <strong>This branch will not be getting any future updates</strong>.</p>
|
||||||
|
|
||||||
|
<p>⚠ What follows applies to the yet unreleased <code>2.0</code> on <code>master</code>.</p>
|
||||||
<a href='#install' class='anchor' aria-hidden=true><span class="header-anchor"></span></a><h2 id='install'>Install</h2>
|
<a href='#install' class='anchor' aria-hidden=true><span class="header-anchor"></span></a><h2 id='install'>Install</h2>
|
||||||
<a href='#a-href-https-github-com-carthage-carthage-carthage-a' class='anchor' aria-hidden=true><span class="header-anchor"></span></a><h3 id='a-href-https-github-com-carthage-carthage-carthage-a'><a href="https://github.com/Carthage/Carthage">Carthage</a></h3>
|
<a href='#a-href-https-github-com-carthage-carthage-carthage-a' class='anchor' aria-hidden=true><span class="header-anchor"></span></a><h3 id='a-href-https-github-com-carthage-carthage-carthage-a'><a href="https://github.com/Carthage/Carthage">Carthage</a></h3>
|
||||||
|
|
||||||
|
@ -81,7 +83,7 @@ for up to date installation instructions.</li>
|
||||||
</ul>
|
</ul>
|
||||||
<a href='#how-it-works' class='anchor' aria-hidden=true><span class="header-anchor"></span></a><h2 id='how-it-works'>How It Works</h2>
|
<a href='#how-it-works' class='anchor' aria-hidden=true><span class="header-anchor"></span></a><h2 id='how-it-works'>How It Works</h2>
|
||||||
|
|
||||||
<p><code>Gifu</code> does not force you to use a specific subclass of <code>UIImageView</code>. The <code>Animator</code> class does the heavy-lifting, while the <code>GIFAnimatable</code> protocol exposes the functionality to the view classes that conform to it, using protocol extensions.</p>
|
<p><code>Gifu</code> does not force you to use the built-in <code>GIFImageView</code> subclass. The <code>Animator</code> does the heavy-lifting, while the <code>GIFAnimatable</code> protocol exposes the functionality to the view classes that conform to it, using protocol extensions.</p>
|
||||||
|
|
||||||
<p>The <code>Animator</code> has a <code>FrameStore</code> that only keeps a limited number of frames in-memory, effectively creating a buffer for the animation without consuming all the available memory. This approach makes loading large GIFs a lot more resource-friendly.</p>
|
<p>The <code>Animator</code> has a <code>FrameStore</code> that only keeps a limited number of frames in-memory, effectively creating a buffer for the animation without consuming all the available memory. This approach makes loading large GIFs a lot more resource-friendly.</p>
|
||||||
|
|
||||||
|
@ -94,15 +96,12 @@ containing 10 frames, Gifu will load the current frame (red), buffer the next tw
|
||||||
<p>There are two options that should cover any situation:</p>
|
<p>There are two options that should cover any situation:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>Use the built-in <code>GIFImageView</code> subclass.</li>
|
<li>Use the built-in <code>GIFImageView</code> subclass if you don’t need to combine GIF support with another image library.</li>
|
||||||
<li>Make any class conform to <code>GIFAnimatable</code>. Subclassing <code>UIImageView</code> is the easiest since you get most of the required properties for free.</li>
|
<li>If you need more flexibility and composability, make your class conform to <code>GIFAnimatable</code>. In practice, any <code>UIView</code> subclass would do, since you get most of the required properties for free. For best results, make your <code>UIImageView</code> subclass conform to <code>GIFAnimatable</code> to get other niceties such as intrinsic content size.</li>
|
||||||
</ul>
|
</ul>
|
||||||
<a href='#gifimageview' class='anchor' aria-hidden=true><span class="header-anchor"></span></a><h3 id='gifimageview'>GIFImageView</h3>
|
|
||||||
|
|
||||||
<p>A subclass of <code>UIImageView</code> that conforms to <code>GIFAnimatable</code>. You can use this class as-is or subclass it for further customization (not recommended).</p>
|
|
||||||
<a href='#gifanimatable' class='anchor' aria-hidden=true><span class="header-anchor"></span></a><h3 id='gifanimatable'>GIFAnimatable</h3>
|
<a href='#gifanimatable' class='anchor' aria-hidden=true><span class="header-anchor"></span></a><h3 id='gifanimatable'>GIFAnimatable</h3>
|
||||||
|
|
||||||
<p>The bread and butter of Gifu. Through protocol extensions, <code>GIFAnimatable</code> exposes all the APIs of the library, and with very little boilerplate, any <code>UIImageView</code> subclass can conform to it.</p>
|
<p>The bread and butter of Gifu. Through protocol extensions, <code>GIFAnimatable</code> exposes all the APIs of the library, and with very little boilerplate, any class can conform to it.</p>
|
||||||
<pre class="highlight swift"><code><span class="kd">class</span> <span class="kt">MyImageView</span><span class="p">:</span> <span class="kt">UIImageView</span><span class="p">,</span> <span class="kt">GIFAnimatable</span> <span class="p">{</span>
|
<pre class="highlight swift"><code><span class="kd">class</span> <span class="kt">MyImageView</span><span class="p">:</span> <span class="kt">UIImageView</span><span class="p">,</span> <span class="kt">GIFAnimatable</span> <span class="p">{</span>
|
||||||
<span class="kd">public</span> <span class="kd">lazy</span> <span class="k">var</span> <span class="nv">animator</span><span class="p">:</span> <span class="kt">Animator</span><span class="p">?</span> <span class="o">=</span> <span class="p">{</span>
|
<span class="kd">public</span> <span class="kd">lazy</span> <span class="k">var</span> <span class="nv">animator</span><span class="p">:</span> <span class="kt">Animator</span><span class="p">?</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
<span class="k">return</span> <span class="kt">Animator</span><span class="p">(</span><span class="nv">withDelegate</span><span class="p">:</span> <span class="k">self</span><span class="p">)</span>
|
<span class="k">return</span> <span class="kt">Animator</span><span class="p">(</span><span class="nv">withDelegate</span><span class="p">:</span> <span class="k">self</span><span class="p">)</span>
|
||||||
|
@ -114,7 +113,7 @@ containing 10 frames, Gifu will load the current frame (red), buffer the next tw
|
||||||
<span class="p">}</span>
|
<span class="p">}</span>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>That’s it. Now <code>MyImageView</code> is fully GIF-compatible, and any of these methods can be called on it:</p>
|
<p>That’s it. Now <code>MyImageView</code> has access to all these methods and properties:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>prepareForAnimation(withGIFNamed:)</code> and <code>prepareForAnimation(withGIFData:)</code> to prepare the animator property for animation.</li>
|
<li><code>prepareForAnimation(withGIFNamed:)</code> and <code>prepareForAnimation(withGIFData:)</code> to prepare the animator property for animation.</li>
|
||||||
|
@ -125,8 +124,16 @@ containing 10 frames, Gifu will load the current frame (red), buffer the next tw
|
||||||
<li><code>updateImageIfNeeded()</code> to update the image property if necessary.</li>
|
<li><code>updateImageIfNeeded()</code> to update the image property if necessary.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>This approach is especially powerful when you want to combine the functionality of different image libraries.</p>
|
<p>Furthermore, you can make any class GIF-animatable, starting with <code>UIView</code> subclasses:</p>
|
||||||
<pre class="highlight swift"><code><span class="kd">class</span> <span class="kt">MyImageView</span><span class="p">:</span> <span class="kt">OtherImageClass</span><span class="p">,</span> <span class="kt">GIFAnimatable</span> <span class="p">{}</span>
|
<pre class="highlight swift"><code><span class="kd">class</span> <span class="kt">CustomAnimatedView</span><span class="p">:</span> <span class="kt">UIView</span><span class="p">,</span> <span class="kt">GIFAnimatable</span> <span class="p">{</span>
|
||||||
|
<span class="kd">public</span> <span class="kd">lazy</span> <span class="k">var</span> <span class="nv">animator</span><span class="p">:</span> <span class="kt">Animator</span><span class="p">?</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="k">return</span> <span class="kt">Animator</span><span class="p">(</span><span class="nv">withDelegate</span><span class="p">:</span> <span class="k">self</span><span class="p">)</span>
|
||||||
|
<span class="p">}()</span>
|
||||||
|
|
||||||
|
<span class="k">override</span> <span class="kd">public</span> <span class="kd">func</span> <span class="nf">display</span><span class="p">(</span><span class="n">_</span> <span class="nv">layer</span><span class="p">:</span> <span class="kt">CALayer</span><span class="p">)</span> <span class="p">{</span>
|
||||||
|
<span class="nf">updateImageIfNeeded</span><span class="p">()</span>
|
||||||
|
<span class="p">}</span>
|
||||||
|
<span class="p">}</span>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>Keep in mind that you need to have control over the class implementing <code>GIFAnimatable</code> since you cannot add the stored <code>Animator</code> property in an extension.</p>
|
<p>Keep in mind that you need to have control over the class implementing <code>GIFAnimatable</code> since you cannot add the stored <code>Animator</code> property in an extension.</p>
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -63,6 +63,8 @@
|
||||||
<p>Gifu adds protocol-based, performance-aware animated GIF support to UIKit. (It’s also a <a href="https://goo.gl/maps/CCeAc">prefecture in Japan</a>).</p>
|
<p>Gifu adds protocol-based, performance-aware animated GIF support to UIKit. (It’s also a <a href="https://goo.gl/maps/CCeAc">prefecture in Japan</a>).</p>
|
||||||
|
|
||||||
<p>⚠ <strong>Swift 2.3</strong> support is on the <a href="https://github.com/kaishin/Gifu/tree/swift2.3">swift2.3</a> branch. <strong>This branch will not be getting any future updates</strong>.</p>
|
<p>⚠ <strong>Swift 2.3</strong> support is on the <a href="https://github.com/kaishin/Gifu/tree/swift2.3">swift2.3</a> branch. <strong>This branch will not be getting any future updates</strong>.</p>
|
||||||
|
|
||||||
|
<p>⚠ What follows applies to the yet unreleased <code>2.0</code> on <code>master</code>.</p>
|
||||||
<a href='#install' class='anchor' aria-hidden=true><span class="header-anchor"></span></a><h2 id='install'>Install</h2>
|
<a href='#install' class='anchor' aria-hidden=true><span class="header-anchor"></span></a><h2 id='install'>Install</h2>
|
||||||
<a href='#a-href-https-github-com-carthage-carthage-carthage-a' class='anchor' aria-hidden=true><span class="header-anchor"></span></a><h3 id='a-href-https-github-com-carthage-carthage-carthage-a'><a href="https://github.com/Carthage/Carthage">Carthage</a></h3>
|
<a href='#a-href-https-github-com-carthage-carthage-carthage-a' class='anchor' aria-hidden=true><span class="header-anchor"></span></a><h3 id='a-href-https-github-com-carthage-carthage-carthage-a'><a href="https://github.com/Carthage/Carthage">Carthage</a></h3>
|
||||||
|
|
||||||
|
@ -81,7 +83,7 @@ for up to date installation instructions.</li>
|
||||||
</ul>
|
</ul>
|
||||||
<a href='#how-it-works' class='anchor' aria-hidden=true><span class="header-anchor"></span></a><h2 id='how-it-works'>How It Works</h2>
|
<a href='#how-it-works' class='anchor' aria-hidden=true><span class="header-anchor"></span></a><h2 id='how-it-works'>How It Works</h2>
|
||||||
|
|
||||||
<p><code>Gifu</code> does not force you to use a specific subclass of <code>UIImageView</code>. The <code>Animator</code> class does the heavy-lifting, while the <code>GIFAnimatable</code> protocol exposes the functionality to the view classes that conform to it, using protocol extensions.</p>
|
<p><code>Gifu</code> does not force you to use the built-in <code>GIFImageView</code> subclass. The <code>Animator</code> does the heavy-lifting, while the <code>GIFAnimatable</code> protocol exposes the functionality to the view classes that conform to it, using protocol extensions.</p>
|
||||||
|
|
||||||
<p>The <code>Animator</code> has a <code>FrameStore</code> that only keeps a limited number of frames in-memory, effectively creating a buffer for the animation without consuming all the available memory. This approach makes loading large GIFs a lot more resource-friendly.</p>
|
<p>The <code>Animator</code> has a <code>FrameStore</code> that only keeps a limited number of frames in-memory, effectively creating a buffer for the animation without consuming all the available memory. This approach makes loading large GIFs a lot more resource-friendly.</p>
|
||||||
|
|
||||||
|
@ -94,15 +96,12 @@ containing 10 frames, Gifu will load the current frame (red), buffer the next tw
|
||||||
<p>There are two options that should cover any situation:</p>
|
<p>There are two options that should cover any situation:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>Use the built-in <code>GIFImageView</code> subclass.</li>
|
<li>Use the built-in <code>GIFImageView</code> subclass if you don’t need to combine GIF support with another image library.</li>
|
||||||
<li>Make any class conform to <code>GIFAnimatable</code>. Subclassing <code>UIImageView</code> is the easiest since you get most of the required properties for free.</li>
|
<li>If you need more flexibility and composability, make your class conform to <code>GIFAnimatable</code>. In practice, any <code>UIView</code> subclass would do, since you get most of the required properties for free. For best results, make your <code>UIImageView</code> subclass conform to <code>GIFAnimatable</code> to get other niceties such as intrinsic content size.</li>
|
||||||
</ul>
|
</ul>
|
||||||
<a href='#gifimageview' class='anchor' aria-hidden=true><span class="header-anchor"></span></a><h3 id='gifimageview'>GIFImageView</h3>
|
|
||||||
|
|
||||||
<p>A subclass of <code>UIImageView</code> that conforms to <code>GIFAnimatable</code>. You can use this class as-is or subclass it for further customization (not recommended).</p>
|
|
||||||
<a href='#gifanimatable' class='anchor' aria-hidden=true><span class="header-anchor"></span></a><h3 id='gifanimatable'>GIFAnimatable</h3>
|
<a href='#gifanimatable' class='anchor' aria-hidden=true><span class="header-anchor"></span></a><h3 id='gifanimatable'>GIFAnimatable</h3>
|
||||||
|
|
||||||
<p>The bread and butter of Gifu. Through protocol extensions, <code>GIFAnimatable</code> exposes all the APIs of the library, and with very little boilerplate, any <code>UIImageView</code> subclass can conform to it.</p>
|
<p>The bread and butter of Gifu. Through protocol extensions, <code>GIFAnimatable</code> exposes all the APIs of the library, and with very little boilerplate, any class can conform to it.</p>
|
||||||
<pre class="highlight swift"><code><span class="kd">class</span> <span class="kt">MyImageView</span><span class="p">:</span> <span class="kt">UIImageView</span><span class="p">,</span> <span class="kt">GIFAnimatable</span> <span class="p">{</span>
|
<pre class="highlight swift"><code><span class="kd">class</span> <span class="kt">MyImageView</span><span class="p">:</span> <span class="kt">UIImageView</span><span class="p">,</span> <span class="kt">GIFAnimatable</span> <span class="p">{</span>
|
||||||
<span class="kd">public</span> <span class="kd">lazy</span> <span class="k">var</span> <span class="nv">animator</span><span class="p">:</span> <span class="kt">Animator</span><span class="p">?</span> <span class="o">=</span> <span class="p">{</span>
|
<span class="kd">public</span> <span class="kd">lazy</span> <span class="k">var</span> <span class="nv">animator</span><span class="p">:</span> <span class="kt">Animator</span><span class="p">?</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
<span class="k">return</span> <span class="kt">Animator</span><span class="p">(</span><span class="nv">withDelegate</span><span class="p">:</span> <span class="k">self</span><span class="p">)</span>
|
<span class="k">return</span> <span class="kt">Animator</span><span class="p">(</span><span class="nv">withDelegate</span><span class="p">:</span> <span class="k">self</span><span class="p">)</span>
|
||||||
|
@ -114,7 +113,7 @@ containing 10 frames, Gifu will load the current frame (red), buffer the next tw
|
||||||
<span class="p">}</span>
|
<span class="p">}</span>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>That’s it. Now <code>MyImageView</code> is fully GIF-compatible, and any of these methods can be called on it:</p>
|
<p>That’s it. Now <code>MyImageView</code> has access to all these methods and properties:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>prepareForAnimation(withGIFNamed:)</code> and <code>prepareForAnimation(withGIFData:)</code> to prepare the animator property for animation.</li>
|
<li><code>prepareForAnimation(withGIFNamed:)</code> and <code>prepareForAnimation(withGIFData:)</code> to prepare the animator property for animation.</li>
|
||||||
|
@ -125,8 +124,16 @@ containing 10 frames, Gifu will load the current frame (red), buffer the next tw
|
||||||
<li><code>updateImageIfNeeded()</code> to update the image property if necessary.</li>
|
<li><code>updateImageIfNeeded()</code> to update the image property if necessary.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>This approach is especially powerful when you want to combine the functionality of different image libraries.</p>
|
<p>Furthermore, you can make any class GIF-animatable, starting with <code>UIView</code> subclasses:</p>
|
||||||
<pre class="highlight swift"><code><span class="kd">class</span> <span class="kt">MyImageView</span><span class="p">:</span> <span class="kt">OtherImageClass</span><span class="p">,</span> <span class="kt">GIFAnimatable</span> <span class="p">{}</span>
|
<pre class="highlight swift"><code><span class="kd">class</span> <span class="kt">CustomAnimatedView</span><span class="p">:</span> <span class="kt">UIView</span><span class="p">,</span> <span class="kt">GIFAnimatable</span> <span class="p">{</span>
|
||||||
|
<span class="kd">public</span> <span class="kd">lazy</span> <span class="k">var</span> <span class="nv">animator</span><span class="p">:</span> <span class="kt">Animator</span><span class="p">?</span> <span class="o">=</span> <span class="p">{</span>
|
||||||
|
<span class="k">return</span> <span class="kt">Animator</span><span class="p">(</span><span class="nv">withDelegate</span><span class="p">:</span> <span class="k">self</span><span class="p">)</span>
|
||||||
|
<span class="p">}()</span>
|
||||||
|
|
||||||
|
<span class="k">override</span> <span class="kd">public</span> <span class="kd">func</span> <span class="nf">display</span><span class="p">(</span><span class="n">_</span> <span class="nv">layer</span><span class="p">:</span> <span class="kt">CALayer</span><span class="p">)</span> <span class="p">{</span>
|
||||||
|
<span class="nf">updateImageIfNeeded</span><span class="p">()</span>
|
||||||
|
<span class="p">}</span>
|
||||||
|
<span class="p">}</span>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>Keep in mind that you need to have control over the class implementing <code>GIFAnimatable</code> since you cannot add the stored <code>Animator</code> property in an extension.</p>
|
<p>Keep in mind that you need to have control over the class implementing <code>GIFAnimatable</code> since you cannot add the stored <code>Animator</code> property in an extension.</p>
|
||||||
|
|
Loading…
Reference in New Issue