 
 public extension UITextField{
     func processIcons() {
-        let text = self.text! as NSString
-        let textRange = NSMakeRange(0, text.length)
-        let attributedString = NSMutableAttributedString(string: self.text!)
-        
-        text.enumerateSubstringsInRange(textRange, options: .ByWords, usingBlock: {
-            (substring, substringRange, _, _) in
-            var s = ["", ""]
-            s = substring!.characters.split{$0 == ":"}.map(String.init)
-            if s.count == 1{
-                return
-            }
-            if let _ = fontAwesomeIconArr[s[1]] where s[0].lowercaseString == "fa"{
-                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.FontAwesome, code: s[1])!)
-                let newRange = _NSRange(location: substringRange.location, length: 1)
-                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.FontAwesome, fontSize: self.font!.pointSize), range: newRange)
-            }
-            if let _ = ioniconArr[s[1]] where s[0].lowercaseString == "ii"{
-                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.Ionicon, code: s[1])!)
-                let newRange = _NSRange(location: substringRange.location, length: 1)
-                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.Ionicon, fontSize: self.font!.pointSize), range: newRange)
-            }
-            if let _ = octiconArr[s[1]] where s[0].lowercaseString == "oi"{
-                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.Octicon, code: s[1])!)
-                let newRange = _NSRange(location: substringRange.location, length: 1)
-                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.Octicon, fontSize: self.font!.pointSize), range: newRange)
-            }
-            if let _ = iconicIconArr[s[1]] where s[0].lowercaseString == "inic"{
-                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.Iconic, code: s[1])!)
-                let newRange = _NSRange(location: substringRange.location, length: 1)
-                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.Iconic, fontSize: self.font!.pointSize), range: newRange)
-            }
-            if let _ = elegantIconArr[s[1]] where s[0].lowercaseString == "el"{
-                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.ElegantIcons, code: s[1])!)
-                let newRange = _NSRange(location: substringRange.location, length: 1)
-                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.ElegantIcons, fontSize: self.font!.pointSize), range: newRange)
-            }
-            if let _ = themifyIconArr[s[1]] where s[0].lowercaseString == "th"{
-                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.Themify, code: s[1])!)
-                let newRange = _NSRange(location: substringRange.location, length: 1)
-                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.Themify, fontSize: self.font!.pointSize), range: newRange)
-            }
-            if let _ = mapIconsArr[s[1]] where s[0].lowercaseString == "mp"{
-                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.MapIcons, code: s[1])!)
-                let newRange = _NSRange(location: substringRange.location, length: 1)
-                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.MapIcons, fontSize: self.font!.pointSize), range: newRange)
-            }
-            if let _ = stroke7Arr[s[1]] where s[0].lowercaseString == "pe"{
-                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.Stroke7, code: s[1])!)
-                let newRange = _NSRange(location: substringRange.location, length: 1)
-                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.Stroke7, fontSize: self.font!.pointSize), range: newRange)
-            }
-            if let _ = materialIconArr[s[1]] where s[0].lowercaseString == "mat"{
-                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.Material, code: s[1])!)
-                let newRange = _NSRange(location: substringRange.location, length: 1)
-                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.Material, fontSize: self.font!.pointSize), range: newRange)
-            }
+        processTextIcons(self.text! as NSString, pointSize: self.font!.pointSize, attributedStringToCheck: self.attributedText!, setTextCallback: {(attributedString: NSAttributedString) in
+            self.attributedText = attributedString
         })
-        
-        self.attributedText = attributedString
     }
     
-    func setTextWithIconFont(font: Fonts, size: CGFloat = 15.0, text: String){
+    func setTextWithIconFont(font: FontsFileNames, size: CGFloat = 15.0, text: String){
         self.font = UIFont.iconFontOfSize(font, fontSize: size)
         self.text = text
     }
 }
 
