NSAnimationContext不为NSButton的帧大小设置动画

时间:2016-09-21 13:29:44

标签: swift macos cocoa animation nsanimationcontext

NSAnimationContext.runAnimationGroup(_:_:)文档中所示,使用NSAnimationContext为框架原点大小设置动画,这对于某些视图类型(包括NSImageView)可以正常工作。但是,除非我在动画

之后添加明确的帧大小更改,否则它不会像NSButton那样正常工作

动画NSImageView

的帧大小

以下工作正如NSImageView所期望的那样。它被移动到原点,并调整为200x200:

NSAnimationContext.runAnimationGroup({(let context) -> Void in
    context.duration = 2.0
    // Get the animator for an NSImageView
    let a = self.theImage.animator()
    // Move and resize the NSImageView
    a.frame = NSRect(x: 0, y: 0, width: 200, height: 200)
}) {
    print("Animation done")
}

动画NSButton

的帧大小

使用NSButton执行相同操作时,按钮将移动不会调整

NSAnimationContext.runAnimationGroup({(let context) -> Void in
    context.duration = 2.0
    // Get the animator for an NSButton
    let a = self.button.animator()
    // Move and resize the NSImageView
    a.frame = NSRect(x: 0, y: 0, width: 200, height: 200)
}) {
    print("Animation done")
}

但是,如果我将以下代码行添加到最后,在所有动画代码之后,它会按预期工作!

self.button.frame = NSRect(x: 0, y: 0, width: 200, height: 200)

NSButton的最终工作列表是:

NSAnimationContext.runAnimationGroup({(let context) -> Void in
    context.duration = 2.0
    // Get the animator for an NSButton
    let a = self.button.animator()
    // Move and resize the NSImageView
    a.frame = NSRect(x: 0, y: 0, width: 200, height: 200)
}) {
    print("Animation done")
}
self.button.frame = NSRect(x: 0, y: 0, width: 200, height: 200)

我在这里找不到礼物马,但我不明白为什么这对于NSButton来说是必需的,甚至是什么让它起作用。任何人都可以解释为什么在动画代码之后明确设置NSButton 的框架会使动画生效吗?

1 个答案:

答案 0 :(得分:1)

我怀疑这与在运行时生成的隐式自动布局约束有关。修改框架后,自动布局只会将其恢复为原始大小。

我放弃了原来的方法,支持以下内容:

  1. 在Interface Builder中创建宽度和/或高度约束。我使用默认优先级1000(约束是必需的)。
  2. 为宽度和/或高度NSLayoutConstraint创建一个出口。这在IB中很棘手:我必须双击检查器的测量选项卡中的约束,然后在检查器中打开约束对象。然后,您可以选择连接选项卡并连接插座。
  3. 在我的NSViewController子类中,我使用锚定义新的高度或宽度:theWidthConstraint.constant = 200后跟self.view.needsUpdateConstraints = true
  4. 这种方法更清洁,与自动布局系统更兼容。此外,它还可以轻松地为新自动布局产生的整个布局更改设置动画:

    NSAnimationContext.runAnimationGroup({(let context) -> Void in
        context.duration = 1.0
        self.theWidthConstraint.animator().constant = 200
        // Other constraint modifications can go here
    }) {
        print("Animation done")
    }