在UIPasteBoard中复制NSAttributedString

Gui*_*ume 10 copy-paste uikit nsattributedstring uipasteboard ios

如何在粘贴板中复制NSAttributedString,以允许用户粘贴或以编程方式粘贴(使用- (void)paste:(id)senderUIResponderStandardEditActions协议).

我试过了:

UIPasteboard *pasteBoard = [UIPasteboard generalPasteboard];
[pasteBoard setValue:attributedString forPasteboardType:(NSString *)kUTTypeRTF];
Run Code Online (Sandbox Code Playgroud)

但这次崩溃:

-[UIPasteboard setValue:forPasteboardType:]: value is not a valid property list type'
Run Code Online (Sandbox Code Playgroud)

这是预期的,因为NSAttributedString不是属性列表值.

如果用户在我的应用中粘贴了粘贴板的内容,我希望保留属性字符串的所有标准和自定义属性.

Gui*_*ume 9

我发现当我(作为应用程序的用户)将UITextView中的富文本复制到粘贴板中时,粘贴板包含两种类型:

"public.text",
"Apple Web Archive pasteboard type
Run Code Online (Sandbox Code Playgroud)

基于此,我在UIPasteboard上创建了一个方便的类别.
(大量使用此答案中的代码).

它有效,但是:
转换为html格式意味着我将失去自定义属性.任何干净的解决方案都会很乐意接受.

文件UIPasteboard + AttributedString.h:

@interface UIPasteboard (AttributedString)

- (void) setAttributedString:(NSAttributedString *)attributedString;

@end
Run Code Online (Sandbox Code Playgroud)

文件UIPasteboard + AttributedString.m:

#import <MobileCoreServices/UTCoreTypes.h>

#import "UIPasteboard+AttributedString.h"

@implementation UIPasteboard (AttributedString)

- (void) setAttributedString:(NSAttributedString *)attributedString {
    NSString *htmlString = [attributedString htmlString]; // This uses DTCoreText category NSAttributedString+HTML - https://github.com/Cocoanetics/DTCoreText
    NSDictionary *resourceDictionary = @{ @"WebResourceData" : [htmlString dataUsingEncoding:NSUTF8StringEncoding],
    @"WebResourceFrameName":  @"",
    @"WebResourceMIMEType" : @"text/html",
    @"WebResourceTextEncodingName" : @"UTF-8",
    @"WebResourceURL" : @"about:blank" };



    NSDictionary *htmlItem = @{ (NSString *)kUTTypeText : [attributedString string],
        @"Apple Web Archive pasteboard type" : @{ @"WebMainResource" : resourceDictionary } };

    [self setItems:@[ htmlItem ]];
}


@end
Run Code Online (Sandbox Code Playgroud)

只实现了setter.如果你想写getter,和/或把它放在GitHub上,请成为我的客人:)


Ort*_*ntz 9

@ Guillaume使用HTML的方法对我不起作用(至少在iOS 7.1 beta 5中).

更清洁的解决方案是将NSAttributedStrings作为RTF(加上明文后备)插入到粘贴板中:

- (void)setAttributedString:(NSAttributedString *)attributedString {
    NSData *rtf = [attributedString dataFromRange:NSMakeRange(0, attributedString.length)
                               documentAttributes:@{NSDocumentTypeDocumentAttribute: NSRTFTextDocumentType}
                                            error:nil];
    self.items = @[@{(id)kUTTypeRTF: [[NSString alloc] initWithData:rtf encoding:NSUTF8StringEncoding],
                     (id)kUTTypeUTF8PlainText: attributedString.string}];
}
Run Code Online (Sandbox Code Playgroud)

斯威夫特2.3

public extension UIPasteboard {
  public func set(attributedString: NSAttributedString?) {

    guard let attributedString = attributedString else {
      return
    }

    do {
      let rtf = try attributedString.dataFromRange(NSMakeRange(0, attributedString.length), documentAttributes: [NSDocumentTypeDocumentAttribute: NSRTFTextDocumentType])
      items = [[kUTTypeRTF as String: NSString(data: rtf, encoding: NSUTF8StringEncoding)!, kUTTypeUTF8PlainText as String: attributedString.string]]

    } catch {

    }
  }
}
Run Code Online (Sandbox Code Playgroud)

斯威夫特3

import MobileCoreServices
public extension UIPasteboard {
  public func set(attributedString: NSAttributedString?) {

    guard let attributedString = attributedString else {
      return
    }

    do {
      let rtf = try attributedString.data(from: NSMakeRange(0, attributedString.length), documentAttributes: [NSDocumentTypeDocumentAttribute: NSRTFTextDocumentType])
      items = [[kUTTypeRTF as String: NSString(data: rtf, encoding: String.Encoding.utf8.rawValue)!, kUTTypeUTF8PlainText as String: attributedString.string]]

    } catch {

    }
  }
}
Run Code Online (Sandbox Code Playgroud)