5

使用文档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 之后显式设置帧?

4

1 回答 1

1

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

我放弃了原来的方法,转而采用以下方法:

  1. 在 Interface Builder 中创建宽度和/或高度约束。我使用默认优先级 1000(约束是强制性的)。
  2. 为宽度和/或高度创建一个出口NSLayoutConstraint。这在 IB 中很棘手:我必须在检查器的测量选项卡中双击约束,然后在检查器中打开约束对象。然后您可以选择连接选项卡并连接插座。
  3. 在我的NSViewController子类中,我使用锚来定义新的高度或宽度:theWidthConstraint.constant = 200后跟self.view.needsUpdateConstraints = true

这种方法更简洁,与自动布局系统更兼容。此外,它还可以轻松地为新的自动布局导致的整个布局更改设置动画:

NSAnimationContext.runAnimationGroup({(let context) -> Void in
    context.duration = 1.0
    self.theWidthConstraint.animator().constant = 200
    // Other constraint modifications can go here
}) {
    print("Animation done")
}
于 2016-09-23T19:26:51.793 回答