How do I render pseudo HTML efficiently with MonoTouch?
I need to draw a label that contains multiple highlighted words, consists of multiple paragraphs with different spacers, and may contain small inline images (like icons and bullets) from resources.
I know I could use NSAttributedString
for bold and italic, but it doesn't support paragraph borders or line termination, and I would rather use HTML / CSS because I am getting the styles from the server. It will also prevent me from embedding my custom images in text without having to wrap them in custom fonts.
Finally, I don't want to use UIWebView
for performance gain.
What libraries or MonoTouch bindings can I use to achieve this?
source to share
I was delighted to learn that Hulu engineers have created an iOS library that does just that. It was called GSFancyText .
Of course, we looked at other options, such as using HTML directly in
UIWebView
or withNSAttributedString
. But we decided to do our own markup and markup parsing and rich text drawing system because of the following advantages:
- It is faster and uses less memory than
UIWebView
s.- We can reuse styles and analysis results in many places.
- We can easily change the style or text of a small part of a paragraph.
- We can potentially extend the system with more attractive features like Quartz 2D features, animations, gestures, etc.
- This makes localization easy. For example, a phrase in bold might appear elsewhere in a Japanese sentence. In this case, we can use a single
NSLocalizableString
to represent sentences with different styles.- Easy to extract plain text on which we can enable VoiceOver support.
The library is awesome, so we went with creating MonoTouch bindings for it .
Example
First, define the styles with a CSS-like line:
var stylesheet = @"
.green { color: #00ff00; font-weight:bold }
.gray { color: gray; font-weight:bold }
";
GSFancyText.ParseStyleAndSetGlobal (stylesheet);
Then create an object GSFancyText
with a markup string:
var fancyText = new GSFancyText ("<span class=green>Hulu</span> <span class=gray>Plus</span>");
Then you can directly draw this on a custom view:
fancyText.drawInRect (rect);
Or create a GSFancyTextView object to display it
var fancyView = new GSFancyTextView (frame, fancyText);
You can find more examples in GSFancyTextView documentation .
My favorite feature is lambda blocks, which allow you to specify a delegate to be called to render the pseudo element <lambda id=yourhandler width=50 height=50>
.
This allows you to insert custom images or make a preliminary inline drawing yourself.
source to share