How to Implement Gif Image Loading spinner in iOS Swift

Posted By : Nitin Bhatt | 10-Jan-2017

How to Implement Gif Image Loading spinner in iOS Swift

In this blog I have demonstrated how to implement Gif loading spinner in iOS swift.

 

To Implement loading spinner with Gif image first drag and drop the Gif image on your Xcode project  then create new file UIImage+Gif.swift and write this code inside this file.

 

 //
//  Gif.swift
//  SwiftGif
//
//  Created by Arne Bahlo on 07.06.14.
//  Copyright (c) 2014 Arne Bahlo. All rights reserved.
//

import UIKit
import ImageIO

extension UIImage {
    
    public class func gifWithData(data: NSData) -> UIImage? {
        guard let source = CGImageSourceCreateWithData(data, nil) else {
            print("SwiftGif: Source for the image does not exist")
            return nil
        }
        return UIImage.animatedImageWithSource(source)
    }
    
    public class func gifWithName(name: String) -> UIImage? {
        guard let bundleURL = NSBundle.mainBundle().URLForResource(name, withExtension: "gif") else {
            print("SwiftGif: This image named \"\(name)\" does not exist")
            return nil
        }
        guard let imageData = NSData(contentsOfURL: bundleURL) else {
            print("SwiftGif: Cannot turn image named \"\(name)\" into NSData")
            return nil
        }
        return gifWithData(imageData)
    }
    
    class func delayForImageAtIndex(index: Int, source: CGImageSource!) -> Double {
        var delay = 0.05
        
        // Get dictionaries
        let cfProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil)
        let gifProperties: CFDictionaryRef = unsafeBitCast(
            CFDictionaryGetValue(cfProperties,
                unsafeAddressOf(kCGImagePropertyGIFDictionary)),
            CFDictionary.self)

        // Get delay time
        var delayObject: AnyObject = unsafeBitCast(
            CFDictionaryGetValue(gifProperties,
                unsafeAddressOf(kCGImagePropertyGIFUnclampedDelayTime)),
            AnyObject.self)
        if delayObject.doubleValue == 0 {
            delayObject = unsafeBitCast(CFDictionaryGetValue(gifProperties,
                unsafeAddressOf(kCGImagePropertyGIFDelayTime)), AnyObject.self)
        }
        
        delay = delayObject as! Double
        
        if delay < 0.1 {
            delay = 0.1 // Make sure they're not too fast
        }
        
        return delay
    }
    
    class func gcdForPair(var a: Int?, var _ b: Int?) -> Int {
        // Check if one of them is nil
        if b == nil || a == nil {
            if b != nil {
                return b!
            } else if a != nil {
                return a!
            } else {
                return 0
            }
        }
        
        // Swap for modulo
        if a < b {
            let c = a
            a = b
            b = c
        }
        
        // Get greatest common divisor
        var rest: Int
        while true {
            rest = a! % b!
            
            if rest == 0 {
                return b! // Found it
            } else {
                a = b
                b = rest
            }
        }
    }
    
    class func gcdForArray(array: Array) -> Int {
        if array.isEmpty {
            return 1
        }
        
        var gcd = array[0]
        
        for val in array {
            gcd = UIImage.gcdForPair(val, gcd)
        }
        
        return gcd
    }
    
    class func animatedImageWithSource(source: CGImageSource) -> UIImage? {
        let count = CGImageSourceGetCount(source)
        var images = [CGImageRef]()
        var delays = [Int]()
        
        // Fill arrays
        for i in 0..<count {="" add="" image="" if="" let="" i,="" nil)="" images.append(image)="" }="" at="" it's="" delay="" in="" cs="" delayseconds="UIImage.delayForImageAtIndex(Int(i)," source:="" source)="" delays.append(int(delayseconds="" *="" 1000.0))="" seconds="" to="" ms="" calculate="" full="" duration="" duration:="" int="{" var="" sum="0" for="" val:="" delays="" +="val" return="" }()="" get="" frames="" gcd="gcdForArray(delays)" frame:="" uiimage="" framecount:="" i="" 0..="" 

 

Then create file  ActivityIndicatorWithLabel.swift write this code inside file.

import Foundation
import UIKit

public class ActivityIndicatorWithLabel {
    
    var containerView = UIView()
    var progressView = UIView()
    var activityIndicator = UIActivityIndicatorView()

    
    public class var shared: ActivityIndicatorWithLabel {
        struct Static {
            static let instance: ActivityIndicatorWithLabel = ActivityIndicatorWithLabel()
        }
        return Static.instance
    }
    
    var pinchImageView = UIImageView()
    
    public func showProgressView(uiView: UIView) {
        containerView.frame = CGRect(x: 0, y: 0, width: uiView.frame.width, height: uiView.frame.height)
        containerView.backgroundColor = UIColorFromHex(0xffffff, alpha: 0.80)
        let imageData = NSData(contentsOfURL: NSBundle.mainBundle().URLForResource("loadingSpinnerJeenees", withExtension: "gif")!)
        let animatedImage = UIImage.gifWithData(imageData!)
         pinchImageView = UIImageView(image: animatedImage)
        pinchImageView.frame = CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0)
//        pinchImageView.center = CGPointMake(30.0, 30.0);
        progressView.frame = CGRectMake(0, 0, (pinchImageView.frame.size.width), 60)
        progressView.center = uiView.center
        progressView.addSubview(pinchImageView)
        containerView.addSubview(progressView)
        uiView.addSubview(containerView)
    }
    
    public func hideProgressView() {
        activityIndicator.stopAnimating()
        pinchImageView.removeFromSuperview()
        activityIndicator.removeFromSuperview()
        progressView.removeFromSuperview()
        containerView.removeFromSuperview()
       
    }
    
    public func UIColorFromHex(rgbValue:UInt32, alpha:Double=1.0)->UIColor {
        let red = CGFloat((rgbValue & 0xFF0000) >> 16)/256.0
        let green = CGFloat((rgbValue & 0xFF00) >> 8)/256.0
        let blue = CGFloat(rgbValue & 0xFF)/256.0
        return UIColor(red:red, green:green, blue:blue, alpha:CGFloat(alpha))
    }
}
 

 

To show loading spinner write this code :-

 ActivityIndicatorWithLabel.shared.showProgressView(view)
 

 

 

 

 

To hide loading spinner write this code :-

 ActivityIndicatorWithLabel.shared.hideProgressView()
 

 

 

 

 

About Author

Author Image
Nitin Bhatt

Nitin is an Assistant Project Manager specializing in iOS Application Development. He is an avid reader.

Request for Proposal

Name is required

Comment is required

Sending message..