2012-09-26 39 views
8

Làm thế nào để bạn sao chép một NSAttributedString trong tông, cho phép người dùng để dán, hoặc để dán theo chương trình (với - (void)paste:(id)sender, từ giao thức UIResponderStandardEditActions).Sao chép NSAttributedString trong UIPasteBoard

tôi đã cố gắng:

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

nhưng vụ tai nạn này với:

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

mà là để được mong đợi, bởi vì NSAttributedString không phải là một giá trị danh sách bất động sản.

Nếu người dùng dán nội dung của bảng trong ứng dụng của tôi, tôi muốn giữ tất cả các tiêu chuẩn và thuộc tính tùy chỉnh của chuỗi được phân bổ.

+0

Made một số hiểu biết trong UIPasteBoard và NSAttributedString, có thể có giá trị: http://stackoverflow.com/a/38211885/1054573 –

Trả lời

9

Tôi đã thấy rằng khi tôi (như một người dùng của ứng dụng) sao chép văn bản phong phú từ một UITextView vào tông, các tông chứa hai loại:

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

Trên cơ sở đó, tôi đã tạo ra một loại thuận tiện trên UIPasteboard.
(Sử dụng mã nặng từ this answer).

Nó hoạt động, nhưng:
Chuyển đổi sang định dạng html có nghĩa là tôi sẽ mất thuộc tính tùy chỉnh. Bất kỳ giải pháp sạch sẽ được sẵn sàng chấp nhận.

file UIPasteboard + AttributedString.h:

@interface UIPasteboard (AttributedString) 

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

@end 

file 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 

Chỉ thực hiện setter. Nếu bạn muốn viết getter, và/hoặc đặt nó trên GitHub, hãy là khách của tôi :)

+0

+1, nhưng đây là setter, không phải là getter;) –

+0

@ H2CO3 Cảm ơn bạn :) Cập nhật lần thứ e câu trả lời. – Guillaume

+0

@ThomasTempelmann cảm ơn, đã chỉnh sửa! – Guillaume

-1

Trình quản lý bảng trong OSX có thể tự động chuyển đổi giữa nhiều kiểu văn bản và hình ảnh.

Đối với các loại văn bản đa dạng, bạn thường đặt RTF vào trong bảng. Bạn có thể tạo biểu diễn RTF từ một chuỗi được phân bổ và ngược lại. Xem "Tham chiếu bổ sung bộ ứng dụng NSAttributedString".

Nếu bạn cũng có hình ảnh, hãy sử dụng RTFd thay vì hương vị RTF.

Tôi không biết các loại MIME cho những thứ này (tôi đã quen với API của bảng tổng hợp Carbon), nhưng bạn có thể chuyển đổi giữa các loại UTI, Pboard và MIME bằng cách sử dụng API UTType.

UTI cho RTF là "public.rtf", cho RTFd là "com.apple.flat-rtfd".

+0

Đây là câu hỏi iOS. – Guillaume

+0

Rất tiếc - thẻ "ios" nhỏ dễ bỏ qua. Và iOS dường như không có chuyển đổi RTF. Bummer. –

+0

Đồng ý. Thông thường, khi thẻ là cách duy nhất để xem nó, tôi rõ ràng nó trong câu hỏi. Tôi không phải vì tôi nghĩ UIPasteboard là đủ. Xin lỗi vì không rõ ràng hơn. – Guillaume

8

@ Cách tiếp cận của Guillaume sử dụng HTML không hoạt động đối với tôi (ít nhất là trong iOS 7.1 beta 5).

Giải pháp sạch hơn là để chèn NSAttributedStrings như RTF (cộng với dự phòng plaintext) vào bảng dán:

- (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

Nó là khá đơn giản:

#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];