• Stars
    star
    807
  • Rank 54,612 (Top 2 %)
  • Language
    Swift
  • License
    MIT License
  • Created over 4 years ago
  • Updated about 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

基于Swift插值方式优雅的构建富文本, 支持点击长按事件, 支持不同类型过滤, 支持自定义视图等.

Logo

AttributedString - 基于Swift插值方式优雅的构建富文本

License  Swift  Platform  Swift Package Manager  Carthage  Cocoapods

🇨🇳天朝子民

Features

  • Constructing rich text using interpolation, Smooth coding, Elegant and natural style.
  • More control extension support.
  • Support for multi-level rich text cascading and provide other style priority strategies.
  • Support for all NSAttributedString.Key functions.
  • Support iOS & macOS & watchOS & tvOS.
  • Support text and attachment click or press event callback, support highlight style.
  • Support async image attachment, you can load remote image to UITextView.
  • Support view attachment, you can add custom view to UITextView.
  • Continue to add more new features.

Screenshot

Simple

Coding

All Font
Kern Stroke

Installation

CocoaPods - Podfile

pod 'AttributedString'

Carthage - Cartfile

github "lixiang1994/AttributedString"

Swift Package Manager for Apple platforms

Select Xcode menu File > Swift Packages > Add Package Dependency and enter repository URL with GUI.

Repository: https://github.com/lixiang1994/AttributedString

Swift Package Manager

Add the following to the dependencies of your Package.swift:

.package(url: "https://github.com/lixiang1994/AttributedString.git", from: "version")

Usage

First make sure to import the framework:

import AttributedString

How to initialize:

// Normal
let a: ASAttributedString = .init("lee", .font(.systemFont(ofSize: 13)))
// Interpolation
let b: ASAttributedString = "\("lee", .font(.systemFont(ofSize: 13)))"

Here are some usage examples. All devices are also available as simulators:

Font:

textView.attributed.text = """

\("fontSize: 13", .font(.systemFont(ofSize: 13)))

\("fontSize: 20", .font(.systemFont(ofSize: 20)))

\("fontSize: 22 weight: semibold", .font(.systemFont(ofSize: 22, weight: .semibold)))

"""

ForegroundColor:

textView.attributed.text = """

\("foregroundColor", .foreground(.white))

\("foregroundColor", .foreground(.red))

"""

Strikethrough:

textView.attributed.text = """

\("strikethrough: single", .strikethrough(.single))

\("strikethrough: double color: .red", .strikethrough(.double, color: .red))

"""

Attachment: (Does not include watchOS)

// ASAttributedString.Attachment

textView.attributed.text = """

\(.data(xxxx, type: "zip"))

\(.file(try!.init(url: .init(fileURLWithPath: "xxxxx"), options: [])))

\(.attachment(NSTextAttachment()))

"""

Attachment Image: (Does not include watchOS)

// ASAttributedString.ImageAttachment

textView.attributed.text = """

\(.image(UIImage(named: "xxxx")))

\(.image(UIImage(named: "xxxx"), .custom(size: .init(width: 200, height: 200))))

\(.image(UIImage(named: "xxxx"), .proposed(.center))).

"""

Attachment Async Image: (Only supports iOS: UITextView)

// ASAttributedString.AsyncImageAttachment

textView.attributed.text = """

\(.image(url, placeholder: xxxxx))

"""

Custom loader:

ASAttributedString.AsyncImageAttachment.Loader = AsyncImageAttachmentKingfisherLoader.self

Please read the demo AttachmentViewController.swift file for details.

Attachment View: (Only supports iOS: UITextView)

// ASAttributedString.ViewAttachment

textView.attributed.text = """

\(.view(xxxxView))

\(.view(xxxxView, .custom(size: .init(width: 200, height: 200))))

\(.view(xxxxView, .proposed(.center))).

"""

Wrap:

let a: ASAttributedString = .init("123", .background(.blue))
let b: ASAttributedString = .init("456", .background(.red))
textView.attributed.text = "\(wrap: a) \(wrap: b, .paragraph(.alignment(.center)))"

// Defalut embedding mode, Nested internal styles take precedence over external styles
textView.attributed.text = "\(wrap: a, .paragraph(.alignment(.center)))"
textView.attributed.text = "\(wrap: .embedding(a), .paragraph(.alignment(.center)))"
// Override mode, Nested outer style takes precedence over inner style
textView.attributed.text = "\(wrap: .override(a), .paragraph(.alignment(.center)))"

