{"id":13474264,"url":"https://github.com/dufflink/vfont","last_synced_at":"2025-04-10T03:40:19.645Z","repository":{"id":39743841,"uuid":"485317162","full_name":"dufflink/vfont","owner":"dufflink","description":"iOS Variable Font Integration","archived":false,"fork":false,"pushed_at":"2022-09-21T12:12:23.000Z","size":625,"stargazers_count":69,"open_issues_count":3,"forks_count":4,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-08-04T09:13:24.477Z","etag":null,"topics":["cocoapods","ios","swift","swift-package-manager","swiftui","variable-fonts"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dufflink.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-04-25T10:04:15.000Z","updated_at":"2024-07-21T08:11:45.000Z","dependencies_parsed_at":"2022-07-13T15:29:20.922Z","dependency_job_id":null,"html_url":"https://github.com/dufflink/vfont","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dufflink%2Fvfont","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dufflink%2Fvfont/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dufflink%2Fvfont/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dufflink%2Fvfont/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dufflink","download_url":"https://codeload.github.com/dufflink/vfont/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248154675,"owners_count":21056541,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cocoapods","ios","swift","swift-package-manager","swiftui","variable-fonts"],"created_at":"2024-07-31T16:01:10.859Z","updated_at":"2025-04-10T03:40:19.605Z","avatar_url":"https://github.com/dufflink.png","language":"Swift","funding_links":[],"categories":["Swift"],"sub_categories":[],"readme":"[![Version](https://img.shields.io/badge/Version-0.6.1-red?style=flat-square)](https://img.shields.io/badge/Version-0.6.1-red?style=flat-square)\n[![Platforms](https://img.shields.io/badge/Platforms-iOS-blue?style=flat-square)](https://img.shields.io/badge/Platforms-iOS-blue?style=flat-square)\n[![SwiftUI](https://img.shields.io/badge/SwiftUI-compatible-orange?style=flat-square)](https://img.shields.io/badge/SwiftUI-compatible-orange?style=flat-square)\n[![Swift Package Manager](https://img.shields.io/badge/Swift_Package_Manager-compatible-green?style=flat-square)](https://img.shields.io/badge/Swift_Package_Manager-compatible-green?style=flat-square)\n[![Cocoapods](https://img.shields.io/badge/Cocoapods-compatible-green?style=flat-square)](https://img.shields.io/badge/Cocoapods-compatible-green?style=flat-square)\n\n# VFont\n\u003cimg width=\"200\" height=\"130\" src=\"https://user-images.githubusercontent.com/29461219/170474103-3bc01bce-56eb-487d-867d-79c31296c885.gif\"/\u003e\n\n\u003cimg align=\"right\" height=\"160\" width=\"160\"\n     title=\"VFont logo\" src=\"https://user-images.githubusercontent.com/29461219/168282928-cd6bd7ea-12e0-4572-8a8b-2b65538edb03.svg\"\u003e\n\n`VFont` is a brilliant library which simplifies working with variable fonts in iOS projects. \n\nIf you've never heard about variable fonts, I'd recommend reading this article [Variable fonts in real life: how to use and love them](https://evilmartians.com/chronicles/variable-fonts-in-real-life-how-to-use-and-love-them) by [@romashamin](https://github.com/romashamin)\n\n\u003ca href=\"https://evilmartians.com/\"\u003e\n  \u003cimg\n    src=\"https://evilmartians.com/badges/sponsored-by-evil-martians.svg\"\n    alt=\"Sponsored by Evil Martians\"\n    width=\"236\"\n    height=\"54\"/\u003e \n\u003c/a\u003e\n\n## What does the library make easier?\n\nFirst of all, I wondered if variable fonts are supported in iOS. Nowadays, developers use the top-level `UIFont` class to work individually with Light, Regular, Medium, Bold, and other font styles. I discovered that VF support had already been added in `iOS 3.2`. However, it was implemented using low level code in the `CTFont` class in the `CoreText` library. This leads to extra work in order to get to variable fonts using `CoreText` and `UIFont`.\n\n## Usage\nFirst, you need to add the custom variable font to your project. If you've never done this, I recommend reading this [tutorial](https://sarunw.com/posts/how-to-add-custom-fonts-to-ios-app). \n\u003e❗️ Be aware that the font file name can be different from the actual font name! To get the correct full font name, upload the font file to [fontgauntlet.com](https://fontgauntlet.com/).\n### Native instruments\n```swift\n// First, you have to get information about the variable font (axes names, IDs, and allowed values). But the current axis value isn't there 🤷‍♂️\n// Here you can face a problem, like the custom font wasn't added to the project, was added incorrectly, or font name isn't correct\nlet uiFont = UIFont(name: \"Martian Mono\", size: 16.0)!\nlet ctFont = CTFontCreateWithName(uiFont.fontName as CFString, 16.0, nil)\nlet variationAxes = CTFontCopyVariationAxes(ctFont) as! [Any] // font information with weird format 👎\n\n// To set new values you need to know the correct axis IDs and allowed values (maxValue and minValue)\nlet variations = [2003265652: 600, 2003072104: 100] // 2003265652 - 'Weight'; 2003072104 - `Width`\n\n// As we know, text elements in UIKit use the UIFont class. So, you have to create new UIFont object with new values for axes\nlet uiFontDescriptor = UIFontDescriptor(fontAttributes: [.name: uiFont.fontName, kCTFontVariationAttribute as UIFontDescriptor.AttributeName: variations])\nlet newUIFont = UIFont(descriptor: uiFontDescriptor, size: uiFont.pointSize) \n// Now, you can apply the UIFont object for UI text elements\n// Here you may notice the name of the new UIFont object has been changed to 'MartianMono-Regular_wght2580000_wdth640000'\nlet label = UILabel()\nlabel.font = newUIFont\n```\nIf you want to continue changing the current font object, or if you'd like to create more complex logic, you need to store the `UIFont` object. Moreover, you should parse the variation axes values and store these, too. But don't worry, `VFont` will do this for you!\n\n### VFont library\n#### UIKit\n```swift\nimport VFont\n\nlet vFont = VFont(name: \"Martian Mono\", size: 16)! // UIFont like initialization\nvFont.setValue(400, forAxisID: 2003265652) // setting a new value for the 'Weight' axis\n\nlet label = UILabel()\nlabel.font = vFont.uiFont // apply the variable font for a UI text element\n```\n```swift\nvFont.getAxesDescription() // get the font information with а human readable format, if you need it ✅\n\n// override the `updated` closure to observe all font changes, if you're going to change it at runtime\nvFont.updated = { uiFont in\n    label.font = uiFont\n}\n```\n#### SwiftUI\n```swift\nstruct ContentView: View {\n\n    var body: some View {\n       Text(\"Title 1\")\n          .font(.vFont(\"Martian Mono\", size: 16, axisID: 2003265652, value: 450))\n       Text(\"Title 2\")\n           .font(.vFont(\"Inter\", size: 32, axes: [2003072104: 80, 2003265652: 490])\n    }\n    \n}\n```\n\u003e Why do we use number IDs instead of axis names? Good question! But the answer is really simple. The `CTFont` framework which works with variable fonts under the hood returns different axis names for different system languages. This means that only the axis number IDs are unique values. If you find a way of receiving English names regardless of system language, I would appreciate knowing about this!\n\n## Installation\n### Swift Package Manager\n\n- `File` \u003e `Swift Packages` \u003e `Add Package Dependency`\n- Search `https://github.com/dufflink/vfont`\n- Select `Up to Next Major` with `0.6.1`\n\n### Cocoapods\n\nTo integrate `VFont` to your Xcode project using CocoaPods, specify it in your `Podfile`:\n\n```ruby\npod 'VFont'\n```\n\n## Advanced usage\nIf you use `UIKit`, you can create your own font class inheriting the `VFont` class!\n\n### UIKit\n```swift\nimport VFont\n\nfinal class MartianMono: VFont {\n    \n    init?(size: CGFloat) {\n        super.init(name: \"Martian Mono\", size: size)\n    }\n    \n    var weight: CGFloat {\n        get {\n            return axes[2003265652]?.value ?? .zero\n        } set {\n            setValue(newValue, axisID: 2003265652)\n        }\n    }\n    \n    var width: CGFloat {\n        get {\n            return axes[2003072104]?.value ?? .zero\n        } set {\n            setValue(newValue, axisID: 2003072104)\n        }\n    }\n    \n}\n```\n```swift\nlet font = MartianMono(size: 16)\n        \nfont?.weight = 300\nfont?.width = 90\n```\n### SwiftUI\nIn a `SwiftUI` project you can create `static method` as a `Font` structure extension:\n```swift\nextension Font {\n    \n    static func martianMono(size: CGFloat, width: CGFloat = 0, weight: CGFloat = 0) -\u003e Font {\n        return .vFont(\"Martian Mono\", size: size, axes: [\n            2003072104: width,\n            2003265652: weight\n        ])\n    }\n    \n}\n```\n```swift\nstruct ContentView: View {\n    \n    var body: some View {\n        Text(\"Hello, world!\")\n            .font(.martianMono(size: 16, width: 300, weight: 100))\n    }\n    \n}\n```\n## Examples\nMove on to [Examples](https://github.com/dufflink/vfont/tree/master/Example) and research how does it work! Also, you can lanch the examples in Xcode. To complete this, clone the repository and launch the `VFont.xcworkspace` file.\n\nhttps://user-images.githubusercontent.com/29461219/167891461-f3c9a035-9d36-4e93-8a47-0a02ed1b0007.mp4\n\n## Roadmap\n- The next step is creating a script that will parse the `Info.plist` file and which will automatically generate the font classes for UIKit and the extensions for SwiftUI. The generated code will have the same structure as in the [Font class](https://github.com/dufflink/vfont/edit/master/README.md#font-class) section abowe.\n\n- Support for tvOS, watchOS, and macOS\n\n## License\nVFont is released under the MIT license. [See LICENSE](https://github.com/dufflink/vfont/blob/master/LICENSE.md) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdufflink%2Fvfont","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdufflink%2Fvfont","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdufflink%2Fvfont/lists"}