Forcing text layout
Forcing text layout
- Subject: Forcing text layout
- From: Keith Blount <email@hidden>
- Date: Fri, 12 Mar 2010 10:11:02 -0800 (PST)
Hello,
I have a page layout view, roughly based on the one in TextEdit although not quite the same. When text gets loaded into the page layout view, I need to force layout so that at least the first few pages get added (or removed if I'm replacing text that was already in there) properly. So far, I have been using the following code to force layout of the text - and this is again based on code from the TextEdit sources - which has mostly worked fine:
- (void)forceInitialLayout
{
NSUInteger len, loc = MIN(50000,[[self textStorage] length]);
if ((len = [[self textStorage] length]) > 0)
{
NSRange glyphRange;
if (loc >= len) loc = len - 1;
// Find out which glyph index the desired character index corresponds to
glyphRange = [[selflayoutManager] glyphRangeForCharacterRange:NSMakeRange(loc, 1) actualCharacterRange:NULL];
if (glyphRange.location > 0)
{
// Now cause layout by asking a question which has to determine where the glyph is
(void)[[selflayoutManager] textContainerForGlyphAtIndex:glyphRange.location- 1effectiveRange:NULL];
}
}
}
(Note that 50,000 is just an arbitrary number of characters to get the initial layout going before the user sees the view, so that the user doesn't see pages suddenly appearing or disappearing.)
As I say, this generally works fine, but I have just found a special case. If there are two pages of text, and the second page only has an image on it, and if this image was forced across to the second text container because there wasn't enough space in the first, the above method will not force layout of the second container, only the first. The result is that there should be two pages but only one appears on screen until the user scrolls,when it suddenly pops in. If I type some text after the image and try again, it works fine, but if there is just an image that has been forced onto the second page, it doesn't work.
Now, as I understand it, all the above code from TextEdit does is ask a question of the layout manager that will force layout up to the given character (in the above method, up to the character at index 50,000 or up to the end of the text, whichever comes first). My guess is that asking for -textContainerForGlyphAtIndex: doesn't necessarily take into account the fact that an image might get pushed across to another page if it is too big, and may return the container it was initially intended for instead (even though the docs say that the method will return the text container in which it is laid out). So I figured I'd try asking the layout manager some different questions which, according to the docs, should cause layout. -locationForGlyphAtIndex: seems to do the job:
- (void)forceInitialLayout
{
NSInteger charIndex = (50000 > [[self textStorage] length] ? [[self textStorage] length] : 50000);
if (charIndex > 0)
{
charIndex -= 1;
[layoutManagerlocationForGlyphAtIndex:charIndex];
}
}
The above code correctly lays out both pages whereas the original didn't.
So my question is, is using -locationForGlyphAtIndex: just as valid a way of doing it, or is there a good reason Apple used -textContainerForGlyphAtIndex: instead? Or is there a better way to force the initial layout of text that will spill across multiple text containers?
Many thanks and all the best,
Keith
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden