Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to draw images among rich-text with CoreText? (iOS)

I can draw rich-text with Core Text, the problem is placing images flowing with the text. (iOS SDK 4.1)

I'm try to drawing some kind of rich-text. Problem is designer placed many icons among text. So the text what I have to draw is something like this:

Here is a word <an icon image>, and another words.
The image(<another icon>) should be placed like a glyph.
It's part of text, not an example.

<icon> are images. (This is not a code. Just an illustration.)

I can draw this by laying out all of them manually, but it's too hard keeping complex text layout behaviors. So I'm finding a way to draw this with Core Text.

like image 988
eonil Avatar asked Feb 04 '23 01:02

eonil


2 Answers

I got solution.

The key of laying out non-text content is CTRunDelegate. Core Text does not support non-text content, so you have to make blank spaces for them, and draw or place them yourself later.

A part of NSAttributedString attributed with kCTRunDelegateAttributeName will call registered callback to determine width of each glyph. This will let you make blank space for each non-text object.

However, after drawing the text with Core Text, the layout information stored with frame/line/run will invalidated. So you have to draw/place non-text contents after layout with framesetter/typesetter, but before drawing.

This link describes basic usage of CTRunDelegate:
How to use CTRunDelegate in iPad?


There is a problem with Core Text. Originally, CTRunDelegate designed to support variable width and vertical alignment via CTRunDelegateCallbacks.getAscent and CTRunDelegateCallbacks.getDescent. But vertical alignment feature doesn't work currently. This might be a bug.

I described this problem here: Aligning multiple sized text vertical center instead of baseline with Core Text in iOS

If you have informations about this problem, please see my question at the link.

like image 147
eonil Avatar answered Feb 11 '23 10:02

eonil


You simply set a delegate for a given CTRun and the delegate object is responsible to let know Core Text what is the CTRun ascent space, descent space and width.

When Core Text "reaches" a CTRun which has a CTRunDelegate it asks the delegate - how much width should I leave for this chunk of data, how high should it be? This way you build a hole in the text - then you draw your image in that very spot.

enter image description here

Here is a blog about Core Text.It has the answer for you .

How To Create a Simple Magazine App with Core Text

like image 29
jasonhao Avatar answered Feb 11 '23 10:02

jasonhao