{"id":20087976,"url":"https://github.com/lixiang1994/attributedstring","last_synced_at":"2025-04-06T18:13:15.202Z","repository":{"id":37385151,"uuid":"222348136","full_name":"lixiang1994/AttributedString","owner":"lixiang1994","description":"基于Swift插值方式优雅的构建富文本, 支持点击长按事件, 支持不同类型过滤, 支持自定义视图等.","archived":false,"fork":false,"pushed_at":"2024-09-19T08:04:50.000Z","size":10421,"stargazers_count":880,"open_issues_count":18,"forks_count":79,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-03-30T17:08:05.244Z","etag":null,"topics":["app","apple","attributedstring","attributes","click","cocoapods","ios","label","macos","nsattributedstring","paragraph","regex","rich-text","string","swift","swift5","text","textview","tvos","watchos"],"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/lixiang1994.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":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-11-18T02:35:35.000Z","updated_at":"2025-03-27T06:29:02.000Z","dependencies_parsed_at":"2024-04-17T09:48:20.917Z","dependency_job_id":"10760d41-b660-4fc1-83aa-4f01d290b3d3","html_url":"https://github.com/lixiang1994/AttributedString","commit_stats":{"total_commits":202,"total_committers":2,"mean_commits":101.0,"dds":0.01980198019801982,"last_synced_commit":"f3a2b4d4805bc96df0f11061e5b33fefb3a337c6"},"previous_names":[],"tags_count":44,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lixiang1994%2FAttributedString","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lixiang1994%2FAttributedString/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lixiang1994%2FAttributedString/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lixiang1994%2FAttributedString/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lixiang1994","download_url":"https://codeload.github.com/lixiang1994/AttributedString/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247526753,"owners_count":20953143,"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":["app","apple","attributedstring","attributes","click","cocoapods","ios","label","macos","nsattributedstring","paragraph","regex","rich-text","string","swift","swift5","text","textview","tvos","watchos"],"created_at":"2024-11-13T16:10:57.221Z","updated_at":"2025-04-06T18:13:15.181Z","avatar_url":"https://github.com/lixiang1994.png","language":"Swift","readme":"![Logo](Resources/logo.png)\n\n# AttributedString - 基于Swift插值方式优雅的构建富文本\n\n[![License](https://img.shields.io/cocoapods/l/AttributedString.svg)](LICENSE)\u0026nbsp;\n![Swift](https://img.shields.io/badge/Swift-5.2-orange.svg)\u0026nbsp;\n![Platform](https://img.shields.io/cocoapods/p/AttributedString.svg?style=flat)\u0026nbsp;\n[![Swift Package Manager](https://img.shields.io/badge/Swift_Package_Manager-compatible-4BC51D.svg?style=flat\")](https://swift.org/package-manager/)\u0026nbsp;\n[![Carthage](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\u0026nbsp;\n[![Cocoapods](https://img.shields.io/cocoapods/v/AttributedString.svg)](https://cocoapods.org)\n\n## [🇨🇳天朝子民](README_CN.md)\n\n## Features\n\n- [x] Constructing rich text using interpolation, Smooth coding, Elegant and natural style.\n- [x] More control extension support.\n- [x] Support for multi-level rich text cascading and provide other style priority strategies.\n- [x] Support for all `NSAttributedString.Key` functions.\n- [x] Support iOS \u0026 macOS \u0026 watchOS \u0026 tvOS.\n- [x] Support text and attachment click or press event callback, support highlight style.\n- [x] Support async image attachment, you can load remote image to `UITextView`.\n- [x] Support view attachment, you can add custom view to `UITextView`.\n- [x] Continue to add more new features.\n\n## Screenshot\n\n\u003cimg src=\"Resources/simple.png\" alt=\"Simple\" width=\"80%\" /\u003e\n\n\u003cimg src=\"Resources/coding.gif\" alt=\"Coding\" width=\"80%\" /\u003e\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"Resources/all.png\" alt=\"All\" width=\"40%\" /\u003e\n\u003cimg src=\"Resources/font.png\" alt=\"Font\" width=\"40%\" /\u003e\n\u003c/div\u003e\n\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"Resources/kern.png\" alt=\"Kern\" width=\"40%\" /\u003e\n\u003cimg src=\"Resources/stroke.png\" alt=\"Stroke\" width=\"40%\" /\u003e\n\u003c/div\u003e\n\n\n## Installation\n\n#### CocoaPods - Podfile\n\n```ruby\npod 'AttributedString'\n```\n\n#### Carthage - Cartfile\n\n```ruby\ngithub \"lixiang1994/AttributedString\"\n```\n\n#### [Swift Package Manager for Apple platforms](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app)\n\nSelect Xcode menu `File \u003e Swift Packages \u003e Add Package Dependency` and enter repository URL with GUI.  \n```\nRepository: https://github.com/lixiang1994/AttributedString\n```\n\n#### [Swift Package Manager](https://swift.org/package-manager/)\n\nAdd the following to the dependencies of your `Package.swift`:\n```swift\n.package(url: \"https://github.com/lixiang1994/AttributedString.git\", from: \"version\")\n```\n\n\n## Usage\n\nFirst make sure to import the framework:\n\n```swift\nimport AttributedString\n```\n\n\n\nHow to initialize:\n\n```swift\n// Normal\nlet a: ASAttributedString = .init(\"lee\", .font(.systemFont(ofSize: 13)))\n// Interpolation\nlet b: ASAttributedString = \"\\(\"lee\", .font(.systemFont(ofSize: 13)))\"\n```\n\n\n\nHere are some usage examples. All devices are also available as simulators:\n\n\n#### Font:\n\n```swift\ntextView.attributed.text = \"\"\"\n\n\\(\"fontSize: 13\", .font(.systemFont(ofSize: 13)))\n\n\\(\"fontSize: 20\", .font(.systemFont(ofSize: 20)))\n\n\\(\"fontSize: 22 weight: semibold\", .font(.systemFont(ofSize: 22, weight: .semibold)))\n\n\"\"\"\n```\n\n#### ForegroundColor:\n\n```swift\ntextView.attributed.text = \"\"\"\n\n\\(\"foregroundColor\", .foreground(.white))\n\n\\(\"foregroundColor\", .foreground(.red))\n\n\"\"\"\n```\n\n#### Strikethrough: \n\n```swift\ntextView.attributed.text = \"\"\"\n\n\\(\"strikethrough: single\", .strikethrough(.single))\n\n\\(\"strikethrough: double color: .red\", .strikethrough(.double, color: .red))\n\n\"\"\"\n```\n\n#### Attachment: (Does not include watchOS)\n\n```swift\n// ASAttributedString.Attachment\n\ntextView.attributed.text = \"\"\"\n\n\\(.data(xxxx, type: \"zip\"))\n\n\\(.file(try!.init(url: .init(fileURLWithPath: \"xxxxx\"), options: [])))\n\n\\(.attachment(NSTextAttachment()))\n\n\"\"\"\n```\n\n#### Attachment Image: (Does not include watchOS)\n\n```swift\n// ASAttributedString.ImageAttachment\n\ntextView.attributed.text = \"\"\"\n\n\\(.image(UIImage(named: \"xxxx\")))\n\n\\(.image(UIImage(named: \"xxxx\"), .custom(size: .init(width: 200, height: 200))))\n\n\\(.image(UIImage(named: \"xxxx\"), .proposed(.center))).\n\n\"\"\"\n```\n\n#### Attachment Async Image: (Only supports iOS: UITextView)\n\n```swift\n// ASAttributedString.AsyncImageAttachment\n\ntextView.attributed.text = \"\"\"\n\n\\(.image(url, placeholder: xxxxx))\n\n\"\"\"\n```\n\nCustom loader:\n\n```swift\nASAttributedString.AsyncImageAttachment.Loader = AsyncImageAttachmentKingfisherLoader.self\n```\n\nPlease read the demo `AttachmentViewController.swift` file for details.\n\n\n#### Attachment View: (Only supports iOS: UITextView)\n\n```swift\n// ASAttributedString.ViewAttachment\n\ntextView.attributed.text = \"\"\"\n\n\\(.view(xxxxView))\n\n\\(.view(xxxxView, .custom(size: .init(width: 200, height: 200))))\n\n\\(.view(xxxxView, .proposed(.center))).\n\n\"\"\"\n```\n\n#### Wrap:\n\n```swift\nlet a: ASAttributedString = .init(\"123\", .background(.blue))\nlet b: ASAttributedString = .init(\"456\", .background(.red))\ntextView.attributed.text = \"\\(wrap: a) \\(wrap: b, .paragraph(.alignment(.center)))\"\n\n// Defalut embedding mode, Nested internal styles take precedence over external styles\ntextView.attributed.text = \"\\(wrap: a, .paragraph(.alignment(.center)))\"\ntextView.attributed.text = \"\\(wrap: .embedding(a), .paragraph(.alignment(.center)))\"\n// Override mode, Nested outer style takes precedence over inner style\ntextView.attributed.text = \"\\(wrap: .override(a), .paragraph(.alignment(.center)))\"\n```\n\n#### Append:\n\n```swift\nlet a: ASAttributedString = .init(\"123\", .background(.blue))\nlet b: ASAttributedString = .init(\"456\", .background(.red))\nlet c: ASAttributedString = .init(\"789\", .background(.gray))\ntextView.attributed.text = a + b\ntextView.attributed.text += c\n```\n\n#### Checking:\n\n```swift\nvar string: ASAttributedString = .init(\"my phone number is +86 18611401994.\", .background(.blue))\nstring.add(attributes: [.foreground(color)], checkings: [.phoneNumber])\ntextView.attributed.text = string\n```\n\n```swift\nvar string: ASAttributedString = .init(\"open https://www.apple.com and https://github.com/lixiang1994/AttributedString\", .background(.blue))\nstring.add(attributes: [.foreground(color)], checkings: [.link])\ntextView.attributed.text = string\n```\n\n```swift\nvar string: ASAttributedString = .init(\"123456789\", .background(.blue))\nstring.add(attributes: [.foreground(color)], checkings: [.regex(\"[0-6]\")])\ntextView.attributed.text = string\n```\n\n\n#### Action: (Only supports iOS: UILabel / UITextView \u0026 macOS: NSTextField)\n\nFor complex styles, it is recommended to use UITextView.\n\nUITextview needs to set `isEditable` and `isSelectable` to `false`.\n\n##### Click:\t\n\n```swift\n// Text\nlet a: ASAttributedString = .init(\"lee\", .action({  }))\n// Attachment (image)\nlet b: ASAttributedString = .init(.image(image), action: {\n    // code\n})\n\n// It is recommended to use functions as parameters.\nfunc clicked() {\n    // code\n}\n// Normal\nlet c: ASAttributedString = .init(\"lee\", .action(clicked))\nlet d: ASAttributedString = .init(.image(image), action: clicked)\n// Interpolation\nlet e: ASAttributedString = \"\\(\"lee\", .action(clicked))\"\nlet f: ASAttributedString = \"\\(.image(image), action: clicked)\"\n\n// More information. \nfunc clicked(_ result: ASAttributedString.Action.Result) {\n    switch result.content {\n    case .string(let value):\n       \tprint(\"Currently clicked text: \\(value) range: \\(result.range)\")\n\t\t\t\t\n    case .attachment(let value):\n        print(\"Currently clicked attachment: \\(value) range: \\(result.range)\")\n    }\n}\n\nlabel.attributed.text = \"This is \\(\"Label\", .font(.systemFont(ofSize: 20)), .action(clicked))\"\ntextView.attributed.text = \"This is a picture \\(.image(image, .custom(size: .init(width: 100, height: 100))), action: clicked) Displayed in custom size.\"\n```\n\n##### Press:  \n\n```swift\nfunc pressed(_ result: ASAttributedString.Action.Result) {\n    switch result.content {\n    case .string(let value):\n        print(\"Currently pressed text: \\(value) range: \\(result.range)\")\n                \n    case .attachment(let value):\n        print(\"Currently pressed attachment: \\(value) range: \\(result.range)\")\n    }\n}\n\nlabel.attributed.text = \"This is \\(\"Long Press\", .font(.systemFont(ofSize: 20)), .action(.press, pressed))\"\ntextView.attributed.text = \"This is a picture \\(.image(image, .custom(size: .init(width: 100, height: 100))), trigger: .press, action: pressed) Displayed in custom size.\"\n```\n\n##### Highlight style:    \n\n```swift\nfunc clicked(_ result: ASAttributedString.Action.Result) {\n    switch result.content {\n    case .string(let value):\n        print(\"Currently clicked text: \\(value) range: \\(result.range)\")\n                \n    case .attachment(let value):\n        print(\"Currently clicked attachment: \\(value) range: \\(result.range)\")\n    }\n}\n\nlabel.attributed.text = \"This is \\(\"Label\", .font(.systemFont(ofSize: 20)), .action([.foreground(.blue)], clicked))\"\n```\n\n##### Custom: \n\n```swift\nlet custom = ASAttributedString.Action(.press, highlights: [.background(.blue), .foreground(.white)]) { (result) in\n    switch result.content {\n    case .string(let value):\n        print(\"Currently pressed text: \\(value) range: \\(result.range)\")\n        \n    case .attachment(let value):\n        print(\"Currently pressed attachment: \\(value) range: \\(result.range)\")\n    }\n}\n\nlabel.attributed.text = \"This is \\(\"Custom\", .font(.systemFont(ofSize: 20)), .action(custom))\"\ntextView.attributed.text = \"This is a picture \\(.image(image, .original(.center)), action: custom) Displayed in original size.\"\n```\n\n#### Observe: (Only supports iOS: UILabel / UITextView \u0026 macOS: NSTextField)\n\n```swift\nlabel.attributed.observe([.phoneNumber], highlights: [.foreground(.blue)]) { (result) in\n    print(\"Currently clicked \\(result)\")\n}\n\ntextView.attributed.observe([.link], highlights: [.foreground(.blue)]) { (result) in\n    print(\"Currently clicked \\(result)\")\n}\n```\n\nFor more examples, see the sample application.\n\n\n\n## Properties available via `Attribute` class\n\nThe following properties are available:\n\n| PROPERTY          | TYPE                                 | DESCRIPTION                                                  |\n| ----------------- | ------------------------------------ | ------------------------------------------------------------ |\n| font              | `UIFont`                             | font                                                         |\n| color             | `UIColor`                            | foreground color                                             |\n| background        | `UIColor`                            | background color                                             |\n| paragraph         | `ParagraphStyle`                     | paragraph attributes                                         |\n| ligature          | `Bool`                               | Ligatures cause specific character combinations to be rendered using a single custom glyph that corresponds to those characters |\n| kern              | `CGFloat`                            | kerning                                                      |\n| strikethrough     | `NSUnderlineStyle` . `UIColor`       | strikethrough style and color (if color is nil foreground is used) |\n| underline         | `NSUnderlineStyle` , `UIColor`       | underline style and color (if color is nil foreground is used) |\n| link              | `String` / `URL`                     | URL                                                          |\n| baselineOffset    | `CGFloat`                            | character’s offset from the baseline, in point               |\n| shadow            | `NSShadow`                           | shadow effect of the text                                    |\n| stroke            | `CGFloat`, `UIColor`                 | stroke width and color                                       |\n| textEffect        | `NSAttributedString.TextEffectStyle` | text effect                                                  |\n| obliqueness       | `CGFloat`                            | text obliqueness                                             |\n| expansion         | `CGFloat`                            | expansion / shrink                                           |\n| writingDirection  | `WritingDirection` / `[Int]`         | initial writing direction used to determine the actual writing direction for text |\n| verticalGlyphForm | `Bool`                               | vertical glyph (Currently on iOS, it's always horizontal.)   |\n\n\n## Cases available via `Attribute.Checking` enumerated\n\n| CASE                                 | DESCRIPTION                                         |\n| ------------------------------------ | -------------------------------------------- |\n| `range(NSRange)`                              | custom range                                                         |\n| `regex(String)`                                    | regular expression                                                         |\n| `action`                                                | action                                                                    |\n| `date`                                                   | date (Based on `NSDataDetector`)                         |\n| `link`                                                     | link (Based on `NSDataDetector`)                         |\n| `address`                                             | address (Based on `NSDataDetector`)                         |\n| `phoneNumber`                                  | phone number (Based on `NSDataDetector`)                         |\n| `transitInformation`                            | transit Information (Based on `NSDataDetector`)                         |\n\n\n## Contributing\n\nIf you have the need for a specific feature that you want implemented or if you experienced a bug, please open an issue.\nIf you extended the functionality of AttributedString yourself and want others to use it too, please submit a pull request.\n\n\n## License\n\nAttributedString is under MIT license. See the [LICENSE](LICENSE) file for more info.\n\n\n-----\n\n\u003e ## 欢迎入群交流\n![QQ](https://github.com/lixiang1994/Resources/blob/master/QQClub/QQClub.JPG)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flixiang1994%2Fattributedstring","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flixiang1994%2Fattributedstring","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flixiang1994%2Fattributedstring/lists"}