编程实现NSTextView中选择的文字切换粗体

本文介绍如何使用NSTextView和NSAttributedString操作,通过枚举选区内的字体属性,针对粗体和非粗体进行统一修改,包括使用NSFontDescriptor、NSFontManager和block处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里和文字相关的,一般涉及到NSTextStorage(文本编辑)、NSFont(字体)和NSFontDescriptor(字体信息描述)、NSFontManager(字体管理器)

首先要textView(统一用它代表NSTextView的实例)得到选中的范围:

NSArray *aArray = textView.selectedRanges;
if(!aArray || aArray.count==0)
{
    return;
}
NSRange selectedRange = [(NSValue *)[aArray objectAtIndex:0] rangeValue];  //常见的选中范围是一个,想要通用,可以for一把

想要修改文字属性,需要通知textStorage:

    NSTextStorage *textStorage = [textView textStorage];
    [textStorage beginEditing];   //开始编辑

    //这里是编辑过程。。。。

    [textStorage endEditing];    //结束编辑

最后需要通知textView文本已经更新了:

[textView didChangeText];

整个流程已经实现,打完收工?

不不不,上面是总括流程,还有中间细节需要处理(编辑过程)

这里需要用到NSTextStorage的操作

- (void)enumerateAttributesInRange:(NSRange)enumerationRange options:(NSAttributedStringEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(NSDictionary<NSAttributedStringKey, id> *attrs, NSRange range, BOOL *stop))block API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));

这个操作主要是枚举选中范围内的所有字体属性,例如我们选中“123ABC“,其中123已经是粗体,但是ABC不是,这里就可能枚举出2个范围,也可能更多,比如123是Arial,AB可能是宋体,C可能其他字体。所有必须枚举完这些,注意修改属性。

如上述,选中的文字包含粗体和非粗体的,在著名的编辑软件都是先同意修改成粗体或非粗体,我选择是对第一个枚举的范围属性做标识,然后后面的都根据第一个标识统一修改。

这里需要用到穿越block的参数标识”__block“。

在块里面,可以得到通过NSDictionary *attributesDictionary传递的字体信息

NSFont *font = [attributesDictionary objectForKey:NSFontAttributeName];

然后对font分析是否已经设置为粗体:

             NSFontDescriptor *desc=font.fontDescriptor;
             NSFontDescriptorSymbolicTraits symbolic_traits=desc.symbolicTraits;
             if (!hasChange)
             {
                 hasChange=YES;
                 //NSFontDescriptorTraitBold == NSBoldFontMask
                 if ((symbolic_traits & NSFontDescriptorTraitBold)==0) {
                     //if not bold then set to bold
                     bold_flag=1;
                 }
             }

通过将font放置到通用的NSFontManager,然后进行修改,重新读出来:

             NSUInteger traits = (NSUInteger)symbolic_traits;
             NSFontManager *fontManager = [NSFontManager sharedFontManager];
             [fontManager setSelectedFont:font isMultiple:NO];
             //weight(0~9);default=5
             font = [fontManager fontWithFamily:font.familyName traits:(traits) weight:5 size:(font.pointSize)];

对选中字体切换字体的过程就这么多。中间还有一个很小很小的细节留给读者补充^_^

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值