首页 > 其他分享 >Mac开发基础14-NSTextView(二)

Mac开发基础14-NSTextView(二)

时间:2024-08-06 16:29:33浏览次数:7  
标签:searchRange 14 void Mac NSTextView range length textView

进阶使用和技巧

1. 扩展查找和替换功能

可以自定义查找和替换功能,包括高亮查找结果、批量替换等。

查找并高亮

Objective-C
- (void)highlightOccurrencesOfString:(NSString *)searchString {
    // 清除之前的高亮效果
    [textView.layoutManager removeTemporaryAttribute:NSBackgroundColorAttributeName forCharacterRange:NSMakeRange(0, textView.string.length)];
    
    // 查找并高亮指定字符串
    NSString *textViewString = textView.string;
    NSRange searchRange = NSMakeRange(0, textViewString.length);
    while (searchRange.location < textViewString.length) {
        searchRange = [textViewString rangeOfString:searchString options:0 range:searchRange];
        if (searchRange.location != NSNotFound) {
            // 应用高亮颜色
            [textView.layoutManager addTemporaryAttribute:NSBackgroundColorAttributeName value:[NSColor yellowColor] forCharacterRange:searchRange];
            searchRange.location += searchRange.length;
            searchRange.length = textViewString.length - searchRange.location;
        } else {
            break;
        }
    }
}
Swift
func highlightOccurrences(of searchString: String) {
    // 清除之前的高亮效果
    textView.layoutManager?.removeTemporaryAttribute(.backgroundColor, forCharacterRange: NSRange(location: 0, length: textView.string.utf16.count))
    
    // 查找并高亮指定字符串
    let textViewString = textView.string as NSString
    var searchRange = NSRange(location: 0, length: textViewString.length)
    while let foundRange = textViewString.range(of: searchString, options: [], range: searchRange).toRange() {
        // 应用高亮颜色
        textView.layoutManager?.addTemporaryAttribute(.backgroundColor, value: NSColor.yellow, forCharacterRange: NSRange(foundRange))
        searchRange = NSRange(location: foundRange.upperBound, length: textViewString.length - foundRange.upperBound)
    }
}

2. 自动链接检测

NSTextView 具有自动检测和格式化 URL 的功能,可以自动将 URL 链接转换为可点击的超链接。

启用自动链接检测

Objective-C
textView.automaticLinkDetectionEnabled = YES;
Swift
textView.isAutomaticLinkDetectionEnabled = true

3. 自定义上下文菜单

可以为 NSTextView 提供自定义的上下文菜单,以增加更多操作选项。

Objective-C
- (NSMenu *)menuForEvent:(NSEvent *)event {
    NSMenu *menu = [[NSMenu alloc] initWithTitle:@"Context Menu"];
    [menu addItemWithTitle:@"Custom Action" action:@selector(customAction:) keyEquivalent:@""];
    [menu addItemWithTitle:@"Another Action" action:@selector(anotherAction:) keyEquivalent:@""];
    return menu;
}

- (void)customAction:(id)sender {
    NSLog(@"Custom action triggered");
}

