Re: How is 'truncate last visible line' accomplished?
Re: How is 'truncate last visible line' accomplished?
- Subject: Re: How is 'truncate last visible line' accomplished?
- From: Jim McGowan <email@hidden>
- Date: Sat, 03 Jul 2010 23:52:08 +0800
On 3 Jul 2010, at 21:17, Graham Cox wrote:
>
>> How is 'truncate last visible line' accomplished for wrapped text?
>>
>> I have a custom cell that I would like to have this behaviour in. Most of the system controls/cells support this but it's not clear how it's done for custom cells. I thought it would be a paragraph style attribute but I don't see anything there.
>
>
> The simple solution seems to be to use [NSAttributedString drawWithRect:options:]
>
Not exactly the same issue, but this may help: recently I was working on an NSTextView subclass that needed to have 'truncate last visible line' behaviour (when not being edited). I got this working by iterating through the line fragments until I found one that did not entirely fit within the view's visibleRect, then replaced the whitespace character preceding that line with a \n, essentially creating a new paragraph at that point - this was the only way I could figure to get the truncation happening in the right place, but had the benefit of causing the text system to re-layout. Obviously this needed updating when the view was resized, and cleared out when the view became 1st responder. The code looked like this:
// ivars
NSUInteger _tempTruncatingBreakIndex = UINT_MAX;
BOOL _textIsTruncated = NO;
- (void)reTruncateLastVisibleLine
{
NSUInteger length = [[self textStorage] length];
if ( (!self.truncatesLastVisibleLine) || (length == 0) )
{
return;
}
// remove previously inserted temporary line break
if (_tempTruncatingBreakIndex != UINT_MAX)
{
NSMutableAttributedString *str = [[[self textStorage] mutableCopy] autorelease];
[str deleteCharactersInRange:NSMakeRange(_tempTruncatingBreakIndex, 1)];
[[self textStorage] setAttributedString:str];
_tempTruncatingBreakIndex = UINT_MAX;
length = [[self textStorage] length];
}
// clear the old truncating style
NSMutableParagraphStyle *paraStyle = [[[[self textStorage] attribute:NSParagraphStyleAttributeName atIndex:0 effectiveRange:NULL] mutableCopy] autorelease];
if(paraStyle == nil)
{
paraStyle = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease];
}
[paraStyle setLineBreakMode:NSLineBreakByWordWrapping];
[[self textStorage] addAttribute:NSParagraphStyleAttributeName value:paraStyle range:NSMakeRange(0, length)];
_textIsTruncated = NO;
// walk through each line from the top and find the first one that is not fully visible
NSUInteger lineIndex, glyphIndex, glyphCount = [[self layoutManager] numberOfGlyphs], preccedingLineStartIndex = 0;
NSRange lineRange = MWZeroRange, styleRange;
for (lineIndex = 0, glyphIndex = 0; glyphIndex < glyphCount; lineIndex++)
{
NSRect lineRect = [[self layoutManager] lineFragmentUsedRectForGlyphAtIndex:glyphIndex effectiveRange:&lineRange];
if(!NSContainsRect([self visibleRect], lineRect))
{
_textIsTruncated = YES;
if(preccedingLineStartIndex == 0)
{
// there is only 1 line, so apply the truncating para style to the whole string
styleRange = NSMakeRange(0, length);
}
else
{
// the text is clipped after the first line. insert a temp line break at the begining of the last full line & apply the truncating style from there
_tempTruncatingBreakIndex = preccedingLineStartIndex;
[[self textStorage] replaceCharactersInRange:NSMakeRange(_tempTruncatingBreakIndex, 0) withString:@"\n"];
styleRange = NSMakeRange(_tempTruncatingBreakIndex + 1, [[self textStorage] length] - (_tempTruncatingBreakIndex + 1));
}
// apply the truncating style
[paraStyle setLineBreakMode:NSLineBreakByTruncatingTail];
[[self textStorage] addAttribute:NSParagraphStyleAttributeName value:paraStyle range:styleRange];
break;
}
glyphIndex = NSMaxRange(lineRange);
preccedingLineStartIndex = lineRange.location;
}
}
Attachment:
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________
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