Reputation: 61
New to Swift and iOS. I am attempting to allow the user to copy an nsattributedstring in my app and paste it into Mail, iMessage, or whatever app they choose.
@IBAction func action(sender: UIButton!) {
let stringAttributes = [
NSFontAttributeName: UIFont.boldSystemFontOfSize(14.0),
NSBackgroundColorAttributeName: UIColor.redColor(),
]
let attributedString = NSMutableAttributedString(string: "Hello world!", attributes: stringAttributes)
do {
let documentAttributes = [NSDocumentTypeDocumentAttribute: NSRTFTextDocumentType]
let rtfData = try attributedString.dataFromRange(NSMakeRange(0, attributedString.length), documentAttributes: documentAttributes)
if let rtfString = String(data: rtfData, encoding: NSUTF8StringEncoding) {
let pb = UIPasteboard.generalPasteboard()
return pb.string = rtfString
}
}
catch {
print("error creating RTF from Attributed String")
}
}
When pasted, this returns:
Hello world!{ NSBackgroundColor = "UIDeviceRGBColorSpace 1 0 0 1";NSFont = " font-family:\".SFUIText-Semibold\"; font-weight: bold; font-style: normal; font-size: 14.00pt"; }
Edited code returns:
{\rtf1\ansi\anscipg1252{fontal\f0\fnil\fcharset0 .SFUIText-Semibold;}{\colortbl;\red255\green255\blue255;\red255\green0\blue0;}\pard\tx560\tx1120\tx1680...\pardirnatural\partightenfactor0 \f0\b\fs28\cf0 Hello world!
While doing research, I came across this answer but was not able to get it to work from Leonard Pauli's response. Maybe because that's only within the app and not pasting to another? I'm sorry if this is a duplicate of this question. Paste Formatted Text, Not Images or HTML
I also could not translate this Copy Text with Formatting - iOS 6 NSAttributedString to Pasteboard to swift
I can paste plain text just not text with any attributes.
Upvotes: 6
Views: 2453
Reputation: 569
for swift 5
func copyAttributedStringToPB() {
let stringAttributes = [
NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 14.0),
NSAttributedString.Key.backgroundColor: UIColor.red,
]
let attributedString = NSMutableAttributedString(string: "Hello world!", attributes: stringAttributes)
do {
let documentAttributes = [NSAttributedString.DocumentAttributeKey.documentType: NSAttributedString.DocumentType.rtf]
let rtfData = try attributedString.data(from: NSMakeRange(0, attributedString.length), documentAttributes: documentAttributes)
let pb = UIPasteboard.general
pb.setData(rtfData, forPasteboardType: kUTTypeRTF as String)
}
catch {
print("error creating RTF from Attributed String")
}
}
Upvotes: 4
Reputation: 675
I've updated your code to save the RTF data you're creating to the pasteboard properly, however, loading the RTF data and placing it back into a NSAttributedString
object, seems to be a manual task.
As such, the copy and paste behavior will only work in contexts where the developer has explicitly supported the copying and pasting of RTF data in this manner.
Unfortunately, in the Playgrounds I've been testing the code in, the Pasteboard's string property is set to contain the plaintext version of the RTF data (which is full of markup and weird control characters). I haven't been able to find a solution which fixes this issue, which means apps which don't support the RTF in this manner may still paste the marked up RTF plaintext, instead of attributed text... :(
This will get you some of the way there (in app copy-paste RTF) but obviously isn't great. My projects also rely on this kind of behavior, so if anybody has additional ideas, I'd also love to know.
import MobileCoreServices
// ----- Copy ------
func copyAttributedStringToPB() {
let stringAttributes = [
NSFontAttributeName: UIFont.boldSystemFontOfSize(14.0),
NSBackgroundColorAttributeName: UIColor.redColor(),
]
let attributedString = NSMutableAttributedString(string: "Hello world!", attributes: stringAttributes)
do {
let documentAttributes = [NSDocumentTypeDocumentAttribute: NSRTFTextDocumentType]
let rtfData = try attributedString.dataFromRange(NSMakeRange(0, attributedString.length), documentAttributes: documentAttributes)
let pb = UIPasteboard.generalPasteboard()
pb.setData(rtfData, forPasteboardType: kUTTypeRTF as String)
}
catch {
print("error creating RTF from Attributed String")
}
}
// -------- Paste -------
let pb = UIPasteboard.generalPasteboard()
let data = pb.dataForPasteboardType(kUTTypeRTF as String)
let pastedAttributedString = try! NSAttributedString(data: data!, options: [NSDocumentTypeDocumentAttribute: NSRTFTextDocumentType], documentAttributes: nil)
Upvotes: 3