Append:

let a: ASAttributedString = .init("123", .background(.blue))
let b: ASAttributedString = .init("456", .background(.red))
let c: ASAttributedString = .init("789", .background(.gray))
textView.attributed.text = a + b
textView.attributed.text += c

Checking:

var string: ASAttributedString = .init("my phone number is +86 18611401994.", .background(.blue))
string.add(attributes: [.foreground(color)], checkings: [.phoneNumber])
textView.attributed.text = string
var string: ASAttributedString = .init("open https://www.apple.com and https://github.com/lixiang1994/AttributedString", .background(.blue))
string.add(attributes: [.foreground(color)], checkings: [.link])
textView.attributed.text = string
var string: ASAttributedString = .init("123456789", .background(.blue))
string.add(attributes: [.foreground(color)], checkings: [.regex("[0-6]")])
textView.attributed.text = string

Action: (Only supports iOS: UILabel / UITextView & macOS: NSTextField)

For complex styles, it is recommended to use UITextView.

UITextview needs to set isEditable and isSelectable to false.

Click:
// Text
let a: ASAttributedString = .init("lee", .action({  }))
// Attachment (image)
let b: ASAttributedString = .init(.image(image), action: {
    // code
})

// It is recommended to use functions as parameters.
func clicked() {
    // code
}
// Normal
let c: ASAttributedString = .init("lee", .action(clicked))
let d: ASAttributedString = .init(.image(image), action: clicked)
// Interpolation
let e: ASAttributedString = "\("lee", .action(clicked))"
let f: ASAttributedString = "\(.image(image), action: clicked)"

// More information. 
func clicked(_ result: ASAttributedString.Action.Result) {
    switch result.content {
    case .string(let value):
       	print("Currently clicked text: \(value) range: \(result.range)")
				
    case .attachment(let value):
        print("Currently clicked attachment: \(value) range: \(result.range)")
    }
}

label.attributed.text = "This is \("Label", .font(.systemFont(ofSize: 20)), .action(clicked))"
textView.attributed.text = "This is a picture \(.image(image, .custom(size: .init(width: 100, height: 100))), action: clicked) Displayed in custom size."
Press:
func pressed(_ result: ASAttributedString.Action.Result) {
    switch result.content {
    case .string(let value):
        print("Currently pressed text: \(value) range: \(result.range)")
                
    case .attachment(let value):
        print("Currently pressed attachment: \(value) range: \(result.range)")
    }
}

label.attributed.text = "This is \("Long Press", .font(.systemFont(ofSize: 20)), .action(.press, pressed))"
textView.attributed.text = "This is a picture \(.image(image, .custom(size: .init(width: 100, height: 100))), trigger: .press, action: pressed) Displayed in custom size."
Highlight style:
func clicked(_ result: ASAttributedString.Action.Result) {
    switch result.content {
    case .string(let value):
        print("Currently clicked text: \(value) range: \(result.range)")
                
    case .attachment(let value):
        print("Currently clicked attachment: \(value) range: \(result.range)")
    }
}

label.attributed.text = "This is \("Label", .font(.systemFont(ofSize: 20)), .action([.foreground(.blue)], clicked))"
Custom:
let custom = ASAttributedString.Action(.press, highlights: [.background(.blue), .foreground(.white)]) { (result) in
    switch result.content {
    case .string(let value):
        print("Currently pressed text: \(value) range: \(result.range)")
        
    case .attachment(let value):
        print("Currently pressed attachment: \(value) range: \(result.range)")
    }
}

label.attributed.text = "This is \("Custom", .font(.systemFont(ofSize: 20)), .action(custom))"
textView.attributed.text = "This is a picture \(.image(image, .original(.center)), action: custom) Displayed in original size."

Observe: (Only supports iOS: UILabel / UITextView & macOS: NSTextField)

label.attributed.observe([.phoneNumber], highlights: [.foreground(.blue)]) { (result) in
    print("Currently clicked \(result)")
}

textView.attributed.observe([.link], highlights: [.foreground(.blue)]) { (result) in
    print("Currently clicked \(result)")
}

For more examples, see the sample application.

Properties available via Attribute class

The following properties are available:

