• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: How is 'truncate last visible line' accomplished?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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

  • Prev by Date: Re: Calling javascript from Cocoa 'facelessly'
  • Next by Date: Re: Calling javascript from Cocoa 'facelessly'
  • Previous by thread: Re: How is 'truncate last visible line' accomplished?
  • Next by thread: NSAttributedString & iOS 4
  • Index(es):
    • Date
    • Thread