2015-01-04 35 views
3

我想模拟iOS页面和Keynote应用程序的粘贴板行为。总之,让基本NSAttributedString文本格式(即BIU)被粘贴到一个UITextView,而不是图像,HTML等粘贴带格式的文本,而不是图像或HTML

行为摘要

  1. 如果您复制从Notes应用,Evernote的格式化文本,或者来自网站的文本和图像,页面将仅粘贴纯文本字符串
  2. 如果您从Pages或Keynote内复制格式化文本,它将在Pages,Keynote等其他位置粘贴格式化文本。
  3. 不受欢迎的后果,但也许重要的是承认,Notes应用程序或Evernote都不会粘贴表单从Pages或Keynote中复制的初始文本。我猜测应用程序之间的差异是使用NSAttributedStrings,而不是HTML?

这是如何完成的?在Mac OS上,看起来你可以自己ask the pasteboard to return different types,它提供了丰富的文本和字符串表示,并且使用富文本作为首选。不幸的是,iOS的readObjectsForClasses似乎不存在。也就是说,我可以通过日志看到iOS确实有一个RTF相关类型的粘贴板,thanks to this post。然而,我不能找到一种方法来请求一个NSAttributedString版本的粘贴板内容,这样我就可以优先粘贴它。

背景

我在UITextViews一个文本的应用程序,允许基本NSAttributedString用户可编辑的格式(即粗体,斜体,下划线)。用户想要复制其他应用程序中的文本(例如Safari中的网页,Notes应用程序中的文本),以便粘贴到我的应用程序中的UITextView中。允许粘贴板以默认方式运行意味着我最终可能会收到我的应用程序无意处理的背景颜色,图像,字体等。下面的例子显示了当粘贴到我的应用程序的UITextView中时,如何复制具有背景颜色的文本。

enter image description here

我可以通过继承的UITextView

- (void)paste:(id)sender 
{ 
    UIPasteboard *pasteBoard = [UIPasteboard generalPasteboard]; 
    NSString *string = pasteBoard.string; 
    NSLog(@"Pasteboard string: %@", string); 
    [self insertText:string]; 
} 

意想不到的后果是,失去了保留这是一个从我的应用程序中复制的文本格式的能力,克服1。用户可能想从我的应用中的一个UITextView复制文本,并将其粘贴到我的应用中的另一个UITextView。他们希望保留格式(即粗体,斜体,下划线)。

洞察力和建议表示赞赏。

+0

是的,这可能RTFD VS HTML那是当它涉及到样式跨应用,pasteability区别:) –

回答

1

一些复制/粘贴好吃的东西和想法,为你:)

// Setup code in overridden UITextView.copy/paste 
let pb = UIPasteboard.generalPasteboard() 
let selectedRange = self.selectedRange 
let selectedText = self.attributedText.attributedSubstringFromRange(selectedRange) 

// UTI List 
let utf8StringType = "public.utf8-plain-text" 
let rtfdStringType = "com.apple.flat-rtfd" 
let myType = "com.my-domain.my-type" 
  • 覆盖UITextView的副本:并使用您的自定义纸板型 pb.setValue(selectedText.string, forPasteboardType: myType)
  • 为了让富文本复印件(复印: ):

    // Try custom copy 
    do { 
        // Convert attributedString to rtfd data 
        let fullRange = NSRange(location: 0, length: selectedText.string.characters.count) 
        let data:NSData? = try selectedText.dataFromRange(fullRange, documentAttributes: [NSDocumentTypeDocumentAttribute: NSRTFDTextDocumentType]) 
        if let data = data { 
    
         // Set pasteboard values (rtfd and plain text fallback) 
         pb.items = [[rtfdStringType: data], [utf8StringType: selectedText.string]] 
    
         return 
        } 
    } catch { print("Couldn't copy") } 
    
    // If custom copy not available; 
    // Copy as usual 
    super.copy(sender) 
    
  • 要允许富文本粘贴(粘贴:):

    // Custom handling for rtfd type pasteboard data 
    if let data = pb.dataForPasteboardType(rtfdStringType) { 
        do { 
    
         // Convert rtfd data to attributedString 
         let attStr = try NSAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute: NSRTFDTextDocumentType], documentAttributes: nil) 
    
         // Bonus: Possibly strip all unwanted attributes here. 
    
         // Insert it into textview 
         replaceSelection(attStr) 
    
         return 
        } catch {print("Couldn't convert pasted rtfd")} 
    } 
    // Default handling otherwise (plain-text) 
    else { super.paste(sender) } 
    
  • 更妙然后使用自定义纸板型,白名单都可能通过希望标签,循环,剥去上粘贴的所有其他。

  • (奖金:帮助UX在其他应用程序通过剥离掉您添加不必要的属性,在副本(如字体和FG色))
  • 另外值得注意的,TextView的可能不想让当剪贴板中包含特定类型的粘贴,要解决这个问题:

    // Allow all sort of paste (might want to use a white list to check pb.items agains here) 
    override func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool { 
        if action == #selector(UITextView.paste(_:)) { 
         return true 
        } 
        return super.canPerformAction(action, withSender: sender) 
    } 
    
  • 此外,切:可能是很好的实施也是如此。基本上只是copy:replaceSelection(emptyString)

  • 为了您的方便:

    // Helper to insert attributed text at current selection/cursor position 
    func replaceSelection(attributedString: NSAttributedString) { 
        var selectedRange = self.selectedRange 
    
        let m = NSMutableAttributedString(attributedString: self.attributedText) 
        m.replaceCharactersInRange(self.selectedRange, withAttributedString: attributedString) 
    
        selectedRange.location += attributedString.string.characters.count 
        selectedRange.length = 0 
    
        self.attributedText = m 
        self.selectedRange = selectedRange 
    } 
    

祝你好运!

参考文献: Uniform Type Identifiers Reference

相关问题