2015-01-04 71 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

相關問題