(AppKit) 在 NSTextBlock 快速浏览示例项目:我的尝试

如何解决(AppKit) 在 NSTextBlock 快速浏览示例项目:我的尝试

我正在使用 AppKit 为 macOS 开发一个 Markdown 编辑器,并且已经掌握了所有基础知识并开始工作。我使用 NSTextBlock 作为代码块。

然而,我遇到的一个问题是,在 NSTextBlock 内键入 Tab 会导致插入符号向下移动到下一段,而不是插入 Tab 空格。期望的结果是让用户能够在 NSTextBlock 中插入选项卡。

我创建了一个示例项目来演示 GitHub 上的这种行为。

快速浏览示例项目:

这是一个简单的 AppKit 应用程序。我在 Main.storyboard 的认 ViewController 中添加一个可编辑、可滚动的文本视图。 textView 通过 IBOutlet 连接到 ViewController 类。

自动生成的 viewDidLoad() 方法内部,我调用insertText 函数,我编写该函数将一行文本插入到 NSTextView 中,然后是两个带有 NSTextBlocks 样式的段落。

  func insertText(textStorage: NSTextStorage) {

    //Insert first line of regular text
    var attributes: [NSAttributedString.Key: Any] = [
        .font: NSFont.systemFont(ofSize: 24),.foregroundColor: NSColor.textColor,.backgroundColor: NSColor.clear
    ]
    let attributedString1: NSAttributedString = NSAttributedString(string: "Test\n",attributes: attributes)
    textStorage.append(attributedString1)
    
    //Insert the blue block holdig text
    attributes[.foregroundColor] = NSColor.white
    attributes[.paragraphStyle] = ParagraphStyle(bgColor: NSColor.systemBlue).paragraphStyle
    let attributedBlock1 = NSAttributedString(string: "Hello,I'm the blue block\n",attributes: attributes)
    textStorage.append(attributedBlock1)

    //Insert the pink block holdig text
    attributes[.foregroundColor] = NSColor.black
    attributes[.paragraphStyle] = ParagraphStyle(bgColor: NSColor.systemPink).paragraphStyle
    let attributedBlock2 = NSAttributedString(string: "Hello,I'm the pink block\n",attributes: attributes)
    textStorage.append(attributedBlock2)
}

这样做的效果

enter image description here

如果您启动应用程序并在插入符号位于第一段的开头时尝试插入 Tab,则 Tab 空格会按预期添加到此段的开头。但是,如果您尝试对使用 NSTextBlocks 设置样式的段落执行相同操作,插入符号只会向下移动到下一个段落,并且不会插入 Tab 空格。

我为示例项目编写的另外两个类是 ParagraphStyle 和 CustomTextBlock。

对于 ParagraphStyle 类,保存用于蓝色和粉红色块属性的段落样式:

class ParagraphStyle {

let bgColor: NSColor
let paragraphStyle: NSParagraphStyle

init(bgColor: NSColor) {
    self.bgColor = bgColor
    //Set paragraph style
    self.paragraphStyle = {
        let mutableParagraphStyle = NSMutableParagraphStyle()
        let specialBlock = CustomTextBlock(bgColor: bgColor)
        mutableParagraphStyle.textBlocks.append(specialBlock)
        let style = mutableParagraphStyle as NSParagraphStyle
        return style
    }()
}}

对于继承自 CustomTextBlockNSTextBlock 类,我定义了块的颜色和尺寸:

class CustomTextBlock: NSTextBlock {
        
init(bgColor: NSColor) {
    super.init()
    //Control the BG color of the text block
    self.backgroundColor = bgColor
    //Control dimensions of the text block
    self.setValue(100,type: NSTextBlock.ValueType.percentageValueType,for: NSTextBlock.Dimension.width)
    self.setValue(50,type: NSTextBlock.ValueType.absoluteValueType,for: NSTextBlock.Dimension.minimumHeight)
}

required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}}

我的尝试

  1. 在初始化 ParagraphStyle 类的paragraphStyle 属性值时将NSTextTabs 添加.tabStops 数组。
  2. 通过 addTabStop 方法添加 NSTextTab。
  3. 将值设置为 defaultTabInterval
  4. 将 textView 的 nextkeyviewnextResponder 设置为 nil。

唯一剩下的(我能想到的)就是当 textview 是第一响应者时监听用户按下 tab 键。当事件发生时,我会以编程方式在用户插入符号所在的位置插入 Tab 空格,然后以编程方式将插入符号移回应有的位置。然而,这是解决这个看似简单的问题的一种非常迂回的方法,这就是为什么我相信我可能遗漏了一些明显的东西。希望这里更有经验的开发人员可能有其他建议!

先谢谢你!

解决方法

显然,文本块中的选项卡会将插入点移动到下一个文本块,这在表格中是有意义的。解决方法:子类化 NSTextView,覆盖 insertTab 并插入一个制表符。

override func insertTab(_ sender: Any?) {
    insertText("\t",replacementRange: selectedRange())
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?