Created
January 22, 2020 06:04
-
-
Save lionhylra/4bade5433ecbdf255e8da63a1f793e24 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
/* Example of how to use it: | |
import UIKit | |
class ViewController: UIViewController { | |
@IBOutlet weak var label: UILabel! | |
@IBOutlet weak var textView: UITextView! | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
let style = NSAttributedStringStyle(font: .preferredFont(forTextStyle: .body)) | |
label.attributedText = .compose( | |
style: style, | |
""" | |
Please go to \(urlString: "https://google.com" ) for more details. \(systemImage: "globe") | |
Also you can go to our \(link: "Website", urlString: "https://google.com"). | |
This is another line. | |
""" | |
) | |
textView.attributedText = .compose( | |
style: style, | |
""" | |
Please go to \(urlString: "https://google.com" ) for more details. \(systemImage: "globe") | |
Also you can go to our \(link: "Website", urlString: "https://google.com"). | |
This is another line. | |
""" | |
) | |
} | |
} | |
*/ | |
struct NSAttributedStringLiteral: ExpressibleByStringLiteral { | |
let value: NSAttributedString | |
init(stringLiteral value: String) { | |
self.value = NSAttributedString(string: value) | |
} | |
} | |
extension NSAttributedStringLiteral: ExpressibleByStringInterpolation { | |
init(stringInterpolation: StringInterpolation) { | |
self.value = stringInterpolation.output | |
} | |
} | |
extension NSAttributedStringLiteral { | |
struct StringInterpolation: StringInterpolationProtocol { | |
var output = NSMutableAttributedString() | |
init(literalCapacity: Int, interpolationCount: Int) { | |
// DO NOTHING | |
// this initializer is required, and can be used as a performance optimization | |
} | |
mutating func appendLiteral(_ literal: String) { | |
output.append(NSAttributedString(string: literal)) | |
} | |
mutating func appendInterpolation(link label: String? = nil, url: URL) { | |
output.append(NSAttributedString(string: label ?? url.absoluteString, attributes: [.link: url])) | |
} | |
mutating func appendInterpolation(link label: String? = nil, urlString: String) { | |
assert(URL(string: urlString) != nil) | |
output.append(NSAttributedString(string: label ?? urlString, attributes: [.link: urlString])) | |
} | |
mutating func appendInterpolation(image: UIImage?, size: CGSize? = nil) { | |
let attachment = NSTextAttachment() | |
attachment.image = image | |
if let size = size { | |
attachment.bounds.size = size | |
} | |
output.append(NSAttributedString(attachment: attachment)) | |
} | |
@available(iOS 13.0, *) | |
mutating func appendInterpolation(systemImage name: String, tintColor: UIColor? = nil) { | |
var image = UIImage(systemName: name) | |
if let tintColor = tintColor { | |
image = image?.withTintColor(tintColor) | |
} | |
appendInterpolation(image: image) | |
} | |
} | |
} | |
struct NSAttributedStringStyle { | |
static let `default` = NSAttributedStringStyle() | |
let font: UIFont? | |
let foregroundColor: UIColor? | |
let alignment: NSTextAlignment? | |
let lineSpacing: CGFloat? | |
let paragraphSpacing: CGFloat? | |
init(font: UIFont? = nil, foregroundColor: UIColor? = nil, alignment: NSTextAlignment? = nil, lineSpacing: CGFloat? = nil, paragraphSpacing: CGFloat? = nil) { | |
self.font = font | |
self.foregroundColor = foregroundColor | |
self.alignment = alignment | |
self.lineSpacing = lineSpacing | |
self.paragraphSpacing = paragraphSpacing | |
} | |
func attributes() -> [NSAttributedString.Key: Any] { | |
var attributes: [NSAttributedString.Key: Any] = [:] | |
attributes[.font] = font | |
attributes[.foregroundColor] = foregroundColor | |
let paragraphStyle = NSMutableParagraphStyle() | |
if let alignment = alignment { | |
paragraphStyle.alignment = alignment | |
} | |
if let lineSpacing = lineSpacing { | |
paragraphStyle.lineSpacing = lineSpacing | |
} | |
if let paragraphSpacing = paragraphSpacing { | |
paragraphStyle.paragraphSpacing = paragraphSpacing | |
} | |
attributes[.paragraphStyle] = paragraphStyle | |
return attributes | |
} | |
} | |
extension NSAttributedString { | |
static func compose(style: NSAttributedStringStyle = .default, _ literal: NSAttributedStringLiteral) -> NSAttributedString { | |
let mutableAttributedString = NSMutableAttributedString(attributedString: literal.value) | |
let range = NSRange(location: 0, length: mutableAttributedString.length) | |
mutableAttributedString.addAttributes(style.attributes(), range: range) | |
return mutableAttributedString | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment