2012-09-26 9 views
8

Wie Sie ein NSAttributedString in die Zwischenablage kopieren Sie, dem Benutzer zu ermöglichen einzufügen, oder programmatisch einzufügen (mit - (void)paste:(id)sender, von UIResponderStandardEditActions-Protokoll).Kopieren NSAttributedString in UIPasteBoard

Ich habe versucht:

UIPasteboard *pasteBoard = [UIPasteboard generalPasteboard]; 
[pasteBoard setValue:attributedString forPasteboardType:(NSString *)kUTTypeRTF]; 

aber dieser Absturz mit:

-[UIPasteboard setValue:forPasteboardType:]: value is not a valid property list type' 

, die zu erwarten ist, weil NSAttributedString keine Eigenschaft Listenwert ist.

Wenn der Benutzer den Inhalt der Pasteboard in meiner App einfügen, möchte ich alle Standards und benutzerdefinierten Attribute der attributierten Zeichenfolge beibehalten.

+0

machte einige Einblicke in UIPasteBoard und NSAttributedString könnte wertvoll sein: http://stackoverflow.com/a/38211885/1054573 –

Antwort

9

ich gefunden habe, dass, wenn ich (als Benutzer der Anwendung) Rich-Text aus einem UITextView in die Zwischenablage zu kopieren, die Pappe zwei Arten enthält:

"public.text", 
"Apple Web Archive pasteboard type 

Auf dieser Grundlage habe ich eine bequeme Kategorie auf UIPasteboard.
(Bei starker Verwendung von Code aus this answer).

Es funktioniert, aber:
Die Konvertierung in HTML-Format bedeutet, dass ich benutzerdefinierte Attribute verlieren werde. Jede saubere Lösung wird gerne angenommen.

Datei UIPasteboard + AttributedString.h:

@interface UIPasteboard (AttributedString) 

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

@end 

Datei 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 

Nur implementiert Setter. Wenn du den Getter schreiben und/oder ihn auf GitHub schreiben willst, sei mein Gast :)

+0

+1, aber das ist der Setzer, nicht der Getter;) –

+0

@ H2CO3 Danke :) Aktualisiert th Die Antwort. – Guillaume

+0

@ThomasTempelmann danke, bearbeitet! – Guillaume

-1

Der Pasteboard-Manager in OSX kann automatisch zwischen einer Vielzahl von Text- und Bildtypen konvertieren.

Für Rich-Text-Typen würden Sie normalerweise RTF in die Pasteboard platzieren. Sie können RTF-Darstellung aus einer attributierten Zeichenfolge erstellen und umgekehrt. Siehe "NSAtributedString Application Kit Additions Reference".

Wenn auch Bilder enthalten sind, verwenden Sie den RTFd anstelle von RTF-Geschmack.

Ich kenne nicht die MIME-Typen für diese (ich bin an die Carbon Pasteboard API, nicht die Cocoa One gewöhnt), aber Sie können zwischen UTIs, Pboard und MIME-Typen mit der UTType-API konvertieren.

UTI für RTF ist "public.rtf", für RTFd ist es "com.apple.flat-rtfd".

+0

Dies ist eine iOS-Frage. – Guillaume

+0

Hoppla - das kleine "ios" -Tag ist leicht zu übersehen. Und iOS scheint nicht RTF-Konvertierung eingebaut zu haben. Bummer. –

+0

Einverstanden. Normalerweise, wenn das Tag die einzige Möglichkeit ist, es zu sehen, erkläre ich es in der Frage. Ich tat es nicht, weil ich dachte, UIPasterboard wäre genug. Tut mir leid, dass ich nicht klarer bin. – Guillaume

8

@ Guillaume Ansatz mit HTML funktioniert nicht für mich (zumindest in iOS 7.1 Beta 5).

Die Reinigerlösung ist NSAttributedStrings als RTF (plus Klarrückfall) in die Paste Platine einzufügen:

- (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}]; 
} 

Swift 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 { 

    } 
    } 
} 

Swift 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 { 

    } 
    } 
} 
0

Es ist ganz einfach:

#import <MobileCoreServices/UTCoreTypes.h> 

    NSMutableDictionary *item = [[NSMutableDictionary alloc] init]; 

    NSData *rtf = [attributedString dataFromRange:NSMakeRange(0, attributedString.length) 
          documentAttributes:@{NSDocumentTypeDocumentAttribute: NSRTFDTextDocumentType} 
              error:nil]; 

    if (rtf) { 
    [item setObject:rtf forKey:(id)kUTTypeFlatRTFD]; 
    } 

    [item setObject:attributedString.string forKey:(id)kUTTypeUTF8PlainText]; 

    UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; 
    pasteboard.items = @[item];