0

I am working on one multitarget project where it consists of two apps with each having its own branding.

I have distinguished app name, app icon, and branding color of the app but now I need to switch fonts family of the app dynamically after fetching branding details from API.

The problem I am trying to solve is keeping same font sizes but with different font family.

I tried finding a way out to keep the font sizes same with different font family but didn't succeed, Please let me know if you have any suggestions to solve this particular case.

Jarvis The Avenger
  • 2,750
  • 1
  • 19
  • 37
  • assuming you are using UIFont(...) to set your information but have you looked into using attributes instead? – dniswhite Oct 16 '18 at 04:28
  • @dniswhite all the fonts are set on the storyboard. Is there any way we can use a different font family for the different target using storyboard? – Jarvis The Avenger Oct 16 '18 at 04:34

2 Answers2

0

Update the visual appearance of an entire application in minutes using NUI. You just have to define themes like Theme1.nss and Theme2.nss in two different files then AppDelegate's application didFinishLaunchingWithOptions method you just tell the NUI framework to load those theme accordingly to targets

if Target1

[NUISettings initWithStylesheet:@"Theme1"];    

#elif Target2

[NUISettings initWithStylesheet:@"Theme2"];

#endif

Baig
  • 4,737
  • 1
  • 32
  • 47
0

I found a way to solve this problem through method swizzling. Following are steps to solve this problem:

  • Step1: Create an extension of UIFont and the following code to override font name and family runtime.

Code Example:

  var appFontName = "ArialMT"
  var appFontBoldName = "Arial-BoldMT"

 extension UIFontDescriptor.AttributeName {
   static let nsctFontUIUsage = UIFontDescriptor.AttributeName(rawValue: "NSCTFontUIUsageAttribute")
 } 

extension UIFont {

@objc class func mySystemFont(ofSize size: CGFloat) -> UIFont {
    return UIFont(name: appFontName, size: size)!
}

@objc class func myBoldSystemFont(ofSize size: CGFloat) -> UIFont {
    return UIFont(name: appFontBoldName, size: size)!
}

@objc convenience init(myCoder aDecoder: NSCoder) {

    guard let fontDescriptor = aDecoder.decodeObject(forKey: "UIFontDescriptor") as? UIFontDescriptor else  {
        self.init(myCoder: aDecoder)
        return
    }
    let face = fontDescriptor.object(forKey: UIFontDescriptor.AttributeName.face) as? String ?? "Regular"
    var fontName = appFontName

    switch face {
    case "Regular":
        fontName = appFontName
    case "Bold":
        fontName = appFontBoldName
    default:
        fontName = appFontName
    }
    self.init(name: fontName, size: fontDescriptor.pointSize)!
}

class func overrideInitialize() {
    if self == UIFont.self {
        let systemFontMethod = class_getClassMethod(self, #selector(systemFont(ofSize:)))
        let mySystemFontMethod = class_getClassMethod(self, #selector(mySystemFont(ofSize:)))
        method_exchangeImplementations(systemFontMethod!, mySystemFontMethod!)

        let boldSystemFontMethod = class_getClassMethod(self, #selector(boldSystemFont(ofSize:)))
        let myBoldSystemFontMethod = class_getClassMethod(self, #selector(myBoldSystemFont(ofSize:)))
        method_exchangeImplementations(boldSystemFontMethod!, myBoldSystemFontMethod!)

        let initCoderMethod = class_getInstanceMethod(self, #selector(UIFontDescriptor.init(coder:)))
        let myInitCoderMethod = class_getInstanceMethod(self, #selector(UIFont.init(myCoder:)))
        method_exchangeImplementations(initCoderMethod!, myInitCoderMethod!)
    }
  }
}
  • Step2: (Usage) and call the overrideInitialize method.

    UIFont.overrideInitialize()
    

It preserves Font size by changing font family throughout your app. :)

Jarvis The Avenger
  • 2,750
  • 1
  • 19
  • 37