2017-02-07 3 views
2

У меня очень просто приложение macOS (написанное в Swift с использованием Xcode 8.2.1). В моем основном пользовательском интерфейсе есть NSButton с пользовательским изображением (он представляет собой игральную карту - как в Покере). Когда я нажимаю эту кнопку, мне бы хотелось, чтобы ее изображение было нарисовано, повернутое на 180 градусов (перевернутое вверх ногами).Изображение Flip NSButton с ног на голову

Я новичок в аффинных преобразованиях, но я думал, что это может сработать (это не так).

@IBAction func buttonClicked(_ sender: NSButton) { 
    var transform = sender.layer?.affineTransform() 
    transform = transform?.rotated(by: 180.0 * (CGFloat.pi/180)) 
    sender.layer?.setAffineTransform(transform!) 
} 

Карта повернута должным образом, но она нарисована в новом месте.

Каков правильный способ поворота изображения кнопки на 180 градусов при сохранении его положения в его исходной статике?

+0

Вы добавили ограничения на свой Баттона? – AaoIi

+0

Нет ограничений и автоматическая компоновка отключена. – RobertJoseph

+0

Отметьте мой ответ :) – AaoIi

ответ

1

Чтобы повернуть NSImage или NSButton образ, который я написал расширение для NSImage с помощью Swift 3.

Вы можете перейти к функции:

  • степень вращения, скажем, на 180 градусов.
  • Желаемое изображение для поворота.

Вот как назвать:

@IBAction func button(_ sender: NSButton) { 

    sender.image = NSImage().imageRotatedByDegrees(rotationDegree: 180, 
forImage: sender.image!) 

} 

И ваше расширение:

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 

    } 

} 
+0

Спасибо @Aaoli! Единственная проблема заключается в том, когда вы устанавливаете градусы вращения примерно на 15. Каждое последующее вращение делает изображение меньше и меньше. – RobertJoseph

+0

@RobertJoseph Я проверю это :) – AaoIi

-1

Вы должны использовать преобразование перевода, чтобы перевести центр на 0,0, а затем повернуть, а затем перевести назад, чтобы центр находился там, где вы хотите. Что-то вроде:

transform = transform? 
    .translatedBy(x: -self.center.x, y: -self.center.y) 
    .rotated(by: 180.0 * (CGFloat.pi/180)) 
    .translatedBy(x: self.center.x, y: self.center.y) 
+0

Спасибо. Что само собой можно назвать в вашем примере? Это будет «отправитель» в моем примере? Кроме того, NSView не имеет свойства центра. – RobertJoseph

+0

@RobertJoseph это, вероятно, ваш sender.layer :) – AaoIi

+0

@AaoIi Спасибо, но у CALayer тоже нет свойства центра (по крайней мере, не на macOS). – RobertJoseph

Смежные вопросы