-public extension UIButton{
+public extension UIButton {
     func processIcons() {
-        let text = (self.titleLabel?.text)! as NSString
-        let textRange = NSMakeRange(0, text.length)
-        let attributedString = NSMutableAttributedString(string: (self.titleLabel?.text)!)
-        
-        text.enumerateSubstringsInRange(textRange, options: .ByWords, usingBlock: {
-            (substring, substringRange, _, _) in
-            var s = ["", ""]
-            s = substring!.characters.split{$0 == ":"}.map(String.init)
-            if s.count == 1{
-                return
-            }
-            if let _ = fontAwesomeIconArr[s[1]] where s[0].lowercaseString == "fa"{
-                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.FontAwesome, code: s[1])!)
-                let newRange = _NSRange(location: substringRange.location, length: 1)
-                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.FontAwesome, fontSize: (self.titleLabel?.font!.pointSize)!), range: newRange)
-            }
-            if let _ = ioniconArr[s[1]] where s[0].lowercaseString == "ii"{
-                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.Ionicon, code: s[1])!)
-                let newRange = _NSRange(location: substringRange.location, length: 1)
-                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.Ionicon, fontSize: (self.titleLabel?.font!.pointSize)!), range: newRange)
-            }
-            if let _ = octiconArr[s[1]] where s[0].lowercaseString == "oi"{
-                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.Octicon, code: s[1])!)
-                let newRange = _NSRange(location: substringRange.location, length: 1)
-                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.Octicon, fontSize: (self.titleLabel?.font!.pointSize)!), range: newRange)
-            }
-            if let _ = iconicIconArr[s[1]] where s[0].lowercaseString == "inic"{
-                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.Iconic, code: s[1])!)
-                let newRange = _NSRange(location: substringRange.location, length: 1)
-                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.Iconic, fontSize: (self.titleLabel?.font!.pointSize)!), range: newRange)
-            }
-            if let _ = elegantIconArr[s[1]] where s[0].lowercaseString == "el"{
-                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.ElegantIcons, code: s[1])!)
-                let newRange = _NSRange(location: substringRange.location, length: 1)
-                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.ElegantIcons, fontSize: (self.titleLabel?.font!.pointSize)!), range: newRange)
-            }
-            if let _ = themifyIconArr[s[1]] where s[0].lowercaseString == "th"{
-                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.Themify, code: s[1])!)
-                let newRange = _NSRange(location: substringRange.location, length: 1)
-                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.Themify, fontSize: (self.titleLabel?.font!.pointSize)!), range: newRange)
-            }
-            if let _ = mapIconsArr[s[1]] where s[0].lowercaseString == "mp"{
-                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.MapIcons, code: s[1])!)
-                let newRange = _NSRange(location: substringRange.location, length: 1)
-                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.MapIcons, fontSize: (self.titleLabel?.font!.pointSize)!), range: newRange)
-            }
-            if let _ = stroke7Arr[s[1]] where s[0].lowercaseString == "pe"{
-                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.Stroke7, code: s[1])!)
-                let newRange = _NSRange(location: substringRange.location, length: 1)
-                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.Stroke7, fontSize: (self.titleLabel?.font!.pointSize)!), range: newRange)
-            }
-            if let _ = materialIconArr[s[1]] where s[0].lowercaseString == "mat"{
-                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.Material, code: s[1])!)
-                let newRange = _NSRange(location: substringRange.location, length: 1)
-                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.Material, fontSize: (self.titleLabel?.font!.pointSize)!), range: newRange)
-            }
+        processTextIcons((self.titleLabel?.text)! as NSString, pointSize: (self.titleLabel?.font!.pointSize)!, attributedStringToCheck: (self.titleLabel?.attributedText)!, setTextCallback: {(attributedString: NSAttributedString) in
+            self.setAttributedTitle(attributedString, forState: .Normal)
         })
-        
-        self.setAttributedTitle(attributedString, forState: .Normal)
     }
     
