How to set Custom fonts for whole ios app from one file in Swift 5

 
Maniisha Gorasiya

Nowadays often we need to set custom font in iOS app which is not available in xcode storyboard. There is one way to set custom fonts from storyboard by set font for every objects of storyboard. But this way takes a lot of time and effort to set custom font because sometimes complex project has lots of ViewControllers with many objects and It takes a lot of time to select each object and set its font.

Here is one of the best, easy and short solution for above problem. Some steps and programming needs for set custom fonts from one file, and it sets font to whole app at run time.

Steps:

1. Add the Font File to Your Xcode Project

To add a font file to your Xcode project, select File > Add Files to “Your Project Name” from the menu bar, or select the font files from Finder.Make sure that the font comes in either TFF (TrueType Format) or OTF (OpenType Format).


- Register Your Font File in info.plist file


- Make sure that in your StroryBoard all objects have  System Font


2. Create new swift file named - AppFonts.swit

- Create Structure named – FontName

struct FontName {  

static let regular = "Open Sans"

static let semiBold = "OpenSans-Semibold"

}

 


NOTE: For get your custom Font Name:

for family: String in UIFont.familyNames

{

     print("\(family)")

     for names: String in   UIFont.fontNames(forFamilyName: family)

  {

      print("== \(names)")

  }

}


- Add Extension - UIFontDescriptor.AttributeName

extension UIFontDescriptor.AttributeName { 

                static let nsctFontUIUsage =  UIFontDescriptor.AttributeName

 (rawValue: "NSCTFontUIUsageAttribute")

}


- Create another Extension – UIFont



extension UIFont {

   static varisOverrided: Bool = false

   @objc class funcmySystemFont(ofSize size: CGFloat) ->UIFont {

       return UIFont(name: FontName.regular, size: size)!

    }    

  @objc class funcmySemiBoldSystemFont(ofSize size: CGFloat) ->UIFont {

     return UIFont(name: FontName.semiBold, size: size)!

   }

   @objc convenience init(myCoderaDecoder: NSCoder) {

        guard   let fontDescriptor = aDecoder.decodeObject(forKey: "UIFontDescriptor") as? UIFontDescriptor,

       let fontAttribute = fontDescriptor.fontAttributes

[.nsctFontUIUsage] as? String else {

            self.init(myCoder: aDecoder)

             return

 }

      varfontName = ""switch fontAttribute {

        case "CTFontRegularUsage":

           fontName = FontName.regular

       case "CTFontDemiUsage":

           fontName = FontName.semiBold

        default:

          fontName = FontName.regular

        }

       self.init(name: fontName, size: fontDescriptor.pointSize)!

  }

class funcoverrideInitialize() {

       guard self == UIFont.self, !isOverrided else { return }

  // Avoid method swizzling run twice and revert to original initialize function

      isOverrided = true

   if let systemFontMethod = class_getClassMethod(self, #selector(systemFont(ofSize:))),

       let mySystemFontMethod = class_getClassMethod(self, #selector(mySystemFont(ofSize:))) {

            method_exchangeImplementations(

systemFontMethod, mySystemFontMethod)

           // UITextField().font = UIFont.init(name: Apps.GLOBEL_FONTS, size: 14.0)!      

}     

 if let semiBoldSystemFontMethod = class_getClassMethod(self, #selector(boldSystemFont(ofSize:))),

          let mySemiBoldSystemFontMethod = class_getClassMethod(self, #selector(mySemiBoldSystemFont(ofSize:))) {

           method_exchangeImplementations(

semiBoldSystemFontMethod, mySemiBoldSystemFontMethod)

      }

       if let initCoderMethod = class_getInstanceMethod(self, #selector(UIFontDescriptor.init(coder:))), // Trick to get over the lack of UIFont.init(coder:))

          let myInitCoderMethod = class_getInstanceMethod(self, #selector(UIFont.init(myCoder:))) {

           method_exchangeImplementations(

initCoderMethod, myInitCoderMethod)

      }

    }

}

- Build & Run your app :)




Comments

BK
    12-06-2020

     can we have video demo? it will be a greate

Leave a Comment

Your email address will not be published.



First Floor, Madhav Complex, V. R. Nagar, Mirjapar Madhapar By Pass Ring Road, Bhuj-370001
+(91) 97 26 134340
Mon-Fri 9:00am-6:00pm
talk@lpktechnosoft.com
24 X 7 online support