В настоящее время я пытаюсь реализовать некоторые пользовательские NSView, которые будут анимироваться определенными событиями в приложении MacOS.Элементы управления расположены вдоль линий ползунка, которые вы найдете в плагине AudioUnit.
На вопрос об анимации был дан ответ в на этот вопрос .
В чем я не уверенэто то, как изменить положение CALayer вида и опорную точку для поворота и обновить его кадр для событий мыши.
В качестве базового примера я хочу нарисовать квадрат, создав NSView и установив его цвет фона.Затем я хочу анимировать вращение вида, как и предыдущая ссылка, по событию mouseDown.
При следующей настройке вид перемещается в центр окна, его точка привязки изменяется таким образом, чтовид вращается вокруг него, а не вокруг источника window.contentView!
.Однако перемещение view.layer.position
и установка view.layer!.anchorPoint = CGPoint(x: 0.5,y: 0.5)
также не перемещают кадр, который будет обнаруживать события.
@IBOutlet weak var window: NSWindow!
func applicationDidFinishLaunching(_ aNotification: Notification)
{
let view = customView(frame: NSRect(x: 0, y: 0, width: 50, height: 50))
window.contentView!.wantsLayer = true
view.wantsLayer = true
view.layer?.backgroundColor = NSColor.blue.cgColor
window.contentView?.addSubview(view)
let containerFrame = window.contentView!.frame
let center = CGPoint(x: containerFrame.midX, y: containerFrame.midY)
view.layer?.position = center
view.layer?.anchorPoint = CGPoint(x: 0.5,y: 0.5)
}
В этом случае customView - это просто NSView с анимацией вращения из предыдущей ссылкивыполняется на mouseDown
override func mouseDown(with event: NSEvent)
{
let timeToRotate = 1
let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
rotateAnimation.fromValue = 0.0
rotateAnimation.toValue = angle
rotateAnimation.duration = timeToRotate
rotateAnimation.repeatCount = .infinity
self.layer?.add(rotateAnimation, forKey: nil)
}
Перемещение кадра с помощью установки view.frame = view.layer.frame
приводит к вращению вида вокруг одного из его углов.Итак, вместо этого я изменил view.setFrameOrigin()
@IBOutlet weak var window: NSWindow!
func applicationDidFinishLaunching(_ aNotification: Notification)
{
let view = customView(frame: NSRect(x: 0, y: 0, width: 50, height: 50))
window.contentView!.wantsLayer = true
view.wantsLayer = true
view.layer?.backgroundColor = NSColor.blue.cgColor
window.contentView?.addSubview(view)
let containerFrame = window.contentView!.frame
let center = CGPoint(x: containerFrame.midX, y: containerFrame.midY)
let offsetFrameOrigin = CGPoint(x: center.x - view.bounds.width/2,
y: center.y - view.bounds.height/2)
view.setFrameOrigin(offsetFrameOrigin)
view.layer?.position = center
view.layer?.anchorPoint = CGPoint(x: 0.5,y: 0.5)
}
Установка начала координат view.frame со смещением от центра добивается того, чего я хочу, но я не могу не чувствовать, что это немного «хакерски» ичто я могу подойти к этому неправильно.Тем более, что любое дальнейшее изменение на view.layer
или view.frame
приведет либо к некорректной анимации, либо к обнаружению событий вне нарисованного.
Как я могу изменить NSView.layer так, чтобы он вращался вокруг своего центраодновременно с настройкой NSView.frame, чтобы события мыши обнаруживались в правильной области?
Кроме того, является ли изменение NSView.layer.anchorPoint
правильным способом настройки его вращения вокруг его центра?