{"id":13554692,"url":"https://github.com/Mindgrub/Swash","last_synced_at":"2025-04-03T07:32:19.690Z","repository":{"id":44898784,"uuid":"120529014","full_name":"Mindgrub/Swash","owner":"Mindgrub","description":"Fonts in iOS made safe, expressive, and dynamic.","archived":false,"fork":false,"pushed_at":"2022-01-19T22:29:08.000Z","size":553,"stargazers_count":76,"open_issues_count":2,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-03T17:46:00.211Z","etag":null,"topics":["accessibility","carthage","cocoapods","custom-fonts","dynamic","font","fonts","ios","swift","uifont"],"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/Mindgrub.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-02-06T22:05:27.000Z","updated_at":"2024-11-22T17:05:08.000Z","dependencies_parsed_at":"2022-09-24T22:50:35.310Z","dependency_job_id":null,"html_url":"https://github.com/Mindgrub/Swash","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mindgrub%2FSwash","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mindgrub%2FSwash/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mindgrub%2FSwash/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mindgrub%2FSwash/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Mindgrub","download_url":"https://codeload.github.com/Mindgrub/Swash/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246956644,"owners_count":20860471,"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":["accessibility","carthage","cocoapods","custom-fonts","dynamic","font","fonts","ios","swift","uifont"],"created_at":"2024-08-01T12:02:53.003Z","updated_at":"2025-04-03T07:32:19.222Z","avatar_url":"https://github.com/Mindgrub.png","language":"Swift","readme":"# Swash\n\n[![Version](https://img.shields.io/cocoapods/v/Swash.svg?style=flat)](#installation)\n![Swift 5.1](https://img.shields.io/badge/Swift-5.1-orange.svg)\n![Platforms](https://img.shields.io/cocoapods/p/Swash.svg?style=flat)\n[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n[![License](https://img.shields.io/cocoapods/l/Swash.svg?style=flat)](http://doge.mit-license.org)\n\nSwash is a simple, safe, and expressive abstraction of `UIFont` with baked-in support for dynamic type.\n\n## Usage\nTo define a custom font, just create a `String` enum that conforms to the `Font` protocol.\n```swift\nenum Papyrus: String, Font {\n    case regular = \"Papyrus\"\n    case condensed = \"Papyrus-Condensed\"\n}\n```\n\nThat's all you need to start using your font in your project!\n\n### Static Sizes\n```swift\nlabel.font = Papyrus.regular.of(size: 17)\n```\n\n### Dynamic Type (iOS 11+)\nUses [`UIFontMetrics`](https://developer.apple.com/documentation/uikit/uifontmetrics) for scaling. Setting [`adjustsFontForContentSizeCategory`](https://developer.apple.com/documentation/uikit/uicontentsizecategoryadjusting/1771731-adjustsfontforcontentsizecategor) to `true` tells the label to automatically update the font when the user changes their content size preference. See our [blog post](https://blog.mindgrub.com/custom-fonts-in-ios-made-simple-yet-powerful) for guidance on choosing default sizes for text styles, or just use Swash's provided defaults pulled from Apple's Human Interface Guidelines for [iOS](https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/typography/), [watchOS](https://developer.apple.com/design/human-interface-guidelines/watchos/visual-design/typography/), and [tvOS](https://developer.apple.com/design/human-interface-guidelines/tvos/visual-design/typography/).\n```swift\nlabel1.adjustsFontForContentSizeCategory = true\nlabel2.adjustsFontForContentSizeCategory = true\n\nlabel1.font = Papyrus.condensed.of(textStyle: .headline)\n// Optional size cutoff and default size.\nlabel2.font = GillSans.bold.of(textStyle: .title1, defaultSize: 28, maxSize: 38)\n```\n![Dynamic Type Demo](https://raw.githubusercontent.com/Mindgrub/Swash/master/Assets/dynamic_type_demo.gif)\n\n### Dynamic Type (Before iOS 11)\nUses system font scaling, no default size value. [`adjustsFontForContentSizeCategory`](https://developer.apple.com/documentation/uikit/uicontentsizecategoryadjusting/1771731-adjustsfontforcontentsizecategor) requires the use of [`UIFontMetrics`](https://developer.apple.com/documentation/uikit/uifontmetrics), so it is of no use for custom fonts before iOS 11. You'll have to update the fonts manually, either in [`traitCollectionDidChange(_:)`](https://developer.apple.com/documentation/uikit/uitraitenvironment/1623516-traitcollectiondidchange) or by observing the [`UIContentSizeCategoryDidChange`](https://developer.apple.com/documentation/foundation/nsnotification.name/1622948-uicontentsizecategorydidchange) notification.\n```swift\nlabel.font = Papyrus.condensed.of(style: .headline)\n// Optional size cutoff\nlabel.font = GillSans.bold.of(style: .title1, maxSize: 30)\n```\n\n### System Font\nYou can use `SystemFont` to support dynamic type for different weights and further unify the font syntax in your project.\n```swift\nlabel1.font = SystemFont.light.of(size: 17)\nlabel2.adjustsFontForContentSizeCategory = true\nlabel2.font = SystemFont.preferred.of(textStyle: .body)\nlabel3.font = SystemFont.semiboldItalic.of(textStyle: .body, maxSize: 30)\n```\n**Important note:** [`adjustsFontForContentSizeCategory`](https://developer.apple.com/documentation/uikit/uicontentsizecategoryadjusting/1771731-adjustsfontforcontentsizecategor) only works with `SystemFont` for the `preferred` weight with a nil `maxSize` value. In any other case, you will need to update the font either in [`traitCollectionDidChange(_:)`](https://developer.apple.com/documentation/uikit/uitraitenvironment/1623516-traitcollectiondidchange) or by observing the [`UIContentSizeCategoryDidChange`](https://developer.apple.com/documentation/foundation/nsnotification.name/1622948-uicontentsizecategorydidchange) notification. This is because the `preferred` weight directly returns the result of [`UIFont.preferredFont(forTextStyle:)`](https://developer.apple.com/documentation/uikit/uifont/1619030-preferredfont).\n\n### Bold Text Device Setting\nYou can implement the `boldTextMapping` property on any `Font` in order to support the \"Bold Text\" device setting on iOS and tvOS.\n```\nvar boldTextMapping: MyFont {\n    switch self {\n    case .regular: return .bold\n    case .bold: return .black\n    case .black: return self\n    }\n}\n```\nNow every regular `MyFont` instance will become bold if the user has \"Bold Text\" turned on in their device settings.\n\nIf you'd like, you can observe `UIAccessibility.boldTextStatusDidChangeNotification` via `NotificationCenter` and set your fonts when that updates.\n\n### Font Cascading\nYou can implement the static `cascadeList` property on any `Font` in order to support font cascading. In the event that your font does not support a character that is used in a label, this list will provide fallback fonts to use.\n```\nenum Papyrus: String, Font {\n    case condensed = \"Papyrus-Condensed\"\n    case regular = \"Papyrus\"\n    \n    var cascadeList: [CascadingFontProperties] {\n        [.init(Damascus.regular)]\n    }\n}\n```\nPapyrus does not support Arabic characters. So, here we've provided Damascus as a fallback. If no fallback is provided, the system font will be used for unsupported characters.\n\n### Generate Boilerplate\nSwash can attempt to log your font boilerplate for you!\n```swift\nSwash.logBoilerplate(forFontsWithFamilyNamesContaining: \"gill\")\n```\nOutput:\n```\nenum GillSans: String, Font {\n    case GillSans-Italic = \"GillSans-Italic\"\n    case GillSans-SemiBold = \"GillSans-SemiBold\"\n    case GillSans-UltraBold = \"GillSans-UltraBold\"\n    case GillSans-Light = \"GillSans-Light\"\n    case GillSans-Bold = \"GillSans-Bold\"\n    case GillSans = \"GillSans\"\n    case GillSans-SemiBoldItalic = \"GillSans-SemiBoldItalic\"\n    case GillSans-BoldItalic = \"GillSans-BoldItalic\"\n    case GillSans-LightItalic = \"GillSans-LightItalic\"\n}\n```\nJust copy-paste the output into your project. You'll probably still need to doctor the case names a bit.\n\n### Debug Crashing\nIf your custom font fails to initialize, [`assertionFailure(_:file:line:)`](https://developer.apple.com/documentation/swift/1539616-assertionfailure) is called. This will crash debug builds with the default `-Onone` compiler optimization set. This is to help identify failed font initializations which can otherwise be hard to catch. **Release builds with higher optimization levels will NOT crash**, so you don't have to worry about your app crashing in production over a silly font.\n\n## Installation\n\n### CocoaPods\n\n```ruby\npod 'Swash'\n```\n\n### Carthage\n\n```\ngithub \"Mindgrub/Swash\"\n```\nMake sure to specify your platform when you update (e.g. `carthage update --platform iOS`). Otherwise all 3 frameworks (iOS, tvOS, and watchOS) will be added.\n\n## License\n\nSwash is available under the MIT license. See the LICENSE file for more info.\n","funding_links":[],"categories":["Swift"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMindgrub%2FSwash","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FMindgrub%2FSwash","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMindgrub%2FSwash/lists"}