Scalable approach to create custom fonts and colours for your iOS app
Theme KIT/ Theme Manager
Problem Statement
- We need an efficient and maintainable solution for creating custom fonts and colors for our app that supports both SwiftUI and UIKit.
- Colors and fonts vary according to the market version of the app.
Eg.
- India market version has Font : X1 Color: Y1
- US market version has Font: X2 Color Y2
Solution:
we can achieve result in number of ways. But in this article we will try to approach it using App theming.
App theming is the process of customizing the look and feel of an app. This can include changing the colors, fonts, and other visual elements of the app. App theming can be used to create a more visually appealing and engaging app experience, or to make the app more accessible to users with different needs.
Benefit
- Can be configured for any number of markets.
- can be easily moved to a stand alone swift package
- Scalable to even custom reusbale UI components can also be added based on theme
- Ease of use for developer as its clearly marks list of colors, fonts supported.
Usage
Colors
SwiftUI: Theme.india.headline1.color
UIKit: Theme.usa.body.uicolor
Fonts
SwiftUI: Theme.india.body.font
UIKit: Theme.usa.headline1.uiFont.
Approach:
1. we will create a Theme enum that shall support multiple markets.
public enum Theme {
case usa
case india
public static var current = Theme.taiwan {
didSet {
// once theme is set , we can register font for that theme
let fontName = FontFamily.fontName(theme: current)
FontFamily.registerFonts(fontName: fontName)
}
}
}
2. we need to set current Theme in appDelegate or starting point of app
Theme.current = .india
3. Colors:
- create a new
.xcassets
file for Colors with nameColors.xcassets
- add static reference for above assets from UIColor+Extension.
extension UIColor {
static func white(theme: Theme) -> UIColor {
let assetName = UIColor.assetName("white",
theme: theme)
return UIColor(named: assetName, in: .module, compatibleWith: nil) ?? .clear
}
}
- create a ColorType struct to support UIKit and SwiftUI apps.
public struct ColorType {
public private(set) var uiColor: UIColor
/// Provides color for the ui elements.
public var color: Color {
// convert UIKit color to swiftUI
uiColor.suiColor
}
}
- create a Extension from Theme enum : Theme+ColorExtension.swift which holds the Color Type and shares color for uikit and SwiftUI.
public extension Theme {
var white: ColorType {
let uiColor = UIColor.white(theme: self)
return ColorType(uiColor: uiColor)
}
}
2.Fonts:
- add a FontFamily enum with cases as custom fonts.
enum FontFamily {
case headline1(theme: Theme)
case headline2(theme: Theme)
//gives custom font for case mentioned above
var font: {...}
//gives lineHeight for case mentioned above
var lineHeight: {...}
}
- create a FontStyle struct to support UIKit and SwiftUI apps.
public struct FontStyle {
public private(set) var uiFont: UIFont
public var font: Font {
// support swift ui fonts
return scaledUIFont.suiFont
}
public var lineHeight: CGFloat
}
- create a Extension from Theme enum : Theme+FontExtension.swift which holds the FontStyle and shares fonts for uikit and SwiftUI.
public extension Theme {
var headline1: FontStyle {
let fontStyle = FontFamily.headline1(theme: self)
return FontStyle(uiFont: fontStyle.font,
lineHeight: fontStyle.lineHeight,
scaledUIFont: fontStyle.scaledUIFont)
}
}
Package Repo
Here is standalone swift package with Theme supporting multiple markets.
https://github.com/raghav1786/my_theme_kit_ios
Visit above repo for more info.
Demo Project
I have used standlone swift package with Theme into my demo app.
Thanks for reading through. Please feel free to drop off any suggestions and improvements.
we can also connect in below mentioned forums.
Linkedin: https://www.linkedin.com/in/raghav-sharma-0960a1144/
Github: https://github.com/raghav1786