gpt4 book ai didi

swift - 使用自定义 NSTextBlock 保存和粘贴属性字符串

转载 作者:行者123 更新时间:2023-12-02 11:20:35 25 4
gpt4 key购买 nike

我正在尝试创建一个自定义 NSTextBlock,就像 Apple 在 WWDC 18 ( 23 mins in ) 上所做的那样。

Full demo project here .

好的,所以当我使用附加了文本块的段落样式编辑和标记段落时,它非常有效。

enter image description here

但是当我剪切和粘贴它(或从磁盘存档/取消存档)时,它会丢失它。编辑:它实际上变成了我的 TweetTextBlock子类变成 NSTableViewTextBlock ,这也解释了边界。

enter image description here

实现

Here's a full Xcode project .使用 Format顶部菜单项触发 markTweet功能。

这是我向段落添加属性的方法

    @IBAction func markTweet(_ sender : Any?){
print("now we are marking")
let location = textView.selectedRange().location


guard let nsRange = textView.string.extractRange(by: .byParagraphs, at: location) else { print("Not in a paragraph"); return }

let substring = (textView.string as NSString).substring(with: nsRange)

let tweetParagraph = NSMutableParagraphStyle()
tweetParagraph.textBlocks = [TweetTextBlock()]

let twitterAttributes : [AttKey : Any] = [
AttKey.paragraphStyle : tweetParagraph,
AttKey.font : NSFont(name: "HelveticaNeue", size: 15)
]

textView.textStorage?.addAttributes(twitterAttributes, range: nsRange)
}

这是我的 NSTextBlock子类
import Cocoa

class TweetTextBlock: NSTextBlock {

override init() {
super.init()
setWidth(33.0, type: .absoluteValueType, for: .padding)
setWidth(70.0, type: .absoluteValueType, for: .padding, edge: .minX)

setValue(100, type: .absoluteValueType, for: .minimumHeight)

setValue(300, type: .absoluteValueType, for: .width)
setValue(590, type: .absoluteValueType, for: .maximumWidth)


backgroundColor = NSColor(white: 0.97, alpha: 1.0)

}


override func drawBackground(withFrame frameRect: NSRect, in controlView: NSView,
characterRange charRange: NSRange, layoutManager: NSLayoutManager) {

let frame = frameRect
let fo = frameRect.origin

super.drawBackground(withFrame: frame, in: controlView, characterRange:
charRange, layoutManager: layoutManager)

// draw string
let context = NSGraphicsContext.current
context?.shouldAntialias = true

let drawPoint: NSPoint = CGPoint(x: fo.x + 70, y: fo.y + 10)


let nameAttributes = [AttKey.font: NSFont(name: "HelveticaNeue-Bold", size: 15), .foregroundColor: NSColor.black]
var handleAttributes = [AttKey.font: NSFont(name: "HelveticaNeue", size: 15), .foregroundColor: NSColor(red: 0.3936756253, green: 0.4656872749, blue: 0.5323709249, alpha: 1)]

let nameAStr = NSMutableAttributedString(string: "Johanna Appleseed", attributes: nameAttributes)
let handleAStr = NSAttributedString(string: " @johappleseed · 3h", attributes: handleAttributes)
nameAStr.append(handleAStr)
nameAStr.draw(at: drawPoint)

let im = NSImage(named: "profile-twitter")!
im.draw(in: NSRect(x: fo.x + 10, y: fo.y + 10, width: 50, height: 50))

}

required init?(coder: NSCoder) {
super.init(coder: coder)
}

}


我试过的

我的想法是这可能是因为 TextKit 不知道如何从自定义块中存档属性。但我尝试覆盖 init:fromCoderencode .他们不会被召唤。不适用于复制、粘贴、存档、取消存档。所以我想不是这样。这让我认为所有这些自定义绘图逻辑都不能保存在属性字符串中,而这一切都发生在布局管理器中。那讲得通。但是我如何坚持这个块呢?

更新:我尝试阅读属性。它有一个段落样式,该段落样式在 textBlocks 中有一个项目。数组属性。但该文本块是 NSTextBlock而不是我的子类(我试过 if block is TweetTextBlock 返回 false)

更新 2:我尝试覆盖像 classForArchiver 这样的属性,然后用例如阅读它们 print("twb: Class for archiver", block.classForArchiver) .这里有趣的是文本块变成了 NSTextTableBlock !我现在对黑客攻击如此深入,以至于我正在寻找一种方法来将 className 存储在文本块中的某处。到目前为止,我唯一能想到的就是 tooltip属性,但这对用户是可见的,我可能想将其用于其他用途。

更新 3:工具提示也不保留。这很奇怪。我能想到的下一个大技巧是将文本颜色设置为 HSB (n, 0, 0),其中 n 是 NSTextBlock 子类的标识符。让我们希望我不必去那里。

更新 4。这很可能是由存档和复制/粘贴将字符串转换为 RTF 引起的。这是 public.rtf从我的剪贴板
{\rtf1\ansi\ansicpg1252\cocoartf2509
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;}
{\colortbl;\red255\green255\blue255;\red245\green245\blue245;}
{\*\expandedcolortbl;;\csgray\c97000;}
\pard\intbl\itap1\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0

\f0\fs30 \cf0 THIS text is in a TweetTextBlock}

最佳答案

看来 NSAttributedString 不知何故有问题。我尝试将 NSMutableParagraphStyle 子类化并使用它,但它没有被编码或解码(init)。

可以简单地使用自定义 Attribute.Key 注释文本运行,指示块内容的描述及其“类型”,然后在粘贴后对 AttributedString 进行后处理。

或者,开箱即用的粘贴板类型可能不支持和存档 NSAttributedString。相反,(我猜)最高保真度的文本类型可能是 RTF,这可能解释了根本不调用 TextBlock NSCoding 方法的事实。

看着 NSPasteboard.PasteboardType我的投票是选项 2。

关于swift - 使用自定义 NSTextBlock 保存和粘贴属性字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58620965/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com