文本編輯器我需要了解如何TextKit工作,我怎麼可以用它來建立一個文本編輯器。我需要弄清楚如何僅繪製最終用戶與可見文本進行交互,或確定如何僅將可用文本應用於可見文本而不將屬性應用於processEditing方法中整個已更改的文本範圍。
背景
的iOS 7推出了TextKit。我有一個完全實現TextKit的標記器和代碼(參考Apple的TextKitDemo項目 - 下面提供了一個鏈接)...並且它可以工作。但是,它真的很慢。當文本被解析時,NSTextStorage會要求您在processEditing方法中在同一個線程上着色編輯文本的整個範圍。將作業卸載到線程無濟於事。這太簡單了。我已經到了只能重新修改範圍的地步,但是如果範圍太大,這個過程會很慢。在某些情況下,整個文檔可能會在更改後失效。
以下是我的一些想法。請讓我知道,如果任何這些將工作或可能推動我在正確的方向。
1)多NSTextContainers
閱讀看來我可以在NSLayoutManager內添加多個NSTextContainers的文檔。我假設通過這樣做,我應該能夠定義不僅可以在NSTextContainer中繪製的行數,而且還應該能夠知道哪個NSTextContainer對最終用戶可見。我知道,如果我走這條路,我將需要投入很多時間才能看出這是否可行。初始測試表明您只需要一個NSTextContainer。所以我必須繼承NSLayout的子類,或者在佈局管理器確定哪些文本進入哪個文本容器時創建一個包裝器。呸。另外,我不知道TextKit如何讓我知道是時候繪製一個特定的NSTextContainer了......也許這不是它的工作原理!
2)無效範圍瓦特/ NSLayoutManager
使用invalidateLayoutForCharacterRange無效LayoutManager的:actualCharacterRange :.但是,這實際上做了什麼,它將如何減少文本歸因階段?它什麼時候讓我知道一個特定的文本需要突出顯示?另外,我看到NSLayoutManager將懶洋洋地畫出字形......怎麼樣?什麼時候?這對我有什麼幫助?我如何利用此調用,以便在實際佈置文本之前將背景字符串歸屬?
3)覆蓋NSLayoutManager drawGlyphsForGlyphRange:atPoint:方法。
我真的不想這樣做。也就是說,在Mac OS X中,NSAttributedStrings具有臨時屬性的概念,其中樣式信息僅用於演示。這加快了突出顯示的過程!問題是,它不存在於iOS 7 TextKit框架中(或者它在那裏,我只是不知道它)。我相信通過使用這種方法,它可以給我使用臨時屬性的相同類型的速度......因爲我可以用這種方法回答所有佈局,顏色和格式問題,而無需觸及NSTextStorage歸因串。唯一的問題是,我不知道該方法如何與NSLayoutManager類中提供的其他方法相關。它是否保持寬度和高度的狀態? NSTextContainer太小時會修改它的大小嗎?另外,它只爲在文本緩衝區中添加的字符繪製字形。它不會重新繪製整個屏幕。只有它的一小部分...而且非常好。我對如何使用這個工具有一些想法......但我真的沒有想要佈置字形的願望。這太方便了,我還沒有找到一個很好的例子。
我將不勝感激任何幫助,你必須提供。
作爲感謝,我列出了所有我已經使用在過去的幾年中幫助我去,我現在在哪裏,它們對您有幫助的希望的框架和參考。
語法高亮框架:
- http://colorer.sourceforge.net/
- https://github.com/MikeJ1971/Glint(不支持字符串,註釋等)
- https://projects.gnome.org/gtksourceview/features.html(提供用於令牌生成一個體面的lib用GTK工作但也可能是。重新編寫了不同的佈局管理器)
- http://parsekit.com/(良好解析器。但是,你必須來包裝API來創建一個狀態機需要維修範圍時)
- http://svn.gna.org/viewcvs/etoile/trunk/Etoile/Languages/LanguageKit/
- https://github.com/CodaFi/IDEKit(令人驚歎的工作。在這個代碼中有很多好點子。我的問題是,我完全不知道它如何修理範圍,或者即使它)
- http://www.crimsoneditor.com/(舊的Windows代碼編輯器,它有一個很好的分詞器 - 。雖然有點難以閱讀它不。使用正則表達式的表達式話雖這麼說,我根據我的令牌邏輯關閉的這段代碼,這是遠遠超過上面列出的任何框架)
資源的速度更快:
- http://cocoafactory.com/blog/2012/10/29/how-to-use-custom-nsattributedstring-attributes/
- https://github.com/objcio/issue-5-textkit
- http://alexgorbatchev.com/SyntaxHighlighter/
- http://docs.xamarin.com/samples/TextKitDemo/(蘋果的演示)
- http://cocoadev.com/ImplementSyntaxHighlighting(請務必仔細閱讀所有子文章。偉大的東西)
大部分框架都是一樣的。它們或者不考慮上下文切換(或者你必須編寫包裝來提供上下文)範圍,或者它們不修改上下文範圍,因爲用戶修改了文本(如字符串,多行註釋等)。最後一項要求非常重要。因爲如果令牌生成器無法確定哪些範圍受到更改的影響,您最終必須再次解析並重新命名整個字符串。唯一的例外是Crimson編輯。這個標記器的問題是它在標記時不保存狀態。在繪製時間,算法使用標記來確定繪圖的狀態。它從文檔的頂部開始,一直到文本的可見範圍。不用說,我通過在文檔的某些部分緩存文檔的狀態來優化這一點。
另一個問題是,框架不遵循Apple所做的相同的MVC模式 - 這是可以預料的。具有完整工作編輯器的框架全部使用由它們構建的API(即GTK,Windows等)提供的鉤子,爲它們提供了何時以及何時繪製到屏幕的哪一部分的信息。在我的情況下,TextKit似乎要求您在processEditing中對整個更改的範圍進行歸因。
也許我的觀察是錯誤的。 (我希望他們是!!)也許,例如ParseKit會爲我需要它做的工作,我根本不知道如何使用它。如果是這樣,請讓我知道!並再次感謝!
如果有人試圖實現上述建議,你會讓我知道它是怎麼回事?我很想聽聽你的發現!謝謝! – PeqNP
我忘了補充一件事。我也試着覆蓋NSLayoutManager attributesAtIndex:effectiveRange :.我假設這返回一個NSDictionary與鍵/值對組成的NSForegroundColorAttributeName/UIColor等,但是,每次我試圖返回一個_basic_字典與此鍵/值對,程序掛起...但是,這可能成爲我可以潛在地提供屬性的地方......這是假設屬性被懶惰地查詢。我只能猜測,我需要使已更改的文本範圍無效,以使其正常工作。 – PeqNP
我想我可能會擁有它;如果我可以確定用戶可見的文本範圍,我可以將屬性僅應用於processEditing中的該範圍,並在可見文本之前和之後標記無效範圍,並使用自定義屬性(或NSRanges列表, )。然後,我會在一個單獨的過程中卸載剩餘的工作,僅用於無效的文本。 – PeqNP