MacOS 开发(十二):选择状态下NSTextField字体变化解决方案

402 阅读1分钟

一、需求来源

遇到一个需求:要在 NSTextField/NSTextView 中显示可点击富文本(跳转网页)

WX20190628-081925.png

二、使用示例

@property (nonatomic, strong) NSTextField * textFieldOne;
- (NSTextField *)textFieldOne{
    if (!_textFieldOne) {
        _textFieldOne = ({
            NSTextField *view = [[NSTextField alloc]init];
            
            view.cell.scrollable = true;
            
            view.font = [NSFont fontWithName:@"PingFangSC-Light" size:14];
            view.cell.wraps = true;
            
            view.editable = false;
            view.selectable = true;
            view.allowsEditingTextAttributes = true;
            if (@available(macOS 10.12.2, *)) {
                view.automaticTextCompletionEnabled = true;
            } else {
                // Fallback on earlier versions
            }
            view;
        });
    }
    return _textFieldOne;
}
//key为超链接字符串:value为网络地址
NSDictionary *dic = @{
                      @"github/shang1219178163": @"https://github.com/shang1219178163",
                          };
self.textFieldOne.stringValue = [NSString stringWithFormat:@"%@\n%@\n%@", NSApplication.appName, NSApplication.appCopyright, @"github/shang1219178163"];
    [self.textFieldOne setHyperlinkDic:dic];

三、源码 NSTextField 扩展方法

#import "NSTextField+Helper.h"
-(void)setHyperlinkDic:(NSDictionary *)dic{
    // both are needed, otherwise hyperlink won't accept mousedown
    NSTextField *textField = self;
    
    NSDictionary * attributes = @{
                                  NSFontAttributeName: textField.font,
                                  };
    
    NSAttributedString * attStr = [[NSAttributedString alloc]initWithString:textField.stringValue attributes:attributes];
    
    __block NSMutableAttributedString * mattStr = [[NSMutableAttributedString alloc]init];
    [mattStr replaceCharactersInRange:NSMakeRange(0, 0) withAttributedString:attStr];
    [dic enumerateKeysAndObjectsUsingBlock:^(NSString * key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        NSURL *url = [NSURL URLWithString:obj];
        NSAttributedString * attStr = [NSAttributedString hyperlinkFromString:key withURL:url font:textField.font];
        NSRange range = [mattStr.string rangeOfString:key];
        [mattStr replaceCharactersInRange:range withAttributedString:attStr];
        
    }];
    textField.attributedStringValue = mattStr;
    
    textField.cell.wraps = true;
    textField.cell.scrollable = true;
    textField.editable = false;
    textField.selectable = true;
    textField.allowsEditingTextAttributes = true;
}

四、源码 NSAttributedString 扩展方法

#import "NSAttributedString+Helper.h"
+(id)hyperlinkFromString:(NSString *)string withURL:(NSURL *)aURL font:(NSFont *)font{
    NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString: string];
    
    NSRange range = NSMakeRange(0, attrString.length);
    
//    NSMutableParagraphStyle *paraStyle = [[NSMutableParagraphStyle alloc]init];
    NSDictionary * dic = @{
                           NSFontAttributeName: font,
                           NSForegroundColorAttributeName: NSColor.blueColor,
                           NSLinkAttributeName: aURL.absoluteString,
                           NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle),
//                           NSParagraphStyleAttributeName: paraStyle,
//                           NSBaselineOffsetAttributeName: @15,
                           };
    
    
    [attrString beginEditing];
    [attrString addAttributes:dic range:range];
    [attrString endEditing];
    return attrString;
}

AuthorInfoController.m