This article explains some programmatic techniques using the Cocoa text system to accomplish simple tasks which may not be obvious until you see how they’re done.
Appending Text to a View
Setting Font Styles and Traits
Getting the View Coordinates of a Glyph
This section shows how to use NSTextView methods to append a text string to the text in the view. It also scrolls the text in the view to ensure that the newly appended text is visible.
This code fragment defines a zero-length range of text beginning at the end of the NSTextStorage belonging to the text view. Then it replaces the zero-length range with the string, effectively appending it to the original text storage string, accessed through the text view. Finally, it resets the length of the range to that of the full string in the text view and scrolls the view to make the end of the new range visible.
NSTextView *myView; |
NSString *myText; |
NSRange endRange; |
endRange.location = [[myView textStorage] length]; |
endRange.length = 0; |
[myView replaceCharactersInRange:endRange withString:myText]; |
endRange.length = [myText length]; |
[myView scrollRangeToVisible:endRange]; |
This section shows how to programmatically set font styles, such as bold or italic, and font attributes, such as underlining, in an attributed string.
Underlining is an attribute that can be easily set on an attributed string, using the NSUnderlineStyleAttributeName
constant, as explained in the Cocoa Foundation reference documentation for NSMutableAttributedString. Use the following method:
- (void)addAttribute:(NSString *)name value:(id)value range:(NSRange)aRange |
Pass NSUnderlineStyleAttributeName
for the name argument with a value of [NSNumber numberWithInt:1]
.
Unlike underlining, bold and italic are traits of the font, so you need to use a font manager instance to convert the font to have the desired trait, then add the font attribute to the mutable attributed string. For a mutable attributed string named attributedString
, use the following technique:
NSFontManager *fontManager = [NSFontManager sharedFontManager]; |
unsigned idx = range.location; |
NSRange fontRange; |
NSFont *font; |
while (NSLocationInRange(idx, range)){ |
font = [attributedString attribute:NSFontAttributeName atIndex:idx |
longestEffectiveRange:&fontRange inRange:range]; |
fontRange = NSIntersectionRange(fontRange, range); |
[attributedString applyFontTraits:NSBoldFontMask range:fontRange]; |
idx = NSMaxRange(fontRange); |
} |
If your mutable attributed string is actually an NSTextStorage object, place this code between beginEditing
and endEditing
calls.
Glyph locations are figured relative to the origin of the bounding rectangle of the line fragment in which they are laid out. To get the rectangle of the glyph’s line fragment in its container coordinates, use
lineFragmentRectForGlyphAtIndex:effectiveRange: |
Then add the origin of that rectangle to the location of the glyph returned by
locationForGlyphAtIndex: |
to get the glyph location in container coordinates.
The following code fragment from the CircleView example illustrates this technique.
usedRect = [layoutManager usedRectForTextContainer:textContainer]; |
NSRect lineFragmentRect = [layoutManager lineFragmentRectForGlyphAtIndex:glyphIndex |
effectiveRange:NULL]; |
NSPoint viewLocation, layoutLocation = [layoutManager |
locationForGlyphAtIndex:glyphIndex]; |
// Here layoutLocation is the location (in container coordinates) where the glyph was laid out. |
layoutLocation.x += lineFragmentRect.origin.x; |
layoutLocation.y += lineFragmentRect.origin.y; |
© 1997, 2009 Apple Inc. All Rights Reserved. (Last updated: 2009-04-08)