Using Omni to do RTF Editor


首先這是一個中斷的項目(雖然以后個人可能會繼續,但在公司層面上已經到此為止了),但是還是完成了相關的內容:

讀取rtf/rtfd文件,編輯(字體,大小,顏色),添加圖片,保存。

(至於為什么要選擇rtf格式來實現富文本編輯,下面會做說明)

在項目過程中還是遇到不小的問題,得到些許收獲,因此在這一並紀錄下來。

2012-02-06 16:04:07

首先我們得了解RTF是種什么格式,這個可以到微軟的網站上取找,或者搜索 “RTFV1.7規范.doc”。

規范里面主要是一些控制字,關鍵字之類的東西,我們需要對一些常見的字符進行解析以保證可以顯示大多數格式的rtf文件。

在之前的日志里,我提到了OmniGroup的三大類,這里再說明一下:

<OmniUI/OUIRTFReader.h>:讀取rtf/rtfd文件,得到NSAttributedString對象(iOS可以使用CoreText繪制NSAttributedString)

<OmniUI/OUIEditableFrame.h>:將NSAttributedString對象繪制到View,並實現編輯功能(主要實現iOS的相關delegate,如UIKeyInput,UITextInputTraits,EditMenu等)

<OmniUI/OUIRTFWriter.h>:將NSAttributedString對象 保存程文件rtf/rtfd,並且在Mac上可以打開。

這里先提一下,微軟的rtf標准里面是包含如何處理圖片的,但是在Mac上,如果包含圖片的rtf則會保存成rtfd格式。也就是說Mac上沒有完全支持RTF標准,而這主要是圖片部分沒有支持。

RTFD其實是bundle,本質上是一個文件夾,但是以一個對象的方式呈現在用戶面前。通常,rtfd包含一個“TXT.rtf”和圖片文件。

其中“TXT.rtf"包含如下內容:

{\rtf1\ansi\ansicpg1252\cocoartf1138\cocoasubrtf260

{\fonttbl\f0\fswiss\fcharset0 ArialMT;\f1\fswiss\fcharset0 Helvetica;\f2\fnil\fcharset134 STHeitiSC-Light;

}

{\colortbl;\red255\green255\blue255;}

\paperw11900\paperh16840\margl1440\margr1440\vieww10800\viewh7200\viewkind0

\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural

 

\f0\fs48 \cf0 1\

\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural

 

\f1\fs24 \cf0 {{\NeXTGraphic iPadAppIcon.png \width1440 \height1440

}¬}\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural

 

\f2\fs48 \cf0 \

}

其中,圖片關鍵字為 NeXTGraphic。

因此我們需要修改Reader/Writer,增加NeXTGraphic的解析。

所幸Omni對rtf常見的關鍵字已經做了很好的支持,所以這里的工作量減小很多。

1Reader修改:

添加了rtfd文件路徑變量,因為我們需要通過路徑來獲得圖片數據;

在- (void)_parseKeyword種添加NeXTGraphic的解析。

解析的過程模仿Omni的代碼即可,稍微需要注意的是圖片是作為OATextAttachment對象存儲,然后作為

OAAttachmentAttributeName屬性的值添加到最終的NSAttributedString中。

這部分可以參見Omni提供的TextEdit例子來查看。

2Writer修改:

同樣需要添加文件的路徑;

獲取OAAttachmentAttributeName屬性值,從中獲取圖片的原始數據和名字。將圖片寫入磁盤,將名字添加進”TXT.rtf“,然后再保存。

這部分也是依葫蘆畫瓢。

3OUIEditableFrame這部分沒有做太多更改,可以根據實際需要擴充

4RTF的編輯功能:

這一版本添加了style的選取,即在某處選中Style后彈出一個頁面,可以選擇字體和大小,完成后返回。然后輸入的字符是之前選擇的類型。

因為OUIEditableFrame有相應的獲取當前字符位置的接口,這一部分都放在個人的代碼里實現。

5cut/copy/paste:

主要是包含圖片的cut/copy/paste. 

實現OUIEditableFrame delegate方法,因為UIPasteboard只能保存plist類型的數據,所以我把選中的文本存儲成一個臨時的rtfd文件,

然后paste的時候去從這個文件中讀取還原成NSAttributedString對象。

6 其他:

OUIEditableFrame是添加到UIScrollView上,這樣在編輯的時候也能自由滑動。Omni的例子是沒有這個功能,但是在編輯的時候會自動將

鍵盤下的文字適時的顯示出來。

 還有就是修改完依賴庫以后先選取相應的schema在device上build一下,否則在編譯的時候你使用的庫還是之前的。

 

以上就是這個項目中個人認為重要的地方。其實Omni這個庫很強大但是不太好理解,因為文檔少,可以求助的地方不多,所以遠不如Three20有群眾基礎。

就單單將他的例子模仿學會也着實花了不少時間,研究代碼的時候會很痛苦但是理清了思路后就有豁然開朗的感覺,尤其是發現Omni寫的非常模塊化,非常容易擴展和自定義。

但是也有很多地方未搞明白,比如提供例子里的App入口函數沒有找到,以及如何使用他聞名的內存查看功能等等。

 

另外還有一個問題:

在生成Ad Hoc版本的ipa時,始終沒有結果。Xcode顯示成功了,但是沒有生成archive。網上搜了些方法,還是無果。如果有知道的朋友,麻煩請賜教。

 

接下來談談這個項目本身:

當時公司是想在某一個App上添加文檔編輯功能,目標是生成的文件在Mac/iOS/Windows上通用,並且可以編輯,改變字體大小,添加圖片。

因為App本身是免費的,希望這個功能以簡單的方式實現。

於是目光落在了RTF身上。

但是沒有想到RTF編輯器的水相當深,在我搜索資料的過程中,發現即使是windows開發人員都覺得是件麻煩事。

於是,公司最終以帶圖片的RTF不能在上述平台上通用而中斷項目。

2012-02-07 09:03:41

個人的思考:

1前期調查的時候,就發現相關的資源不多,而且有富文本編輯功能的往往都是以此作為賣點的收費App,沒有哪個App免費的提供了這個功能。

evernote在某種程度上也是富文本編輯,但是其文件格式是自定義的,只能用evernote打開

2作為一個免費App,富文本編輯功能絕對是亮點,但是考慮到難度(因為只有我一個人負責開發),可以迭代式的完善功能。

比方說,先實現文字的富文本編輯,隨后升級成可以添加圖片,再添加存儲的文件在個平台通用等特性

3windows無法正確識別RTFD,那么我們可以設置導出某種格式的功能,比如html等等

 以上是個人對做項目的思考。

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM