Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CassiusPacheco/557d04a859266d1d3b6926a243723b76 to your computer and use it in GitHub Desktop.
Save CassiusPacheco/557d04a859266d1d3b6926a243723b76 to your computer and use it in GitHub Desktop.
Extensions to make attributed strings composable
import Foundation
public func + (lhs: NSAttributedString, rhs: NSAttributedString) -> NSMutableAttributedString {
let mutable = NSMutableAttributedString(attributedString: lhs)
mutable.append(rhs)
return mutable
}
extension String {
public var attributedString: NSMutableAttributedString {
return NSMutableAttributedString(string: self)
}
}
extension NSMutableAttributedString {
public var range: NSRange {
return NSRange(location: 0, length: length)
}
@discardableResult
public func add(color: UIColor, to range: NSRange? = nil) -> NSMutableAttributedString {
let textRage = range ?? self.range
guard textRage.length != 0 else { return self }
addAttribute(NSAttributedString.Key.foregroundColor, value: color, range: textRage)
return self
}
@discardableResult
public func add(font: UIFont, to range: NSRange? = nil) -> NSMutableAttributedString {
let textRage = range ?? self.range
guard textRage.length != 0 else { return self }
addAttribute(NSAttributedString.Key.font, value: font, range: textRage)
return self
}
@discardableResult
public func add(paragraph: NSMutableParagraphStyle, to range: NSRange? = nil) -> NSMutableAttributedString {
let textRage = range ?? self.range
guard textRage.length != 0 else { return self }
addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraph, range: textRage)
return self
}
@discardableResult
public func addStrike(to range: NSRange? = nil) -> NSMutableAttributedString {
let textRage = range ?? self.range
guard textRage.length != 0 else { return self }
addAttribute(NSAttributedString.Key.strikethroughStyle, value: NSNumber(value: NSUnderlineStyle.single.rawValue), range: textRage)
return self
}
@discardableResult
public func addUnderline(to range: NSRange? = nil) -> NSMutableAttributedString {
let textRage = range ?? self.range
guard textRage.length != 0 else { return self }
addAttribute(NSAttributedString.Key.underlineStyle, value: NSNumber(value: NSUnderlineStyle.single.rawValue), range: textRage)
return self
}
@discardableResult
public func add(alignment: NSTextAlignment, to range: NSRange? = nil) -> NSMutableAttributedString {
let textRage = range ?? self.range
guard textRage.length != 0 else { return self }
let paragraphStyle = currentParagraphStyle()
paragraphStyle.alignment = alignment
addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: textRage)
return self
}
@discardableResult
public func add(lineSpacing: CGFloat, to range: NSRange? = nil) -> NSMutableAttributedString {
let textRage = range ?? self.range
guard textRage.length != 0 else { return self }
let paragraphStyle = currentParagraphStyle()
paragraphStyle.lineSpacing = lineSpacing
addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: textRage)
return self
}
@discardableResult
public func add(lineBreakMode: NSLineBreakMode, to range: NSRange? = nil) -> NSMutableAttributedString {
let textRage = range ?? self.range
guard textRage.length != 0 else { return self }
let paragraphStyle = currentParagraphStyle()
paragraphStyle.lineBreakMode = lineBreakMode
addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: textRage)
return self
}
@discardableResult
public func add(lineHeightMultiple: CGFloat, to range: NSRange? = nil) -> NSMutableAttributedString {
let textRage = range ?? self.range
guard textRage.length != 0 else { return self }
let paragraphStyle = currentParagraphStyle()
paragraphStyle.lineHeightMultiple = lineHeightMultiple
addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: textRage)
return self
}
@discardableResult
public func add(letterSpacing: Float, to range: NSRange? = nil) -> NSMutableAttributedString {
let textRage = range ?? self.range
guard textRage.length != 0 else { return self }
addAttribute(NSAttributedString.Key.kern, value: NSNumber(value: letterSpacing), range: textRage)
return self
}
@discardableResult
private func currentParagraphStyle(to range: NSRange? = nil) -> NSMutableParagraphStyle {
let textRage = range ?? self.range
guard length != 0 else { return NSMutableParagraphStyle() }
guard let paragraphStyle = attribute(NSAttributedString.Key.paragraphStyle, at: 0, longestEffectiveRange: nil, in: textRage) as? NSParagraphStyle else {
return NSMutableParagraphStyle()
}
guard let mutableParagraphStyle = paragraphStyle.mutableCopy() as? NSMutableParagraphStyle else {
return NSMutableParagraphStyle()
}
return mutableParagraphStyle
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment