{"id":21412633,"url":"https://github.com/wibosco/ghosttypewriter","last_synced_at":"2025-04-08T03:11:22.413Z","repository":{"id":14695072,"uuid":"76878830","full_name":"wibosco/GhostTypewriter","owner":"wibosco","description":"👻  A UILabel subclass that adds a typewriting animation effect","archived":false,"fork":false,"pushed_at":"2023-03-17T05:28:44.000Z","size":742,"stargazers_count":220,"open_issues_count":7,"forks_count":20,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-09-19T17:32:01.428Z","etag":null,"topics":["animation","cocoapod","ios","storyboard","swift","typing","uilabel"],"latest_commit_sha":null,"homepage":"http://williamboles.com/","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/wibosco.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,"governance":null}},"created_at":"2016-12-19T16:36:35.000Z","updated_at":"2024-09-10T05:55:55.000Z","dependencies_parsed_at":"2023-07-14T10:31:34.356Z","dependency_job_id":null,"html_url":"https://github.com/wibosco/GhostTypewriter","commit_stats":{"total_commits":91,"total_committers":6,"mean_commits":"15.166666666666666","dds":"0.29670329670329665","last_synced_commit":"479f5c30f343a1ea1adb4befd762f11116ae1b48"},"previous_names":["wibosco/typewritinglabel"],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wibosco%2FGhostTypewriter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wibosco%2FGhostTypewriter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wibosco%2FGhostTypewriter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wibosco%2FGhostTypewriter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wibosco","download_url":"https://codeload.github.com/wibosco/GhostTypewriter/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247767236,"owners_count":20992548,"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":["animation","cocoapod","ios","storyboard","swift","typing","uilabel"],"created_at":"2024-11-22T18:14:50.012Z","updated_at":"2025-04-08T03:11:22.382Z","avatar_url":"https://github.com/wibosco.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://github.com/wibosco/GhostTypewriter/actions/workflows/workflow.yml/badge.svg)](https://github.com/wibosco/GhostTypewriter/actions/workflows/workflow.yml)\n[![Swift](https://img.shields.io/badge/Swift-5-orange.svg?style=flat)](https://swift.org)\n[![License](http://img.shields.io/badge/License-MIT-green.svg?style=flat)](https://github.com/wibosco/GhostTypewriter/blob/main/LICENSE)\n[![Platform](https://img.shields.io/badge/Platform-iOS-lightgrey?style=flat)](https://github.com/wibosco/GhostTypewriter)\n[![Twitter](https://img.shields.io/badge/Twitter-@wibosco-blue.svg?style=flat)](https://twitter.com/wibosco)\n\nA `UILabel` subclass that adds a typewriting animation effect - as if a 👻 was typing it directly on your user's device!\n\n`GhostTypewriter` was inspired by the following post [here](https://williamboles.com/ghost-typing-your-way-to-hollywood/).\n\n## Installation\n\n### [CocoaPods](https://cocoapods.org/)\n\nTo integrate `GhostTypewriter` into your Xcode project using CocoaPods, specify it in your `Podfile`:\n\n```ruby\nsource 'https://github.com/CocoaPods/Specs.git'\nplatform :ios, '10.0'\n\npod 'GhostTypewriter'\n```\n\nThen, run the following command:\n\n```bash\n$ pod install\n```\n\n\u003e CocoaPods 1.1.1+ is required to build `GhostTypewriter`.\n\n### [Swift Package Manager](https://swift.org/package-manager/)\n\nSwift Package Manager is a dependency manager built into Xcode.\n\nIf you are using Xcode 11 or higher, go to `File -\u003e Add Packages...` and enter package repository URL https://github.com/wibosco/GhostTypewriter into the search bar, then follow the instructions.\n\n## Usage\n\n![Animated Typing](typingAnimation.gif)\n\n`TypewriterLabel` is a subclass of `UILabel` and where the animation (magic) happens. It works by taking advantage of the `attributedText` property on the label and changing the properties of the text content to gradually expose the text using an animation similar to what you get on a mechanical typewriter.\n\nA `TypewriterLabel` instance when added as a subview will hide it's content.\n\n#### Starting\n\nStarting the animation will cause the content of the label to be reveal one character at a time.\n\n\u003e How quickly each character is revealed is controlled by setting the `typingTimeInterval` property.\n\nThere are two ways to start an animation: with and without a completion closure.\n\nWith a completion closure:\n\n```swift\nimport GhostTypewriter\n\n@IBAction func startAnimationButtonPressed(_ sender: Any) {\n    titleLabel.startTypewritingAnimation {\n        //Implement your completion closure body here...\n    }\n}\n```\n\nWithout a completion closure:\n\n```swift\nimport GhostTypewriter\n\n@IBAction func startAnimationButtonPressed(_ sender: Any) {\n    titleLabel.startTypewritingAnimation()\n}\n```\n\n#### Stopping\n\nStopping an animation causes the characters that have been revealed to remain as is and no new characters being revealed.\n\n```swift\nimport GhostTypewriter\n\n@IBAction func stopAnimationButtonPressed(_ sender: Any) {\n    titleLabel.stopTypewritingAnimation()\n}\n```\n\n#### Resetting\n\nResetting an animation causes all characters to be hidden.\n\n```swift\nimport GhostTypewriter\n\n@IBAction func resetAnimationButtonPressed(_ sender: Any) {\n    titleLabel.resetTypewritingAnimation()\n}\n```\n\nIt's important to note that resetting an `TypewriterLabel` instance does not cause the animation to restart instead you need to call `restartTypewritingAnimation()`.\n\n#### Restarting\n\nRestarting an animation causes all characters to be hidden and for the animation to begin from the start again.\n\nThere are two ways to start an animation: with and without a completion closure.\n\nWithout a completion closure:\n\n```swift\nimport GhostTypewriter\n\n@IBAction func restartAnimationButtonPressed(_ sender: Any) {\n    titleLabel.restartTypewritingAnimation()\n}\n```\n\nWith a completion closure:\n\n```swift\nimport GhostTypewriter\n\n@IBAction func restartAnimationButtonPressed(_ sender: Any) {\n    titleLabel.restartTypewritingAnimation {\n        //Implement your completion closure body here...\n    }\n}\n```\n\n#### Completing\n\nCompleting an animation causes all characters to instantly be revealed.\n\n```swift\nimport GhostTypewriter\n\n@IBAction func completeAnimationButtonPressed(_ sender: Any) {\n    titleLabel.completeTypewritingAnimation()\n}\n```\n\n#### Animation Options\n\n##### Style\n\nBy default `TypewriterLabel` reveals the content as it animates however this can be changed to hiding the content by setting the `animationStyle` property to `.hide`:\n\n```swift\nimport GhostTypewriter\n\noverride func viewDidLoad() {\n    super.viewDidLoad()\n\n    titleLabel.animationStyle = .hide\n}\n```\n\n\u003e `animationStyle` is defaulted to `.reveal`\n\n##### Direction\n\nBy default `TypewriterLabel` animates from character index `0` to `n-1` however this can be changed to go from charcter index `n-1` to `0` by setting the `animationDirection` to `.backward`:\n\n```swift\nimport GhostTypewriter\n\noverride func viewDidLoad() {\n    super.viewDidLoad()\n\n    titleLabel.animationDirection = .backward\n}\n```\n\n\u003e `animationDirection` is defaulted to `.forward`.\n\n#### Adjusting Animation Timing\n\nEach character of a `TypewriterLabel` instance is revealed at a pace set by the `typingTimeInterval` property.\n\n`typingTimeInterval` defaults to `0.1` second.\n\n```swift\nimport GhostTypewriter\n\noverride func viewDidLoad() {\n    super.viewDidLoad()\n\n    titleLabel.typingTimeInterval = 0.3\n}\n```\n\nIt's important to note that setting/changing `typingTimeInterval` after an animation has been started, has no affect on the timing of that animation.\n\n#### Storyboards\n\nAs `TypewriterLabel` is contained in a pod, when using it with storyboards you will need to set the `Module` field to `GhostTypewriter`.\n\n## Migrating from v1 to v2\n\nVersion [`2.0.0`](https://github.com/wibosco/GhostTypewriter/releases/tag/2.0.0) of `GhostTypewriter` contains breaking changes.\n\n* `cancelTypewritingAnimation()` now use `resetTypewritingAnimation()`.\n* `cancelTypewritingAnimation(clearText: true)` now use `resetTypewritingAnimation()`.\n* `cancelTypewritingAnimation(clearText: false)` now use `stopTypewritingAnimation()`.\n\n## Example\n\n\u003e `GhostTypewriter` comes with an [example project](https://github.com/wibosco/GhostTypewriter/tree/master/Example) to provide more details than listed above.\n\n## Found an issue?\n\nPlease open a [new Issue here](https://github.com/wibosco/GhostTypewriterLabel/issues/new) if you run into a problem specific to GhostTypewriterLabel, have a feature request, or want to share a comment.\n\nPull requests are encouraged and greatly appreciated! Please try to maintain consistency with the existing code style. If you're considering taking on significant changes or additions to the project, please communicate in advance by opening a new Issue. This allows everyone to get onboard with upcoming changes, ensures that changes align with the project's design philosophy, and avoids duplicated work.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwibosco%2Fghosttypewriter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwibosco%2Fghosttypewriter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwibosco%2Fghosttypewriter/lists"}