{"id":24801579,"url":"https://github.com/futuredapp/tfbubbleitup","last_synced_at":"2026-03-07T22:31:43.839Z","repository":{"id":42443274,"uuid":"42400041","full_name":"futuredapp/TFBubbleItUp","owner":"futuredapp","description":"Custom view for writing tags, contacts and etc. - written in Swift","archived":false,"fork":false,"pushed_at":"2022-07-22T08:22:39.000Z","size":327,"stargazers_count":330,"open_issues_count":2,"forks_count":24,"subscribers_count":12,"default_branch":"main","last_synced_at":"2025-12-13T10:15:39.679Z","etag":null,"topics":["control","ios","tags"],"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/futuredapp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null}},"created_at":"2015-09-13T14:59:45.000Z","updated_at":"2025-07-04T17:42:46.000Z","dependencies_parsed_at":"2022-08-20T07:20:18.329Z","dependency_job_id":null,"html_url":"https://github.com/futuredapp/TFBubbleItUp","commit_stats":null,"previous_names":["thefuntasty/tfbubbleitup"],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/futuredapp/TFBubbleItUp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/futuredapp%2FTFBubbleItUp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/futuredapp%2FTFBubbleItUp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/futuredapp%2FTFBubbleItUp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/futuredapp%2FTFBubbleItUp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/futuredapp","download_url":"https://codeload.github.com/futuredapp/TFBubbleItUp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/futuredapp%2FTFBubbleItUp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30234517,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-07T19:01:10.287Z","status":"ssl_error","status_checked_at":"2026-03-07T18:59:58.103Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["control","ios","tags"],"created_at":"2025-01-30T04:29:20.990Z","updated_at":"2026-03-07T22:31:43.802Z","avatar_url":"https://github.com/futuredapp.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg alt=\"TFBubbleItUp logo\" align=\"right\" src=\"Documentation/TFBubbleItUp.svg\"\u003e\n\n# TFBubbleItUp\n\n[![Version](https://img.shields.io/cocoapods/v/TFBubbleItUp.svg?style=flat)](http://cocoapods.org/pods/TFBubbleItUp)\n[![License](https://img.shields.io/cocoapods/l/TFBubbleItUp.svg?style=flat)](http://cocoapods.org/pods/TFBubbleItUp)\n[![Platform](https://img.shields.io/cocoapods/p/TFBubbleItUp.svg?style=flat)](http://cocoapods.org/pods/TFBubbleItUp)\n\n![preview](Documentation/preview.gif)\n\n## Usage\n\nJust place UIView in your controller wherever you want and make it as TFBubbleItUpView subclass. It is configured as IBDesignable, so it will show up. The content size is calculated by the view itself, no need to use height constraint. Just set in the Interface builder Intrinsic size to placeholder - width check None and for height choose what suits you best.\n\n![Intrinsic size](Documentation/intrinsic-size.png)\n\nThere is also a delegate available (named bubbleItUpDelegate, because TFBubbleItUpView is in fact a subclass of UICollectionView) with currently one method **func bubbleItUpViewDidFinishEditingBubble(view: TFBubbleItUpView, text: String)**.\n\nYou can preset values with **setItem([TFBubbleItem])** where TFBubbleItem is a struct whose initializer takes string (*TFBubbleItem(text: \"Hullo!\")*).\n\nIf you want to access all items from view, there is method for that **validStrings() -\u003e [String]**. That's because sometimes there are empty items, this method will filter it for you a send you only valid strings.\n\n## Validation\nAmong all the configuration, there is an ability to validate items before they can be bubbled. There is typealias named Validation which is just a function definition:\n\n```swift\npublic typealias Validation = String -\u003e Bool\n```\n\nVerification function takes a string and returns Bool indicates whether the string is valid or not. These methods should be elementary. There are already two of them available as public classes of TFBubbleItUpValidation - testEmptiness() and testEmailAddress(). These methods returns Validation function and the validation can be called like testEmptiness()(\"a text\"). This technique of translating the evaluation of a function is called [Currying](https://en.wikipedia.org/wiki/Currying). You can provide your own Validation:\n\n```swift\nfunc testSomething() -\u003e Validation {\n  return { text in\n    return text == \"something\"\n  }\n}\n```\n\nThis allows us to easily combine validation by function TFBubbleItUpValidation.combine(v1: Validation, v2: Validation) or even better with provided operator **|\u003e\u003e**\n\n```swift\nlet validation = TFBubbleItUpValidation.testEmptiness() |\u003e\u003e TFBubbleItUpValidation.testEmailAddress()\n```\n\nThe validation can be applied to TFBubbleItUpView via configuration\n\n```swift\nTFBubbleItUpViewConfiguration.itemValidation = validation\n```\n\nAnd we can also validate the maximum number of items user can type in by\n\n```swift\nTFBubbleItUpViewConfiguration.numberOfItems = .Quantity(5) // default .Unlimited\n```\n\n## Configuration\n\nBubbleItUp is highly configurable. There is configuration file called *TFBubbleItUpViewConfiguration* with class variables for configuration.\n\nIt is a mix of appearance and functional stuff. I would like to point out **skipOnWhitespace** and **skipOnReturnKey** properties, by them you can change the behaviour of bubble creation around text (see documentation comments bellow).\n\n```swift\n/// Background color for cell in normal state\npublic static var viewBackgroundColor: UIColor = UIColor(red: 0.918, green: 0.933, blue: 0.949, alpha: 1.00)\n\n/// Background color for cell in edit state\npublic static var editBackgroundColor: UIColor = UIColor.whiteColor()\n\n/// Background color for cell in invalid state\npublic static var invalidBackgroundColor: UIColor = UIColor.whiteColor()\n\n/// Font for cell in normal state\npublic static var viewFont: UIFont = UIFont.systemFontOfSize(12.0)\n\n/// Font for cell in edit state\npublic static var editFont: UIFont = UIFont.systemFontOfSize(12.0)\n\n/// Font for cell in invalid state\npublic static var invalidFont: UIFont = UIFont.systemFontOfSize(12.0)\n\n/// Font color for cell in view state\npublic static var viewFontColor: UIColor = UIColor(red: 0.353, green: 0.388, blue: 0.431, alpha: 1.00)\n\n/// Font color for cell in edit state\npublic static var editFontColor: UIColor = UIColor(red: 0.510, green: 0.553, blue: 0.596, alpha: 1.00)\n\n/// Font color for cell in invalid state\npublic static var invalidFontColor: UIColor = UIColor(red: 0.510, green: 0.553, blue: 0.596, alpha: 1.00)\n\n/// Corner radius for cell in view state\npublic static var viewCornerRadius: Float = 2.0\n\n/// Corner radius for cell in edit state\npublic static var editCornerRadius: Float = 2.0\n\n/// Corner radius for cell in invalid state\npublic static var invalidCornerRadius: Float = 2.0\n\n/// Height for item\npublic static var cellHeight: Float = 25.0\n\n/// View insets\npublic static var inset: UIEdgeInsets = UIEdgeInsetsMake(5, 5, 5, 5)\n\n/// Interitem spacing\npublic static var interitemSpacing: CGFloat = 5.0\n\n/// Line spacing\npublic static var lineSpacing: CGFloat = 5.0\n\n/// Keyboard type\npublic static var keyboardType: UIKeyboardType = UIKeyboardType.EmailAddress\n\n/// Keyboard return key\npublic static var returnKey: UIReturnKeyType = UIReturnKeyType.Done\n\n/// Field auto-capitalization type\npublic static var autoCapitalization: UITextAutocapitalizationType = UITextAutocapitalizationType.None\n\n/// Field auto-correction type\npublic static var autoCorrection: UITextAutocorrectionType = UITextAutocorrectionType.No\n\n/// If true it creates new item when user types whitespace\npublic static var skipOnWhitespace: Bool = true\n\n/// If true it creates new item when user press the keyboards return key. Otherwise resigns first responder\npublic static var skipOnReturnKey: Bool = false\n\n/// Number of items that could be written\npublic static var numberOfItems: NumberOfItems = .Unlimited\n\n/// Item has to pass validation before it can be bubbled\npublic static var itemValidation: Validation? = nil\n```\n\n## Requirements\n\nTFBubbleItUp uses Swift 5.0. Target deployment iOS 10.0 and higher.\n\n## Installation\n\nTFBubbleItUp is available through [CocoaPods](http://cocoapods.org). To install\nit, simply add the following line to your Podfile:\n\n```ruby\npod \"TFBubbleItUp\"\n```\n\n## Author\n\nAles Kocur, aleskocur@icloud.com\n\n## License\n\nTFBubbleItUp is available under the MIT license. See the [LICENSE](LICENSE) file for more info.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffuturedapp%2Ftfbubbleitup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffuturedapp%2Ftfbubbleitup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffuturedapp%2Ftfbubbleitup/lists"}