-    func setTextWithIconFont(font: Fonts, size: CGFloat = 15.0, text: String){
+    func setTextWithIconFont(font: FontsFileNames, size: CGFloat = 15.0, text: String){
         self.titleLabel?.font = UIFont.iconFontOfSize(font, fontSize: size)
         self.titleLabel?.text = text
     }
 }
 
 public extension UIFont{
-    static func iconFontOfSize(font: Fonts, fontSize: CGFloat) -> UIFont {
-        let fontName = font.rawValue
+    static func iconFontOfSize(font: FontsFileNames, fontSize: CGFloat) -> UIFont {
+        let fontFileName = font.rawValue
+        let fontName = FontNames[fontFileName]
         var token: dispatch_once_t = 0
-        if (UIFont.fontNamesForFamilyName(fontName).count == 0) {
+        if (UIFont.fontNamesForFamilyName(fontName!).count == 0) {
             dispatch_once(&token) {
-                FontLoader.loadFont(fontName.lowercaseString)
+                FontLoader.loadFont(fontFileName.lowercaseString)
             }
         }
-        return UIFont(name: fontName, size: fontSize)!
+        return UIFont(name: fontName!, size: fontSize)!
     }
 }
 
 public extension String {
-    public static func iconWithCode(font: Fonts, code: String) -> String? {
+    public static func iconWithCode(font: FontsFileNames, code: String) -> String? {
         if let icon = FontArr.getFontArr(font)[code] {
             return icon
         }

    }
}

public extension UILabel{
    func processIcons() {
        let text = self.text! as NSString
        let textRange = NSMakeRange(0, text.length)
        let attributedString = NSMutableAttributedString(string: self.text!)
        
        text.enumerateSubstringsInRange(textRange, options: .ByWords, usingBlock: {
            (substring, substringRange, _, _) in
            var s = ["", ""]
            s = substring!.characters.split{$0 == ":"}.map(String.init)
            if s.count == 1{
                return
            }
            if let _ = fontAwesomeIconArr[s[1]] where s[0].lowercaseString == "fa"{
                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.FontAwesome, code: s[1])!)
                let newRange = _NSRange(location: substringRange.location, length: 1)
                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.FontAwesome, fontSize: self.font!.pointSize), range: newRange)
            }
            if let _ = ioniconArr[s[1]] where s[0].lowercaseString == "ii"{
                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.Ionicon, code: s[1])!)
                let newRange = _NSRange(location: substringRange.location, length: 1)
                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.Ionicon, fontSize: self.font!.pointSize), range: newRange)
            }
            if let _ = octiconArr[s[1]] where s[0].lowercaseString == "oi"{
                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.Octicon, code: s[1])!)
                let newRange = _NSRange(location: substringRange.location, length: 1)
                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.Octicon, fontSize: self.font!.pointSize), range: newRange)
            }
            if let _ = iconicIconArr[s[1]] where s[0].lowercaseString == "inic"{
                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.Iconic, code: s[1])!)
                let newRange = _NSRange(location: substringRange.location, length: 1)
                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.Iconic, fontSize: self.font!.pointSize), range: newRange)
            }
            if let _ = elegantIconArr[s[1]] where s[0].lowercaseString == "el"{
                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.ElegantIcons, code: s[1])!)
                let newRange = _NSRange(location: substringRange.location, length: 1)
                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.ElegantIcons, fontSize: self.font!.pointSize), range: newRange)
            }
            if let _ = themifyIconArr[s[1]] where s[0].lowercaseString == "th"{
                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.Themify, code: s[1])!)
                let newRange = _NSRange(location: substringRange.location, length: 1)
                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.Themify, fontSize: self.font!.pointSize), range: newRange)
            }
            if let _ = mapIconsArr[s[1]] where s[0].lowercaseString == "mp"{
                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.MapIcons, code: s[1])!)
                let newRange = _NSRange(location: substringRange.location, length: 1)
                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.MapIcons, fontSize: self.font!.pointSize), range: newRange)
            }
            if let _ = stroke7Arr[s[1]] where s[0].lowercaseString == "pe"{
                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.Stroke7, code: s[1])!)
                let newRange = _NSRange(location: substringRange.location, length: 1)
                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.Stroke7, fontSize: self.font!.pointSize), range: newRange)
            }
            if let _ = materialIconArr[s[1]] where s[0].lowercaseString == "mat"{
                attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(Fonts.Material, code: s[1])!)
                let newRange = _NSRange(location: substringRange.location, length: 1)
                attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(Fonts.Material, fontSize: self.font!.pointSize), range: newRange)
            }
        })
        
        self.attributedText = attributedString
    }
    
    func setTextWithIconFont(font: Fonts, size: CGFloat = 15.0, text: String){
        self.font = UIFont.iconFontOfSize(font, fontSize: size)
        self.text = text
    }

//
//  JQSwiftIcon.swift
//
//  Created by Jose Quintero on 9/11/2016 and tweaked by Roman Zhyliov on 08/08/2016.
//  Copyright © 2016 Jose Quintero. All rights reserved.
//

import UIKit

let FontNames = [
    "fontawesome"               : "FontAwesome"
    , "open-iconic"             : "Icons"
    , "ionicons"                : "Ionicons"
    , "octicons"                : "octicons"
    , "eleganticons"            : "ElegantIcons"
    , "themify"                 : "themify"
    , "map-icons"               : "map-icons"
    , "pe-icon-7-stroke"        : "Pe-icon-7-stroke"
    , "materialicons-regular"   : "Material Icons"
]

public enum FontsFileNames: String {
    case FontAwesome  = "fontawesome"
    , Iconic       = "open-iconic"
    , Ionicon      = "ionicons"
    , Octicon      = "octicons"
    , ElegantIcons = "eleganticons"
    , Themify      = "themify"
    , MapIcons     = "map-icons"
    , Stroke7      = "pe-icon-7-stroke"
    , Material     = "materialicons-regular"
}