PROPERTY TYPE DESCRIPTION
font UIFont font
color UIColor foreground color
background UIColor background color
paragraph ParagraphStyle paragraph attributes
ligature Bool Ligatures cause specific character combinations to be rendered using a single custom glyph that corresponds to those characters
kern CGFloat kerning
strikethrough NSUnderlineStyle . UIColor strikethrough style and color (if color is nil foreground is used)
underline NSUnderlineStyle , UIColor underline style and color (if color is nil foreground is used)
link String / URL URL
baselineOffset CGFloat character’s offset from the baseline, in point
shadow NSShadow shadow effect of the text
stroke CGFloat, UIColor stroke width and color
textEffect NSAttributedString.TextEffectStyle text effect
obliqueness CGFloat text obliqueness
expansion CGFloat expansion / shrink
writingDirection WritingDirection / [Int] initial writing direction used to determine the actual writing direction for text
verticalGlyphForm Bool vertical glyph (Currently on iOS, it's always horizontal.)

Cases available via Attribute.Checking enumerated

CASE DESCRIPTION
range(NSRange) custom range
regex(String) regular expression
action action
date date (Based on NSDataDetector)
link link (Based on NSDataDetector)
address address (Based on NSDataDetector)
phoneNumber phone number (Based on NSDataDetector)
transitInformation transit Information (Based on NSDataDetector)

Contributing

If you have the need for a specific feature that you want implemented or if you experienced a bug, please open an issue. If you extended the functionality of AttributedString yourself and want others to use it too, please submit a pull request.

License

AttributedString is under MIT license. See the LICENSE file for more info.


欢迎入群交流

QQ

More Repositories

1

LEEAlert

优雅的可自定义 Alert ActionSheet
Objective-C
1,289
star
2

LEETheme

优雅的主题管理库- 一行代码完成多样式切换
Objective-C
817
star
3

AutoInch

优雅的iPhone全尺寸/等比例精准适配工具
Swift
461
star
4

NewsDetailsDemo

资讯详情文章页面Demo 内容部分为HTML数据格式 基于WKWebView加载 原生图片加载方式 (支持GIF图片) 支持持久化缓存等
Objective-C
87
star
5

LEECoolButton

一个炫酷的按钮(适用于喜欢 , 点赞 , 收藏等)
Objective-C
74
star
6

VideoTransitionDemo

视频过渡效果演示
Swift
71
star
7

LEEStarRating

星星评分视图控件 支持整颗 , 半颗 , 无限制评分 可自定义分数范围和星星个数等
Objective-C
60
star
8

UIAdapter

An elegant solution to the iOS screen adaptation problem
Swift
50
star
9

PermissionKit

An elegant permission manager written in swift
Swift
37
star
10

ViewControllerDemo

Swift 泛型 UIViewController的View分离演示
Swift
21
star
11

SKUFilterDemo

SKUFilter 电商Stock Keeping Unit选择过滤器示例
Swift
20
star
12

Router

基于URLNavigator抽象的外部URL路由组件 支持任意类型配置 插件机制
Swift
19
star
13

Loading

An elegant loading view written in swift
Swift
19
star
14

Apis

基于URLNavigator抽象的URL路由组件 灵感来自Moya 配置化 插件化.
Swift
16
star
15

Spring

An elegant animation written in swift
Swift
10
star
16

Guider

An elegant highlight focus guide written in swift
Swift
9
star
17

VideoPlayer

Swift
9
star
18

GearAnimationDemo

齿轮动画Demo
Objective-C
8
star
19

AudioPlayer

Swift
6
star
20

SDKit

简洁、高效的iOS开发“一站式”工具库
Objective-C
6
star
21

Alienware-Aurora-R13-Water-Cooling

外置压缩机水冷改装分享
5
star
22

LEEBubble

一个有趣的小气泡
Objective-C
5
star
23

Scanner

二维码扫描Demo
Swift
4
star
24

AsyncLayer

iOS 异步渲染Layer
Swift
3
star
25

IMInterface

Swift
2
star
26

Specs

CocoaPods PodSpecs
Ruby
2
star
27

VideoClipDemo

视频剪切Demo
Swift
2
star
28

LinearView

Linear layout view based on UIStackView Use chain encapsulation to quickly build vertical or horizontal layout views.
Swift
2
star
29

Resources

1
star
30

LEEResume

简历
JavaScript
1
star
31

Delegates

An elegant multiple delegate written in swift
Swift
1
star
32

ghost-lee-theme

Ghost Blog Themes (LEE)
CSS
1
star
33

QQMusicPlayerDemo

音乐播放器示例Demo 参考QQ音乐
Objective-C
1
star