【问题标题】:NSView drawing explainedNSView绘图解释
【发布时间】: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 问题,但为什么会在一个应用程序而不是另一个应用程序中发生这种情况。

其他一切似乎都正确绘制。扯掉我的头发。

【问题讨论】:

    标签: macos cgcontext core-text


    【解决方案1】:

    经过一番努力,我似乎​​很幸运,测试应用程序完全可以正常工作,并且需要在两个应用程序上设置 textMatrix,以确保在所有条件下都能正常工作。

    似乎也无法创建 CTFrame,然后只是对其进行缩放并重新绘制它——好吧,它对我不起作用,所以我每次都必须在 draw() 方法中重新创建它!

    【讨论】:

      猜你喜欢
      • 2016-01-24
      • 1970-01-01
      • 2013-02-16
      • 1970-01-01
      • 2011-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多