I have a UITextView with a custom NSTextLayout:
VPLayoutManager.h
#import <UIKit/UIKit.h>
@interface VPLayoutManager : NSLayoutManager <NSLayoutManagerDelegate>
@end
VPLayoutManager.m
#import "VPLayoutManager.h"
@implementation VPLayoutManager
- (id)init
{
self = [super init];
if (self) {
self.delegate = self;
}
return self;
}
- (void)drawGlyphsForGlyphRange:(NSRange)glyphsToShow atPoint:(CGPoint)origin
{
//[super drawGlyphsForGlyphRange:glyphsToShow atPoint:origin];
[self enumerateLineFragmentsForGlyphRange:glyphsToShow usingBlock:^(CGRect rect, CGRect usedRect, NSTextContainer *textContainer, NSRange glyphRange, BOOL *stop) {
NSRange characterRange = [self characterRangeForGlyphRange:glyphRange actualGlyphRange:nil];
NSRange paragraphRange = [self.textStorage.string paragraphRangeForRange:characterRange];
if (characterRange.location == paragraphRange.location) {
NSString *listCharacter = [self.textStorage.string substringWithRange:NSMakeRange(glyphRange.location, 1)];
if ([listCharacter isEqualToString:@"\u2063"]) {
CGRect listRect = CGRectOffset(CGRectMake(usedRect.origin.x - 10.0f, usedRect.origin.y, 40.0f, usedRect.size.height), origin.x, origin.y);
NSDictionary *attributes = @{NSFontAttributeName : [UIFont systemFontOfSize:20.0f],
NSForegroundColorAttributeName : [UIColor blackColor]};
[@"-" drawInRect:listRect withAttributes:attributes];
//[super drawGlyphsForGlyphRange:glyphRange atPoint:origin];
}
else {
//[super drawGlyphsForGlyphRange:glyphRange atPoint:origin];
}
}
}];
[super drawGlyphsForGlyphRange:glyphsToShow atPoint:origin];
}
- (NSUInteger)layoutManager:(NSLayoutManager *)layoutManager shouldGenerateGlyphs:(const CGGlyph *)glyphs properties:(const NSGlyphProperty *)props characterIndexes:(const NSUInteger *)charIndexes font:(UIFont *)aFont forGlyphRange:(NSRange)glyphRange
{
if (glyphRange.length > 1) {
NSGlyphProperty *properties = malloc(sizeof(NSGlyphProperty) * glyphRange.length);
NSString *substring = [self.textStorage.string substringWithRange:glyphRange];
for (NSUInteger i = 0; i < glyphRange.length; i++) {
properties[i] = props[i];
}
NSRange regex = [substring rangeOfString:@"\u2063" options:NSRegularExpressionSearch];
if (regex.location != NSNotFound) {
for (NSUInteger i = regex.location; i < regex.length; i++) {
#warning crash on new-line if not at the end of the list
properties[i] = NSGlyphPropertyControlCharacter;
}
}
[layoutManager setGlyphs:glyphs properties:properties characterIndexes:charIndexes font:aFont forGlyphRange:glyphRange];
return glyphRange.length;
}
[layoutManager setGlyphs:glyphs properties:props characterIndexes:charIndexes font:aFont forGlyphRange:glyphRange];
return glyphRange.length;
}
- (NSControlCharacterAction)layoutManager:(NSLayoutManager *)layoutManager shouldUseAction:(NSControlCharacterAction)action forControlCharacterAtIndex:(NSUInteger)charIndex
{
NSString *substring = [layoutManager.textStorage.string substringWithRange:NSMakeRange(charIndex, 1)];
if ([substring isEqualToString:@"\u2063"]) {
return NSControlCharacterZeroAdvancementAction;
}
return action;
}
@end
This code hides the glyph but the UITextView still sees the glyph (the cursor still "shows" that there is a glyph in that position even if is now invisible)... so the question is: how do I completely hide a glyph?
I'm trying to create lists based on a character on the start of a paragraph, the idea was to add a unicode that identifies if the paragraph is part of a list, and inside NSTextLayout, hide this unicode and do the proper operation for "draw" the list.