43

How to do Syntax Highlighting in a UITextView, specifically syntax highlighting (and detection) for Objective-C on the iPhone?

Some of my ideas of how to do this:

  • NSAttributedString. Now available in iOS 3.2 and greater. But how would I put a NSAttributedString into a UITextView?
  • UIWebView. Overlay it when the user finished editing and color the text with CSS stylesheets. But how would I do this in a UIWebView, giving it the text and then coloring it?
Cœur
  • 37,241
  • 25
  • 195
  • 267
Joshua
  • 15,200
  • 21
  • 100
  • 172
  • Joshua can you respond to Kristian about any questions you may have for him here: http://stackoverflow.com/a/12666358/419, thanks. – Kev Oct 18 '12 at 12:26

5 Answers5

79

UPDATE: Since iOS 7 and TextKit, syntax highlighting has become easy as pie. Look no further than here for an introduction (by me).


Assuming that you want an editable component, there is not too much hope. Giving a quick overview, just to make sure I cover everything:

  • UITextView: plain text only, no (public) way around. But editable. No chance to alter anything, no chance to get geometry etc. Uses a web view internally. Each paragraph is a <div>, which is altered by the editing engine. You could change the DOm in there but that's all private API. All private, hence no option.
  • UIWebView: html, so it can be styled, have embedded images, etc. I guess (without looking into it) that this is what the previously mentioned Three 20 UI uses. The problem: cannot be edited. There's no (public) way around that. You canot get selections, acces the DOM, etc without private API and a lot of headaches. Editing would work like in UITextView but require a whole new level of headache. Still: private.
  • CoreText Framework: Since iOS 3.2 a very very good rendering engine. But that's it. Can directly layout and render NSAttributesStrings. However, there is no user interaction. No text selection, no text input, no spell checking, no replacements, no highlights, no no no no no. Just rendering. And quite a bit of work to make it fast on old devices with long texts.
  • UITextInput Protocol: Allows interaction with the keyboard and to grab text input. Also features basic text replacements. Problem: text input only, badly documented. No text selection etc (see above).

So here we are. Two fully functional components that lack a central function and two partial solutions that lack the missing link. Here are all viable approaches I can come up with:

  • Have the user edit a UITextView unstyled and display the content styled in a UIWebView. For the latter you can use the Three20 thing.
  • Build the missing link between CoreText and UITextInput. This includes, but is not limited to, text selection, highlight, background colors, text storage & management, efficiency, spell checking etc. Some of these are provided by system frameworks but still need a lot of integration.
  • File a bug and wait for a nice public API to come (my personal approach).
  • Convince Apple to allow private API again and mess with UItextViews DOM.

The Omni Group has taken the second approach and created an editable text view. You can find it in the OmniUI framework. However, this implementation is far from perfect. (at least it was when I last checked a few months ago). They tried hard but still didn't manage to get to Apples perfection in user interaction. Apple must have invested at least a few man-years into doing only the UI-interaction with text selection and editing. Nothing to be done at home, and as it seems even for companies as the omni group.

There is a interesting aspect to all of this: iWork. Apple claims to not use any private API in them. But the text selection is the very same as in the OS. So they must have copied framework source into the apps. Very honest approach ;)

Max Seelemann
  • 9,344
  • 4
  • 34
  • 40
  • Great answer! You must of put a lot of effort into that. I've decided to go with the first approach you suggested, by letting the user edit a `UITextView` and display the content with syntax highlighting in a `UIWebView` once the user has finished editing. I'm also interested in what Omni Group have done and will check out there Framework. What file(s)/example in the OmniUI framework uses the `CoreText` text view? Thanks again! – Joshua Sep 05 '10 at 12:29
  • Yep, a lot of work. Tried it on my own and programmed each approach to a working version, just to give up afterwards :( – Max Seelemann Sep 05 '10 at 14:31
  • Almost forgot: the example using the text view is the TextEditor. hth – Max Seelemann Sep 05 '10 at 14:32
  • The UITextView has now new posibilities for IOS6, but the options are poor and the attriuted string get/setter has poor performance :( – Augunrik Sep 27 '12 at 12:53
12

Since iOS 5 you can use a UIWebView and set contenteditable="true" on a div in it. This makes the UIWebView open a keyboard up and allow the user to directly input text into the DOM. You can then write a webapp that does syntax highlighting. You can communicate with the cocoa app with custom URLs.

The only issue I have is you don't seem to get spellchecking.

mxcl
  • 26,392
  • 12
  • 99
  • 98
  • Thanks for the answer! This is in fact the method I have gone with now in iOS 5. – Joshua Oct 28 '11 at 07:52
  • Spellchecking question: http://stackoverflow.com/questions/7927605/how-to-activate-spellchecking-for-a-contenteditable-div-in-a-uiwebview – mxcl Nov 24 '11 at 00:37
  • hi max, i have try your suggestion, and yes the keyboard is appear when i set contenteditable="true". But it also show prev & next button, if i want to remove those button, how to do that? – R. Dewi Dec 12 '11 at 07:26
2

If anybody is still looking for a complete solution for this, I know two libraries that provides this:

  • Highlightr: A Swift library for syntax highlighting, supports hundreds of languages but uses JS as backend. It's fast enough for live editing, though. (Disclaimer: I am the creator of this library).
  • SyntaxKit: A native solution by Sam Soffes, but on early stages of development. Should support any TextMate syntax in the future. This should be the way to go when the library is mature enough.
JP Illanes
  • 3,665
  • 39
  • 56
  • Highlightr is a nice library. Thanks for creating it! SyntaxKit appears to be abandoned. – Steve Jan 13 '19 at 08:07
  • @SteveTaylor Thanks, I am happy you like it. But is no longer just my library, there's several people helping me to maintain it. – JP Illanes Jan 13 '19 at 13:13
2

JTextView is a UITextView replacement that supports an NSAttributedString text store. It allows the display of rich text but is incomplete.

ma11hew28
  • 121,420
  • 116
  • 450
  • 651
0

I don't know much about syntax detection, but if you want to have multiple styles in the same UITextView, then Three 20 UI is a thing that you should look at

Here is another question that may relate to you: What is the best way to implement syntax highlighting of source code in Cocoa. I am not sure if it is Mac or iPhone but I think if you combine this and Three20, then you can have your own in iPhone. Good luck

Community
  • 1
  • 1
vodkhang
  • 18,639
  • 11
  • 76
  • 110
  • You mean what's in the Style section? Not bad but it would of been good if there was already an implementation of Syntax Highlighting. – Joshua Sep 04 '10 at 14:17
  • ops, sorry, I misunderstand that you want to highlight some text in a UITextView:(. I think you already finish the part of syntax detection – vodkhang Sep 04 '10 at 14:26
  • Just found something good that may help you. I editted my answer. Hope it helps – vodkhang Sep 04 '10 at 14:38
  • That's a good link (to the other question), the only problem is that all the links there are for Mac and are well outdated. :/ – Joshua Sep 04 '10 at 14:58
  • Oh, you cannot just take out the code you need and then use it for iPhone? – vodkhang Sep 04 '10 at 15:32
  • Unfortunately not, it uses classes not available for iPhone and a lot of the methods used are deprecated. To help people with answers I have edited my question with a few ideas on how I might go about doing it. Thanks anyway though! :) – Joshua Sep 04 '10 at 15:48