【发布时间】:2018-08-13 03:00:13
【问题描述】:
我正在尝试创建一个可以在 NSView 中拖动和旋转的对象,并且使用 NSBezierPath 成功地做到了这一点。我正在创建多个对象并将它们存储在一个类中,并使用 NSBezierPath.transform(using: AffineTransform) 来修改路径以响应拖动和旋转输入。
这一切都很好,但我现在想在形状中添加文本,似乎有一组不同的规则来处理文本。
我尝试通过创建 CTFrame 来使用 Core Text,但不知道如何移动或旋转它。
文本处理与 NSBezierPath 如此不同是否有充分的理由。
然后是AffineTransform和CGAffineTransform的区别。整个事情非常令人困惑,似乎很难找到解释差异的良好文档。
下面是创建和移动看起来完美的形状的代码。我不知道如何移动文本,理想情况下不必重新创建它。有什么方法可以平移和旋转 CTFrame?
var path: NSBezierPath
var location: NSPoint {
didSet {
// move()
}
}
var angle: CGFloat {
didSet {
let dx = angle - oldValue
rotate(dx)
}
}
func createPath(){
// Create a simple path with a rectangle
self.path = NSBezierPath(rect: NSRect(x: -1*width/2.0, y: -1*height/2.0, width: width, height: height))
let line = NSBezierPath()
line.move(to: NSPoint(x: width/2.0, y:0))
line.line(to: NSPoint(x: width/2.0+leader, y:0))
self.path.append(line)
// Label !!
let rect = NSRect(x: width/2.0, y: 0, width: leader, height: height/2.0)
let attrString = NSAttributedString(string: assortmentLabel, attributes: attributesForLeftText)
self.labelFrame = textFrame(attrString: attrString, rect: rect)
// ??? How to rotate the CTFrame - is this even possible
move()
rotate(angle)
}
func rotate(_ da: CGFloat){
// Move to origin
let loc = AffineTransform(translationByX: -location.x, byY: -location.y)
self.path.transform(using: loc)
let rotation = AffineTransform(rotationByDegrees: da)
self.path.transform(using: rotation)
// Move back
self.path.transform(using: AffineTransform(translationByX: location.x, byY: location.y))
}
func move(){
let loc = AffineTransform(translationByX: location.x, byY: location.y)
self.path.transform(using: loc)
}
func draw(){
guard let context = NSGraphicsContext.current?.cgContext else {
return
}
color.set()
path.stroke()
if isSelected {
path.fill()
}
if let frame = self.labelFrame {
CTFrameDraw(frame, context)
}
}
// -----------------------------------
// Modify the item location
// -----------------------------------
func offsetLocationBy(x: CGFloat, y:CGFloat)
{
location.x=location.x+x
location.y=location.y+y
let loc = AffineTransform(translationByX: x, byY: y)
self.path.transform(using: loc)
}
编辑:
我做了一些改变,现在在原点 0,0 处绘制形状,然后在绘制形状之前将转换应用于 CGContext。 这完成了工作,现在使用 CTDrawFrame 可以正常工作...
差不多……
在我的测试应用上它运行良好,但是当我将完全相同的代码集成到生产应用中时,文本出现上下颠倒,所有字符都显示在彼此之上。
据我所知,进行绘图的视图没有什么不同 - 使用相同的 NSView 子类。
是否还有其他可能扰乱文本绘制的东西 - 似乎是一个 isFlipped 问题,但为什么会在一个应用程序而不是另一个应用程序中发生这种情况。
其他一切似乎都正确绘制。扯掉我的头发。
【问题讨论】: