Historically, building rich text in Cocoa has been a tedious task, using NSAttributeString in the Foundation framework, with all the inconsistencies of distinguishing mutable from immutable, passing in a parameter dictionary that requires documentation, and no type checking. The new string interpolation feature in Swift 5 makes it possible to handle custom string literals.
Swift 5 string interpolation
In simple terms, this feature allows developers to implement their own analytic and logical implementations of interpolation in literals. Such as:
let string:CustomString = "\(num: 10)"
Copy the code
This string literal can be handled by implementing a method like func appendInterpolation(num: Int). To achieve this effect, it can be roughly divided into the following steps:
- Custom type and follow
ExpressibleByStringInterpolation
- Nested compliance in type
StringInterpolationProtocol
Interpolation type of - Interpolation types are customized for one to multiple different parameters
func appenInterpolation(...)
Override the method and handle the logic of the corresponding arguments
In this way, string interpolation can theoretically do anything from constructing SQL operations from strings, to regex operations, to generating HTML web pages, and even to some runtime hacks.
Implement AttributeString handling
First custom types, and to realize ExpressibleByStringLiteral support string literals (ExpressibleByStringLiteral ExpressibleByStringLiteral as part of the agreement). So we can build an NSAttributedString with no attributes from string literals.
public struct EasyText {
public let attributedString: NSAttributedString
}
extension EasyText: ExpressibleByStringLiteral {
public init(stringLiteral: String) {
attributedString = NSAttributedString(string: stringLiteral)
}
}
Copy the code
Then realize ExpressibleByStringInterpolation agreement, nested interpolation type, and follow StringInterpolationProtocol. After the interpolation is built, init(stringInterpolation: stringInterpolation) is used to build a custom type. The appendLiteral method is used for interpolation of normal string types.
extension EasyText: ExpressibleByStringInterpolation {
public init(stringInterpolation: StringInterpolation) {
attributedString = NSAttributedString(attributedString: stringInterpolation.rawAttributedString)
}
public struct StringInterpolation:StringInterpolationProtocol {
let rawAttributedString:NSMutableAttributedString
public init(literalCapacity: Int, interpolationCount: Int) {
rawAttributedString = NSMutableAttributedString()}public func appendLiteral(_ literal:String) {
rawAttributedString.append(NSAttributedString(string: literal))
}
}
}
Copy the code
Next implement one to multiple appendInterpolation methods, such as adding NSTextAttachment to interpolation support:
public struct StringInterpolation:StringInterpolationProtocol {
// ...
public func appendInterpolation(attachment:NSTextAttachment) {
rawAttributedString.append(NSAttributedString(attachment: attachment))
}
}
Copy the code
EasyText use
The author supports all attributes in NSAttributedString using string interpolation, and implements a library of several hundred lines. Using this library, you can build NSAttributedString in a simple way:
let text:EasyText = "\("font is 30 pt and color is yellow", .font(.systemFont(ofSize: 20)), .color(.blue))"
textView.attributedText = text.attributedString
Copy the code
It has the following features:
- Type safe, all supported
NSAttributedString.Key
All have type check - Supports multiple platforms, iOS/macOS
- Support most common
NSAttributedString.Key
, there is currently no supported interface to build - Support common operators, such as
+
、+ =
, as well as with other typesString
,NSAttributedString
The operation - Support for inserting images
See the examples for more details.
The last
EasyText is open source and can be integrated through Cocoapods, Cathrage, SwiftPackageManager.
If you think it is helpful, please give a star to encourage you. If you have any questions, please feel free to comment.
Refer to the link
StringInterpolation in Swift 5 — Introduction
StringInterpolation in Swift 5 — AttributedStrings
Fix ExpressibleByStringInterpolation