func processFont(fontSize: CGFloat?, fontFileName: FontsFileNames, attributedString: NSMutableAttributedString, matchedStringArray: [String], substring: String!) {
    
    let substringRange = NSMakeRange(0, substring.characters.count);
    attributedString.replaceCharactersInRange(substringRange, withString: String.iconWithCode(fontFileName, code: matchedStringArray[1])!)
    let newRange = _NSRange(location: substringRange.location, length: 1)
    attributedString.addAttribute(NSFontAttributeName, value: UIFont.iconFontOfSize(fontFileName, fontSize: (fontSize)!), range: newRange)
}

func processFontPrefixes(fontSize: CGFloat?, attributedString: NSMutableAttributedString, matchedStringArray: [String], substring: String!) {
    if let _ = fontAwesomeIconArr[matchedStringArray[1]] where matchedStringArray[0].lowercaseString == "fa"{
        processFont(fontSize, fontFileName: FontsFileNames.FontAwesome, attributedString: attributedString, matchedStringArray: matchedStringArray, substring: substring);
    }
    if let _ = ioniconArr[matchedStringArray[1]] where matchedStringArray[0].lowercaseString == "ii"{
        processFont(fontSize, fontFileName: FontsFileNames.Ionicon, attributedString: attributedString, matchedStringArray: matchedStringArray, substring: substring);
    }
    if let _ = octiconArr[matchedStringArray[1]] where matchedStringArray[0].lowercaseString == "oi"{
        processFont(fontSize, fontFileName: FontsFileNames.Octicon, attributedString: attributedString, matchedStringArray: matchedStringArray, substring: substring);
    }
    if let _ = iconicIconArr[matchedStringArray[1]] where matchedStringArray[0].lowercaseString == "inic"{
        processFont(fontSize, fontFileName: FontsFileNames.Iconic, attributedString: attributedString, matchedStringArray: matchedStringArray, substring: substring);
    }
    if let _ = elegantIconArr[matchedStringArray[1]] where matchedStringArray[0].lowercaseString == "el"{
        processFont(fontSize, fontFileName: FontsFileNames.ElegantIcons, attributedString: attributedString, matchedStringArray: matchedStringArray, substring: substring);
    }
    if let _ = themifyIconArr[matchedStringArray[1]] where matchedStringArray[0].lowercaseString == "th"{
        processFont(fontSize, fontFileName: FontsFileNames.Themify, attributedString: attributedString, matchedStringArray: matchedStringArray, substring: substring);
    }
    if let _ = mapIconsArr[matchedStringArray[1]] where matchedStringArray[0].lowercaseString == "mp"{
        processFont(fontSize, fontFileName: FontsFileNames.MapIcons, attributedString: attributedString, matchedStringArray: matchedStringArray, substring: substring);
    }
    if let _ = stroke7Arr[matchedStringArray[1]] where matchedStringArray[0].lowercaseString == "pe"{
        processFont(fontSize, fontFileName: FontsFileNames.Stroke7, attributedString: attributedString, matchedStringArray: matchedStringArray, substring: substring);
    }
    if let _ = materialIconArr[matchedStringArray[1]] where matchedStringArray[0].lowercaseString == "mat"{
        processFont(fontSize, fontFileName: FontsFileNames.Material, attributedString: attributedString, matchedStringArray: matchedStringArray, substring: substring);
    }
}

func processTextIcons(
    textToCheck: NSString,
    pointSize: CGFloat,
    attributedStringToCheck: NSAttributedString,
    setTextCallback: (NSAttributedString) -> Void) {
    
    let text = textToCheck;
    let textRange = NSMakeRange(0, text.length)
    let attributedString = NSMutableAttributedString(string: textToCheck as String)
    
    text.enumerateSubstringsInRange(textRange, options: .ByWords, usingBlock: {
        (substring, substringRange, _, _) in
        var s = ["", ""]
        s = substring!.characters.split{$0 == ":"}.map(String.init)
        if s.count == 1{
            return
        }
        processFontPrefixes(pointSize, attributedString: attributedString, matchedStringArray: s, substring: substring)
    })
    
    //when the view is about to be released -> overassignment mightn happen
    //which will cause visual font issue
    if (attributedStringToCheck.string != attributedString.string) {
        setTextCallback(attributedString);
    }
}


public struct FontArr {
    static func getFontArr(fromFont: FontsFileNames) -> [String: String]{
        if fromFont == .FontAwesome{
            return fontAwesomeIconArr
        }else if fromFont == .Iconic {
