2

我的应用程序仅针对 iOS 7。我有一个UITextView演示文稿NSAttributedString。该字符串代表一个文档,每个段落都设置了许多用于样式的属性。有些段落需要全部大写,但是,用户可以将段落的样式更改为常规大写的样式,因此必须保留字符串的原始大写。

我该怎么做呢?我的第一个想法是使用新的 Text Kit 功能并进行某种字形替换,但我很难理解它是如何工作的。另一个想法是创建一个自定义字体,其中所有字符都是大写的。

同样,我不能只更改支持字符串,所以类似的东西uppercaseString不起作用。

4

2 回答 2

2
于 2013-11-01T16:33:53.783 回答
1

这是一篇旧帖子,但由于没有人发布有效的答案,这里有一个。我CFStringRef对 ARC 的操作和桥接的知识有点有限,如下所示。随时更正我的代码。

在你的NSLayoutManagerDelegate,实现shouldGenerateGlyphs

-(NSUInteger)layoutManager:(NSLayoutManager *)layoutManager shouldGenerateGlyphs:(const CGGlyph *)glyphs properties:(const NSGlyphProperty *)props characterIndexes:(const NSUInteger *)charIndexes font:(NSFont *)aFont forGlyphRange:(NSRange)glyphRange {
    // Get correct indices
    NSUInteger location = charIndexes[0];
    NSUInteger length = glyphRange.length;
    
    // Create string reference and convert to uppercase
    CFStringRef str = (__bridge CFStringRef)[self.textStorage.string substringWithRange:(NSRange){ location, length }];
    CFMutableStringRef uppercase = CFStringCreateMutable(NULL, CFStringGetLength(str));
    CFStringAppend(uppercase, str);
    CFStringUppercase(uppercase, NULL);
    
    // Create glyphs for our new uppercase string
    CGGlyph *newGlyphs = GetGlyphsForCharacters((__bridge CTFontRef)(aFont), uppercase);
    [self.layoutManager setGlyphs:newGlyphs properties:props characterIndexes:charIndexes font:aFont forGlyphRange:glyphRange];
    free(newGlyphs);

    return glyphRange.length;
}

CGGlyph* GetGlyphsForCharacters(CTFontRef font, CFStringRef string)
{
    // Get the string length.
    CFIndex count = CFStringGetLength(string);
 
    // Allocate our buffers for characters and glyphs.
    UniChar *characters = (UniChar *)malloc(sizeof(UniChar) * count);
    CGGlyph *glyphs = (CGGlyph *)malloc(sizeof(CGGlyph) * count);
 
    // Get the characters from the string.
    CFStringGetCharacters(string, CFRangeMake(0, count), characters);
 
    // Get the glyphs for the characters.
    CTFontGetGlyphsForCharacters(font, characters, glyphs, count);
 
    // Free the buffers
    free(characters);
    return glyphs;
}

我在等宽文本应用程序中成功使用了此代码,在需要更精细脚本的用例中它可能不会那么稳定。

于 2021-09-27T21:38:00.413 回答