【问题标题】:Changed Anchor Point of CALayer in Layer-backed NSView在支持层的 NSView 中更改了 CALayer 的锚点
【发布时间】:2018-08-17 22:49:03
【问题描述】:
我试图通过动画支持层的变换来在支持层的 NSView 上运行缩放动画。我遇到的问题是动画放大到左下角而不是视图的中心。我发现这是因为 NSView 将其支持层的锚点设置为 (0, 0),即使在我将其更改为其他值之后也是如此。这个post 谈到了类似的问题。
我知道要解决这个问题,我可以将视图设为图层托管视图。但是,我想使用自动布局,这就是为什么这不是一个真正的选择。
有没有人知道另一种方法来绕过这种行为并将视图支持层的锚点保持在 (0.5, 0.5)?我在上面链接的帖子中的苹果文档摘录谈到了 NSView 封面方法。锚点的这种覆盖方法是什么?
非常感谢!
【问题讨论】:
标签:
macos
cocoa
core-animation
calayer
nsview
【解决方案1】:
诀窍是覆盖支持层并传递选择的锚点(例如,能够从左上角缩放)。这是我使用的:
extension CGPoint {
static let topLeftAnchor: Self = .init(x: 0.0, y: 1.0)
static let bottomLeftAnchor: Self = .init(x: 0.0, y: 0.0)
static let topRightAnchor: Self = .init(x: 1.0, y: 1.0)
static let bottomRightAnchor: Self = .init(x: 1.0, y: 0.0)
static let centerAnchor: Self = .init(x: 0.5, y: 0.5)
}
class AnchoredLayer: CALayer {
public var customAnchorPoint = CGPoint.topLeftAnchor
override var anchorPoint: CGPoint {
get { customAnchorPoint }
set { super.anchorPoint = customAnchorPoint }
}
}
class AnchoredView: NSView {
required convenience init(anchoredTo point: CGPoint) {
self.init(frame: .zero)
self.wantsLayer = true
self.anchorPoint = point
}
public override func makeBackingLayer() -> CALayer {
let roundedLayer = AnchoredLayer()
return roundedLayer
}
public var anchorPoint: CGPoint {
get { (layer as! AnchoredLayer).customAnchorPoint }
set { (layer as! AnchoredLayer).customAnchorPoint = newValue }
}
}
然后照常使用AnchoredView:
let myView = AnchoredView(anchoredTo: .topLeftAnchor)
// Create the scale animation
let transformScaleXyAnimation = CASpringAnimation()
transformScaleXyAnimation.fillMode = .forwards
transformScaleXyAnimation.keyPath = "transform.scale.xy"
transformScaleXyAnimation.toValue = 1
transformScaleXyAnimation.fromValue = 0.8
transformScaleXyAnimation.stiffness = 300
transformScaleXyAnimation.damping = 55
transformScaleXyAnimation.mass = 0.8
transformScaleXyAnimation.initialVelocity = 4
transformScaleXyAnimation.duration = transformScaleXyAnimation.settlingDuration
myView.layer?.add(transformScaleXyAnimation, forKey: "transformScaleXyAnimation")
...