I have a very simply macOS app (written in Swift using Xcode 8.2.1). In my main UI there is an NSButton with a custom image (it represents a playing card - like in Poker). When I click that button I'd like its image to be drawn rotated by 180 degrees (flipped upside down).
I'm new to affine transforms but I thought this might work (it doesn't).
@IBAction func buttonClicked(_ sender: NSButton) {
var transform = sender.layer?.affineTransform()
transform = transform?.rotated(by: 180.0 * (CGFloat.pi / 180))
sender.layer?.setAffineTransform(transform!)
}
The card is rotated properly but it is drawn in a new location.
What is the right way to rotate a button's image by 180 degrees while keeping its position in its parent static?
To rotate NSImage
or NSButton
image I wrote an extension for NSImage
using Swift 3.
You can pass to the function:
Here is the way to call it:
@IBAction func button(_ sender: NSButton) {
sender.image = NSImage().imageRotatedByDegrees(rotationDegree: 180,
forImage: sender.image!)
}
And your extension:
extension NSImage {
func imageRotatedByDegrees(rotationDegree degrees:CGFloat,forImage
image:NSImage) -> NSImage {
// calculate the bounds for the rotated image
var imageBounds = NSRect(origin: NSZeroPoint, size: image.size)
let boundsPath : NSBezierPath = NSBezierPath(rect: imageBounds)
var transform : NSAffineTransform = NSAffineTransform()
transform.rotate(byDegrees: degrees)
boundsPath.transform(using: transform as AffineTransform)
let rotatedBounds : NSRect = NSRect(origin: NSZeroPoint, size:
boundsPath.bounds.size)
let rotatedImage = NSImage(size: rotatedBounds.size)
// center the image within the rotated bounds
imageBounds.origin.x = NSMidX(rotatedBounds) - (NSWidth
(imageBounds) / 2); imageBounds.origin.y = NSMidY(rotatedBounds) -
(NSHeight (imageBounds) / 2)
// set up the rotation transform
transform = NSAffineTransform()
transform.translateX(by: +(NSWidth(rotatedBounds) / 2), yBy:
+(NSHeight(rotatedBounds) / 2))
transform.rotate(byDegrees: degrees)
transform.translateX(by: -(NSWidth(rotatedBounds) / 2), yBy:
-(NSHeight(rotatedBounds) / 2))
// draw the original image, rotated, into the new image
rotatedImage.lockFocus()
transform.concat()
image.draw(in: imageBounds, from: NSZeroRect, operation:
NSCompositeCopy, fraction: 1.0)
rotatedImage.unlockFocus()
return rotatedImage
}
}