- (void)anotherAction:(id)sender {
    NSLog(@"Another action triggered");
}
Swift
override func menu(for event: NSEvent) -> NSMenu? {
    let menu = NSMenu(title: "Context Menu")
    menu.addItem(withTitle: "Custom Action", action: #selector(customAction(_:)), keyEquivalent: "")
    menu.addItem(withTitle: "Another Action", action: #selector(anotherAction(_:)), keyEquivalent: "")
    return menu
}

@objc func customAction(_ sender: Any?) {
    print("Custom action triggered")
}

@objc func anotherAction(_ sender: Any?) {
    print("Another action triggered")
}

4. 自定义文本标记(标注)

可以利用 NSTextViewNSLayoutManagerNSTextStorage 结合 NSAttachment 添加自定义的文本标记或标注。

Objective-C
- (void)addCustomMarkAtRange:(NSRange)range {
    // 创建自定义附件标注
    NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
    NSAttributedString *attachmentString = [NSAttributedString attributedStringWithAttachment:attachment];
    [textView.textStorage insertAttributedString:attachmentString atIndex:range.location];
    
    // 添加自定义属性
    [textView.textStorage addAttributes:@{NSForegroundColorAttributeName: [NSColor redColor]} range:range];
}
Swift
func addCustomMark(at range: NSRange) {
    // 创建自定义附件标注
    let attachment = NSTextAttachment()
    let attachmentString = NSAttributedString(attachment: attachment)
    textView.textStorage?.insert(attachmentString, at: range.location)
    
    // 添加自定义属性
    textView.textStorage?.addAttributes([.foregroundColor: NSColor.red], range: range)
}

5. 处理空格键和回车键

可以自定义处理空格键和回车键,实现更灵活的输入行为。

Objective-C
- (BOOL)textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector {
    if (commandSelector == @selector(insertNewline:)) {
        // 自定义处理回车键
        NSLog(@"Return key pressed");
        return YES;
    } else if (commandSelector == @selector(insertTab:)) {
        // 自定义处理Tab键
        NSLog(@"Tab key pressed");
        return YES;
    }
    return NO;
}
Swift
override func textView(_ textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {
    if commandSelector == #selector(insertNewline(_:)) {
        // 自定义处理回车键
        print("Return key pressed")
        return true
    } else if commandSelector == #selector(insertTab(_:)) {
        // 自定义处理Tab键
        print("Tab key pressed")
        return true
    }
    return false
}

常用工具类封装

下面,我们将封装一个 NSTextView 的工具类,以更灵活地定制 NSTextView 的行为和功能。

Objective-C

@interface NSTextViewHelper : NSObject

@property (nonatomic, strong) NSTextView *textView;

- (instancetype)initWithTextView:(NSTextView *)textView;

- (void)setPlaceholder:(NSString *)placeholder;
- (void)setTextColor:(NSColor *)color;
- (void)setFont:(NSFont *)font;
- (void)setEditable:(BOOL)editable;
- (void)setSelectable:(BOOL)selectable;
- (void)highlightOccurrencesOfString:(NSString *)searchString;
- (void)addCustomMarkAtRange:(NSRange)range;
- (void)setCustomContextMenu;

@end

@implementation NSTextViewHelper

- (instancetype)initWithTextView:(NSTextView *)textView {
    self = [super init];
    if (self) {
        _textView = textView;
    }
    return self;
}

- (void)setPlaceholder:(NSString *)placeholder {
    if ([_textView isKindOfClass:[NSTextView class]]) {
        // 当前没有直接设置占位符的方法,可以通过扩展创建占位符效果
    }
}

- (void)setTextColor:(NSColor *)color {
    [_textView setTextColor:color];
}

- (void)setFont:(NSFont *)font {
    [_textView setFont:font];
}

- (void)setEditable:(BOOL)editable {
    [_textView setEditable:editable];
}

- (void)setSelectable:(BOOL)selectable {
    [_textView setSelectable:selectable];
}

- (void)highlightOccurrencesOfString:(NSString *)searchString {
    // 清除之前的高亮效果
    [_textView.layoutManager removeTemporaryAttribute:NSBackgroundColorAttributeName forCharacterRange:NSMakeRange(0, _textView.string.length)];
    
    // 查找并高亮指定字符串
    NSString *textViewString = _textView.string;
    NSRange searchRange = NSMakeRange(0, textViewString.length);
    while (searchRange.location < textViewString.length) {
        searchRange = [textViewString rangeOfString:searchString options:0 range:searchRange];
        if (searchRange.location != NSNotFound) {
            // 应用高亮颜色
            [_textView.layoutManager addTemporaryAttribute:NSBackgroundColorAttributeName value:[NSColor yellowColor] forCharacterRange:searchRange];
            searchRange.location += searchRange.length;
            searchRange.length = textViewString.length - searchRange.location;
        } else {
            break;
        }
    }
}

- (void)addCustomMarkAtRange:(NSRange)range {
    // 创建自定义附件标注
    NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
    NSAttributedString *attachmentString = [NSAttributedString attributedStringWithAttachment:attachment];
    [_textView.textStorage insertAttributedString:attachmentString atIndex:range.location];
    
    // 添加自定义属性
    [_textView.textStorage addAttributes:@{NSForegroundColorAttributeName: [NSColor redColor]} range:range];
}

- (void)setCustomContextMenu {
    [_textView setMenu:[self customMenu]];
}

- (NSMenu *)customMenu {
    NSMenu *menu = [[NSMenu alloc] initWithTitle:@"ContextMenu"];
    [menu addItemWithTitle:@"Custom Action" action:@selector(customAction:) keyEquivalent:@""];
    [menu addItemWithTitle:@"Another Action" action:@selector(anotherAction:) keyEquivalent:@""];
    return menu;
}

- (void)customAction:(id)sender {
    NSLog(@"Custom action triggered");
}

- (void)anotherAction:(id)sender {
    NSLog(@"Another action triggered");
}

@end

Swift

class NSTextViewHelper {

    private weak var textView: NSTextView?

    init(textView: NSTextView) {
        self.textView = textView
    }

    func setPlaceholder(_ placeholder: String) {
        if let textView = textView {
            // 当前没有直接设置占位符的方法,可以通过扩展创建占位符效果
        }
    }

    func setTextColor(_ color: NSColor) {
        textView?.textColor = color
    }

    func setFont(_ font: NSFont) {
        textView?.font = font
    }

    func setEditable(_ editable: Bool) {
        textView?.isEditable = editable
    }

    func setSelectable(_ selectable: Bool) {
        textView?.isSelectable = selectable
    }

    func highlightOccurrences(of searchString: String) {
        guard let textView = textView else { return }
        
        // 清除之前的高亮效果
        textView.layoutManager?.removeTemporaryAttribute(.backgroundColor, forCharacterRange: NSRange(location: 0, length: textView.string.utf16.count))
        
        // 查找并高亮指定字符串
        let textViewString = textView.string as NSString
        var searchRange = NSRange(location: 0, length: textViewString.length)
        while let foundRange = textViewString.range(of: searchString, options: [], range: searchRange).toRange() {
            // 应用高亮颜色
            textView.layoutManager?.addTemporaryAttribute(.backgroundColor, value: NSColor.yellow, forCharacterRange: NSRange(foundRange))
            searchRange = NSRange(location: foundRange.upperBound, length: textViewString.length - foundRange.upperBound)
        }
    }

    func addCustomMark(at range: NSRange) {
        guard let textView = textView else { return }
        
        // 创建自定义附件标注
        let attachment = NSTextAttachment()
        let attachmentString = NSAttributedString(attachment: attachment)
        textView.textStorage?.insert(attachmentString, at: range.location)
        
        // 添加自定义属性
        textView.textStorage?.addAttributes([.foregroundColor: NSColor.red], range: range)
    }

    func setCustomContextMenu() {
        textView?.menu = customMenu()
    }

    private func customMenu() -> NSMenu {
        let menu = NSMenu(title: "ContextMenu")
        menu.addItem(withTitle: "Custom Action", action: #selector(customAction(_:)), keyEquivalent: "")
        menu.addItem(withTitle: "Another Action", action: #selector(anotherAction(_:)), keyEquivalent: "")
        return menu
    }

    @objc func customAction(_ sender: Any?) {
        print("Custom action triggered")
    }

    @objc func anotherAction(_ sender: Any?) {
        print("Another action triggered")
    }
}

使用示例

Objective-C

NSTextView *textView = [[NSTextView alloc] initWithFrame:NSMakeRect(0, 0, 400, 300)];
NSTextViewHelper *helper = [[NSTextViewHelper alloc] initWithTextView:textView];
[helper setTextColor:[NSColor blueColor]];
[helper setFont:[NSFont fontWithName:@"Helvetica" size:14]];
[helper setEditable:YES];
[helper highlightOccurrencesOfString:@"NSTextView"];
[helper addCustomMarkAtRange:NSMakeRange(0, 5)];
[helper setCustomContextMenu];

Swift

let textView = NSTextView(frame: NSMakeRect(0, 0, 400, 300))
let helper = NSTextViewHelper(textView: textView)
helper.setTextColor(.blue)
helper.setFont(NSFont(name: "Helvetica", size: 14)!)
helper.setEditable(true)
helper.highlightOccurrences(of: "NSTextView")
helper.addCustomMark(at: NSRange(location: 0, length: 5))
helper.setCustomContextMenu()

标签:searchRange,14,void,Mac,NSTextView,range,length,textView
From: https://www.cnblogs.com/chglog/p/18345428

相关文章

  • Xmind2024支持多平台使用,包括Windows、Mac、iOS、等操作系统
    “Xmind2024”是Xmind公司推出的一款全新的思维导图软件,它集成了多种功能,包括智能导图、AI生成、语音输入等。这款产品旨在帮助用户更高效地整理思路,提高思维能力。让我们来了解一下Xmind2024的特点。它采用了全新的设计风格,界面简洁明了,操作便捷。同时,它还提供了丰富的模板......
  • XMind2024思维导图软件特别版+便携版Mac+win+平板
    大家好!今天我们要聊的是一款神奇的思维工具——Xmind2024。你是否常常感到思维混乱,无法集中注意力,或者在处理复杂问题时感到无从下手?如果你有以上的困扰,那么恭喜你,Xmind2024将为你打开一扇全新的大门。让我们先来看看Xmind2024的特点吧。这款产品最大的亮点在于其强大的思维导......
  • Mac开发基础11-NSTextField(一)
    NSTextField是macOS应用中常用的UI元素之一,它用于显示和输入文本。NSTextField提供了丰富的API来定制和处理用户输入。常见API和技巧1.初始化NSTextField程序化创建Objective-CNSTextField*textField=[[NSTextFieldalloc]initWithFrame:NSMakeRect(0,0,20......
  • Mac开发基础12-NSTextField(二)
    NSTextField是一个功能强大的控件,不仅可以作为简单的文本输入框,还可以实现更多高级功能。例如,支持富文本、实现自定义绘制、处理复杂的输入校验等。进阶使用和技巧1.富文本显示与编辑NSTextField支持富文本,也就是说你可以为文本设置不同的颜色、字体、大小等。设置富文本O......
  • Mac开发基础09-NSViewController(一)
    NSViewController简介NSViewController是macOS应用程序中的核心类,用于管理单个视图层次结构。它提供了对视图生命周期、布局管理和内容更新的控制,并与模型数据和其他控制器进行交互,提供了高效的视图控制和管理机制。基础知识点NSViewController继承自NSResponder,它主要用......
  • Mac开发基础10-NSViewController(二)
    1.View-BasedUIUpdatesNSViewController提供了很多优化UI更新的方法。利用这些方法,你可以更有效地管理复杂视图的改变。viewWillLayout该方法在控制器的视图层次结构布局之前调用,可以在此方法中修改子视图的布局。Objective-C-(void)viewWillLayout{[superview......
  • 14. a+aa+...=sum
    题目:求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加有键盘控制。代码:#include<stdio.h>#include<stdlib.h>voidtest(){intsum=0;inta;inttemp;intn;scanf("%d%d",&a,&......
  • Windows 和 MacOS 上安装配置ADB(安卓调试桥)_android adb工具安装 mac
    一、Android调试桥(ADB)Android调试桥(ADB)是一款多功能命令行工具,它让你能够更便捷地访问和管理Android设备。使用ADB命令,你可以轻松执行以下操作网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!在设备上安装、复制和删除文件;安装应用程序;录制设备屏幕或截......
  • 暑假集训CSP提高模拟14
    暑假集训CSP提高模拟14组题人:@H_Kaguya|@LYinMX\(T1\)P209.BA\(30pts\)部分分\(30pts\):输出\(\left\lceil\dfrac{\sum\limits_{i=1}^{m}a_{i}}{n}\right\rceil\)。数形结合,将\(\{a\}\)抽象成矩形,烙饼抽象成海报覆盖,最终有\(\max(\max\limits_{i=1}^{m}......
  • Mac开发基础08-NSWindow(二)
    NSWindow其他使用和技巧NSWindow是macOS应用程序中用于显示和管理窗口的核心类。可用于创建、编辑和管理应用程序的窗口。1.自定义窗口的内容视图层级替换默认的内容视图NSWindow默认包含一个内容视图,你可以使用自定义内容视图来替换它。Objective-CNSView*customVie......