Last active
March 26, 2022 03:24
-
-
Save JadenGeller/101909ddc62729d43f7a to your computer and use it in GitHub Desktop.
Interpolated Attributed String Builder
This file contains 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
// Example | |
var brown: AttributedStringSegment = "brown" | |
brown.foregroundColor = UIColor.brownColor() | |
brown.expansion = 1.1 | |
var lazy: AttributedStringSegment = "lazy" | |
lazy.strikethroughStyle = NSUnderlineStyle.StyleDouble | |
lazy.strikethroughColor = UIColor.redColor() | |
let fox = UIImage(named: "fox.jpg")! | |
let text = attributedString("The quick \(brown) \(fox) jumped over the \(lazy) dog.") | |
// AND WE GET SOMETHING LIKE THIS! | |
// https://twitter.com/JadenGeller/status/614286532875194368 | |
func attributedString(builder: AttributedStringBuilder) -> NSAttributedString { | |
return builder.attributedString | |
} | |
struct AttributedStringBuilder : StringInterpolationConvertible, StringLiteralConvertible { | |
private let attributedString: NSAttributedString | |
init(stringInterpolation strings: AttributedStringBuilder...) { | |
let builder = NSMutableAttributedString() | |
for string in strings { | |
builder.appendAttributedString(string.attributedString) | |
} | |
self.attributedString = NSAttributedString(attributedString: builder) | |
} | |
init<T>(stringInterpolationSegment expr: T) { | |
attributedString = "\(expr)".attributedStringRepresentation | |
} | |
init<T : AttributedStringConvertible>(stringInterpolationSegment expr: T) { | |
attributedString = expr.attributedStringRepresentation | |
} | |
init(string: String) { | |
attributedString = NSAttributedString(string: string) | |
} | |
init(stringLiteral value: String) { | |
attributedString = NSAttributedString(string: value) | |
} | |
init(extendedGraphemeClusterLiteral value: String) { | |
attributedString = NSAttributedString(string: value) | |
} | |
init(unicodeScalarLiteral value: String) { | |
attributedString = NSAttributedString(string: value) | |
} | |
} | |
protocol AttributedStringConvertible { | |
var attributedStringRepresentation: NSAttributedString { get } | |
} | |
extension NSAttributedString { | |
var attributedStringRepresentation: NSAttributedString { | |
get { | |
return self | |
} | |
} | |
} | |
struct AttributedStringSegment : AttributedStringConvertible, StringLiteralConvertible { | |
let text: String | |
init(_ text: String) { | |
self.text = text | |
} | |
init(stringLiteral value: String) { | |
text = value | |
} | |
init(extendedGraphemeClusterLiteral value: String) { | |
text = value | |
} | |
init(unicodeScalarLiteral value: String) { | |
text = value | |
} | |
var font: UIFont! | |
var paragraphStyle: NSParagraphStyle! | |
var foregroundColor: UIColor! | |
var backgroundColor: UIColor! | |
var kern: Float! | |
var strikethroughStyle: NSUnderlineStyle! | |
var underlineStyle: NSUnderlineStyle! | |
var strokeColor: UIColor! | |
var strokeWidth: Float! | |
var shadow: NSShadow! | |
var link: NSURL! | |
var baselineOffset: Float! | |
var underlineColor: UIColor! | |
var strikethroughColor: UIColor! | |
var obliqueness: Float! | |
var expansion: Float! | |
var writingDirection: [NSWritingDirection]! | |
var vertical: Bool! | |
var attributedStringRepresentation: NSAttributedString { | |
get { | |
var attributes = [String : NSObject]() | |
if let font = font { | |
attributes[NSFontAttributeName] = font | |
} | |
if let paragraphStyle = paragraphStyle { | |
attributes[NSParagraphStyleAttributeName] = paragraphStyle | |
} | |
if let foregroundColor = foregroundColor { | |
attributes[NSForegroundColorAttributeName] = foregroundColor | |
} | |
if let backgroundColor = backgroundColor { | |
attributes[NSBackgroundColorAttributeName] = backgroundColor | |
} | |
if let kern = kern { | |
attributes[NSKernAttributeName] = kern | |
} | |
if let strikethroughStyle = strikethroughStyle { | |
attributes[NSStrikethroughStyleAttributeName] = strikethroughStyle.rawValue | |
} | |
if let underlineStyle = underlineStyle { | |
attributes[NSUnderlineStyleAttributeName] = underlineStyle.rawValue | |
} | |
if let strokeColor = strokeColor { | |
attributes[NSStrokeColorAttributeName] = strokeColor | |
} | |
if let strokeWidth = strokeWidth { | |
attributes[NSStrokeWidthAttributeName] = strokeWidth | |
} | |
if let shadow = shadow { | |
attributes[NSShadowAttributeName] = shadow | |
} | |
if let link = link { | |
attributes[NSLinkAttributeName] = link | |
} | |
if let baselineOffset = baselineOffset { | |
attributes[NSBaselineOffsetAttributeName] = baselineOffset | |
} | |
if let underlineColor = underlineColor { | |
attributes[NSUnderlineColorAttributeName] = underlineColor | |
} | |
if let strikethroughColor = strikethroughColor { | |
attributes[NSStrikethroughColorAttributeName] = strikethroughColor | |
} | |
if let obliqueness = obliqueness { | |
attributes[NSObliquenessAttributeName] = obliqueness | |
} | |
if let expansion = expansion { | |
attributes[NSExpansionAttributeName] = expansion | |
} | |
if let writingDirection = writingDirection { | |
attributes[NSWritingDirectionAttributeName] = writingDirection.map { $0.rawValue } | |
} | |
if let vertical = vertical { | |
attributes[NSVerticalGlyphFormAttributeName] = vertical ? 1 : 0 | |
} | |
return NSAttributedString(string: text, attributes: attributes) | |
} | |
} | |
} | |
extension NSURL : AttributedStringConvertible { | |
var attributedStringRepresentation: NSAttributedString { | |
get { | |
var segment = AttributedStringSegment(absoluteString) | |
segment.link = self | |
return segment.attributedStringRepresentation | |
} | |
} | |
} | |
extension String : AttributedStringConvertible { | |
var attributedStringRepresentation: NSAttributedString { | |
get { | |
return NSAttributedString(string: self) | |
} | |
} | |
} | |
extension NSTextAttachment { | |
var attributedStringRepresentation: NSAttributedString { | |
get { | |
return NSAttributedString(attachment: self) | |
} | |
} | |
} | |
extension UIImage : AttributedStringConvertible { | |
var attributedStringRepresentation: NSAttributedString { | |
get { | |
let attachment = NSTextAttachment() | |
attachment.image = self | |
return attachment.attributedStringRepresentation | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment