案例:属性字符串已创建。如何改变字符串的大小?核心文本/ NSStringDrawing - CFAttributedStringRef/NSAttributedString - 更改字体大小
我猜我们既可以
A)更新的pointsize所有字体的属性串
B)绘制属性串一些变换
案例:属性字符串已创建。如何改变字符串的大小?核心文本/ NSStringDrawing - CFAttributedStringRef/NSAttributedString - 更改字体大小
我猜我们既可以
A)更新的pointsize所有字体的属性串
B)绘制属性串一些变换
能正常工作在Mac OS和iOS
@implementation NSAttributedString (Scale)
- (NSAttributedString *)attributedStringWithScale:(double)scale
{
if(scale == 1.0)
{
return self;
}
NSMutableAttributedString *copy = [self mutableCopy];
[copy beginEditing];
NSRange fullRange = NSMakeRange(0, copy.length);
[self enumerateAttribute:NSFontAttributeName inRange:fullRange options:0 usingBlock:^(UIFont *oldFont, NSRange range, BOOL *stop) {
double currentFontSize = oldFont.pointSize;
double newFontSize = currentFontSize * scale;
// don't trust -[UIFont fontWithSize:]
UIFont *scaledFont = [UIFont fontWithName:oldFont.fontName size:newFontSize];
[copy removeAttribute:NSFontAttributeName range:range];
[copy addAttribute:NSFontAttributeName value:scaledFont range:range];
}];
[self enumerateAttribute:NSParagraphStyleAttributeName inRange:fullRange options:0 usingBlock:^(NSParagraphStyle *oldParagraphStyle, NSRange range, BOOL *stop) {
NSMutableParagraphStyle *newParagraphStyle = [oldParagraphStyle mutableCopy];
newParagraphStyle.lineSpacing *= scale;
newParagraphStyle.paragraphSpacing *= scale;
newParagraphStyle.firstLineHeadIndent *= scale;
newParagraphStyle.headIndent *= scale;
newParagraphStyle.tailIndent *= scale;
newParagraphStyle.minimumLineHeight *= scale;
newParagraphStyle.maximumLineHeight *= scale;
newParagraphStyle.paragraphSpacing *= scale;
newParagraphStyle.paragraphSpacingBefore *= scale;
[copy removeAttribute:NSParagraphStyleAttributeName range:range];
[copy addAttribute:NSParagraphStyleAttributeName value:newParagraphStyle range:range];
}];
[copy endEditing];
return copy;
}
@end
快乐编码
我相信在解析是唯一的出路。归属字符串的格式可能非常复杂,您的工作是增加字体大小。
但是,如果您需要这种渲染技巧,您可以避免字符串解析 - 使用缩放变换来增加文本大小。
我使用下面的代码。其中一个错误是,如果属性字符串中的某些文本没有被设置为字体属性,它将不会被更新。所以我不得不用font-attributes来封装所有东西。
- (void)recalculateSizeChangeInAttributedString {
if(self.attributedStringOriginal == nil) {
self.attributedStringOriginal = [self.attributedString copy];
}
CFMutableAttributedStringRef tempString = CFAttributedStringCreateMutableCopy(CFAllocatorGetDefault(), self.attributedStringOriginal.length, (CFMutableAttributedStringRef)self.attributedStringOriginal);
int lastIndex = 0;
int limit = CFAttributedStringGetLength(tempString);
for (int index = 0; index < limit;) {
CFRange inRange = CFRangeMake(0, limit - index);
CFRange longestEffective;
CTFontRef font = (CTFontRef)CFAttributedStringGetAttribute(tempString, index, kCTFontAttributeName, &longestEffective);
if(font != nil) {
// log for testing
NSLog(@"index: %i, range: %i - %i, longest: %i - %i, attribute: %@",
index, inRange.location,
inRange.location + inRange.length,
longestEffective.location, longestEffective.location + longestEffective.length,
@"..."
);
// alter the font and set the altered font/attribute
int rangeEnd = longestEffective.length != 0 ? longestEffective.length : 1;
CTFontRef modifiedFont = CTFontCreateCopyWithAttributes(font, CTFontGetSize((CTFontRef)font) * sizeFactor, NULL, NULL);
CFAttributedStringSetAttribute(tempString, CFRangeMake(index, rangeEnd), kCTFontAttributeName, modifiedFont);
CFRelease(modifiedFont);
}
// make next loop continue where current attribute ended
index += longestEffective.length;
if(index == lastIndex)
index ++;
lastIndex = index;
}
self.attributedString = (NSMutableAttributedString *)tempString;
CFRelease(tempString);
}
“在Mac OS和iOS上都可以正常工作”是否在OS X中提供了UIFont? – 2015-10-30 14:12:29
另外,' - [UIFont fontWithSize:]'有什么问题? – 2015-10-30 14:18:32
对,只需要用NSFont替换即可。我目前不记得这个问题是什么,但我认为它试图以非常错误的方式变得聪明。如果我没有记错,我得到了错误的字体家族!相当震撼。我在什么地方写过关于它,我会看看我能否找到它。 – hfossli 2015-10-30 22:38:26