views:

568

answers:

5

For an iPhone ebook application I need to break arbitrarily long HTML documents up into pages which fit exactly on one screen. If I simply use UIWebView for this, the bottom-most lines tend to get displayed only partly: the rest disappears off the edge of the view.

So I assume I would need to know how many complete lines (or characters) would be displayed by the UIWebView, given the source HTML, and then feed it exactly the right amount of data. This probably involves lots of calculation, and the user also needs to be able to change fonts and sizes.

I have no idea if this is even possible, although apps like Stanza take HTML (epub) files and paginate them nicely. It's a long time since I looked at JavaScript, would that be an option worth looking at?

Any suggestions very much appreciated!

update

So I've hit upon a possible solution, using JavaScript to annotate the DOM-tree with sizes and positions of each element. It should then be possible to restructure the tree (using built-in XSLT or JavaScript), cutting it up in pages which fit exactly on the screen.

Remaining problem here is that this always breaks the page on paragraph-boundaries, since there is no access to the text at a lower level than the P-element. Perhaps this can be remedied by parsing the text into words, encapsulating each word in a SPAN-tag, repeating the measurement procedure above, and then only displaying the SPAN elements that fit onto the screen, inserting the remaining ones at the front of the next page.

All this sounds rather complicated. Am I talking any sense? Is there a simpler way?

A: 

Have a look at blog post from Drew McCormack. http://www.macresearch.org/cocoa-scientists-xxx-developing-iphone

Shaji
Thanks for that link, but it focuses on a PDF solution. One of my requirements is that fonts and sizes should be changeable, which (as far I know) isn't possible with a PDF, since it's a page description format. Hence my choice for HTML.
radnoise
+5  A: 

You should look at the PagedMedia CSS module: http://www.w3.org/TR/css3-page/ CSS3 also support multicolumn layouts (google for "css3-multicol". I don't have enough Karma to include a second link here :-)

About your update: how about doing the layout of one single page, then use a DIV with overflow:hidden for the text part. Next thing would be to overlay a transparent item on top of that, that would programmatically scroll the inner content of the DIV PAGE_HEIGHT pixels up or down according to some navigation controls (or gestures).

Thanks, useful suggestion! Pity that WebKit doesn't implement even the CSS2 @page rule. Multicolumn support is apparently experimental still, but maybe I can fiddle a bit with that. I don't know if I can have a UIWebView which is wide enough for the number of columns I need to render (1 per page), but it's worth investigating.
radnoise
I haven't tried @page on the iPhone, but I would most certainly expect Apple to support it on the iPad, at least in an upcoming update.multicolumn works great in recent versions of webkit (not sure about iphone tho).
+2  A: 

The other option is to have a parent <div> with multiple css3 columns: link1, link2.
This works on Android:

<style type='text/css'>
div {
    width: 1024px; // calculated
    -webkit-column-gap: 0px;
    -webkit-column-width: 320px; // calculated
    }
p {
    text-align: justify;
    padding:10px;
    }
</style>
alex
Yes, an earlier suggestion involved using css columns. I've tried it on Safari 3.1 and it looks fine, so I'll be looking into that for the iPhone.
radnoise
How to calculat div's width ?
HelloWorld
A: 

The CSS multicol suggestions are very interesting! However, and I hope it's ok to respond with another question: how would you go from splitting one or more long <p> elements into columns to having one particular of these columns being rendered in a WebView? The DOM hasn't changed, so you can't pick out an element and render it. What am I missing?

dunken69
I haven't looked at this in depth yet, and I don't know of a way to render just one column. But I assume you can use JavaScript to scroll to the column you want. As long as your viewport is sized to the column's dimensions, only that column will be visible.Of course I do hope all of this doesn't result in outrageous memory requirements.
radnoise
A: 

Any progress on this. I have the exact same problem.

Lindea