A Swift macro that automates font property generation and provides a helper method for custom font sizes based on a provided font name.
FontsGeneratorMacro simplifies font management in SwiftUI by dynamically generating static font properties for common text styles (e.g., largeTitle, title, body) and a helper function for custom sizes.
- Automatic Font Property Generation – Creates static properties for SwiftUI text styles.
- Custom Font Size Support – Use
ofSize(_:)to define arbitrary font sizes. - Error Handling – Throws an error if no font name is provided.
To install via Swift Package Manager, add this dependency to your Package.swift:
.package(url: "https://github.com/vetrek/fonts-generator-macro", from: "1.0.0"),
Define your font inside an extension Font, ensuring proper namespacing and clarity:
extension Font {
enum FuturaBT {
@FontGenerator(fontName: "FuturaBT-Bold")
enum Bold {}
@FontGenerator(fontName: "FuturaBT-Light")
enum Light {}
@FontGenerator(fontName: "FuturaBT-Italic")
enum Italic {}
}
}Encapsulating fonts within Font provides better structure, usability, and readability.
Text("Hello, World!")
.font(.FuturaBT.Bold.largeTitle)- Avoids cluttering global scope with multiple enums.
- Keeps font-related definitions grouped.
- Reduces conflicts with other types.
Swift and SwiftUI follow a structured, namespaced approach for clarity:
UIColor.systemRedUIFont.TextStyle.bodyFont.largeTitle
Use the generated fonts seamlessly in SwiftUI:
struct ContentView: View {
var body: some View {
VStack(spacing: 10) {
Text("Large Title")
.font(.FuturaBT.Bold.largeTitle)
Text("Body")
.font(.FuturaBT.Bold.body)
Text("Custom Size")
.font(.FuturaBT.Bold.ofSize(14))
}
}
}When the macro expands, it generates the following:
extension Font {
enum FuturaBT {
enum Bold {
public static var largeTitle: Font {
.custom("AnyFontName", size: 34, relativeTo: .largeTitle)
}
public static var title: Font {
.custom("AnyFontName", size: 28, relativeTo: .title)
}
public static var title2: Font {
.custom("AnyFontName", size: 22, relativeTo: .title2)
}
public static var title3: Font {
.custom("AnyFontName", size: 20, relativeTo: .title3)
}
public static var body: Font {
.custom("AnyFontName", size: 17, relativeTo: .body)
}
public static var callout: Font {
.custom("AnyFontName", size: 16, relativeTo: .callout)
}
public static var subheadline: Font {
.custom("AnyFontName", size: 15, relativeTo: .subheadline)
}
public static var footnote: Font {
.custom("AnyFontName", size: 13, relativeTo: .footnote)
}
public static var caption: Font {
.custom("AnyFontName", size: 12, relativeTo: .caption)
}
public static var caption2: Font {
.custom("AnyFontName", size: 11, relativeTo: .caption2)
}
public static func ofSize(_ size: CGFloat) -> Font {
.custom("AnyFontName", size: size)
}
}
}
}We welcome contributions! Feel free to:
- Report issues.
- Submit pull requests.
- Suggest features.
This project is licensed under the MIT License. See LICENSE for details.
For any questions or support, feel free to open an issue.