我是Mac OS 10.11(非iOS)的Cocoa / Swift应用程序的新手。我创建了NSView
,其大小为A4
纸张,在NSString.drawAtPoint
中使用drawRect()
绘制了一些简单的线条和一些文字。到目前为止它的确有效。
然而,有时我需要将几个字符转为90度,而某些文字需要在X或Y方向缩放。这是我不知道该怎么做的地方。请有人能告诉我如何实现这些目标吗?
非常感谢。
答案 0 :(得分:3)
您可以使用NSAffineTransform
。此代码将大写字母“A”顺时针旋转90度:
[NSGraphicsContext saveGraphicsContext]; // save current affine transform
[[[NSAffineTransform transform] rotateByDegrees:90] concat];
[@"A" drawAtPoint:point withAttributes:@{}];
[NSGraphicsContext restoreGraphicsContext]; // restore original transform
请注意rotateByDegrees
围绕原点旋转图形上下文。如果要围绕其他点旋转,则需要添加几个翻译。这个concat
变换围绕rotatePoint
旋转:
NSAffineTransform *transform = [NSAffineTransform transform];
[transform translateXBy:rotatePoint.x yBy:rotatePoint.y];
[transform rotateByDegrees:90];
[transform translateXBy:-rotatePoint.x yBy:-rotatePoint.y];
[transform contat];
答案 1 :(得分:1)
以下是使用Swift 3.1 for cocoa / macOS的类似答案。为了应用旋转和其他常见变换,在图形上下文中添加了一些便捷方法,而无需创建单独的AffineTransform。
这里要记住的真正诀窍是,当您旋转上下文时,您正在旋转整个坐标系,因此您必须将要在非旋转上下文中绘制文本的点转换为旋转上下文中的重叠点。
func drawVerticalText(text: String, withAttributes attributes: [String : Any]?, origin: CGPoint, context: CGContext) {
// Draws text that rotated 90 degrees ( pi/2 radians ) counterclockwise.
/*
Rotate entire drawing context 90 degrees clockwise including axis orientation!
i.e. the positive Y axis is pointing to the left instead of up, and positive X axis
is pointing up instead of to the right. This also means that anything drawn having
two positive x and y coordinates will be rendered off screen of the current view.
*/
let halfRadian : CGFloat = CGFloat.pi / 2.0
context.rotate(by: halfRadian )
/*
In order to have the text rendered in our current view, we have to find a point in our
rotated context, that overlays the point where we want to draw the text in our non-rotated
context. The x-axis is horizontal in the non-rotated context (ascending values to the
right), while the y-axis is horizontal in our rotated context (ascending values to the
left). So our oppisite value of our x coordinate in the non-rotated context must be
mapped to the y-axis in our rotated context. Accordingly, the y-axis is vertical in our
non-rotated context (ascending values upwards), while x-axis is vertical in our rotated
context (ascending values upwards). So our y value in the non-rotated context must be
mapped to the x-axis in our rotated context. i.e. If we graph a point (Y,-X) in our rotated
context, it will overlap the point (X,Y) in our non-rotated context.
*/
// The origin represents the lower left corner of the rectangle in which the text will be rendered.
let translatedOrigin = NSPoint(x: origin.y, y: -origin.x)
// Draw the text.
text.draw(at: translatedOrigin, withAttributes: attributes)
// Rotate the context counter-clockwise 90 degrees ( pi/2 radians ) after we are done.
context.rotate(by: -halfRadian )
}
以下是NSView中的调用内容:
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
let context = NSGraphicsContext.current()?.cgContext
drawVerticalText(text: "My text string", withAttributes: nil, origin: CGPoint(x: 50.0, y: 100.0) , context: context!)
}