在NSView上设置自动布局约束和Alpha的动画

在NSView上设置自动布局约束和Alpha的动画,nsview,nsviewanimation,Nsview,Nsviewanimation,Swift 3、iOS 10、macOS 10.12.4 我正在构建一个可以在iOS和Mac上运行的应用程序。在iOS方面,我成功地为UIView设置了动画。当用户点击某个东西时,会出现一个弹出窗口并设置动画。以下是我在点击事件中的代码: self.popupConstraintX.constant = x self.popupConstraintY.constant = y UIView.animate(withDuration: 0.25 , delay: 0.0, options: .c

Swift 3、iOS 10、macOS 10.12.4

我正在构建一个可以在iOS和Mac上运行的应用程序。在iOS方面,我成功地为
UIView
设置了动画。当用户点击某个东西时,会出现一个弹出窗口并设置动画。以下是我在点击事件中的代码:

self.popupConstraintX.constant = x
self.popupConstraintY.constant = y

UIView.animate(withDuration: 0.25 , delay: 0.0, options: .curveLinear, animations: {
  self.graphPopup.alpha = 1.0
  self.layoutIfNeeded()

}, completion:nil)
self.popupConstraintX.constant = x
self.popupConstraintY.constant = y

self.view.layoutSubtreeIfNeeded()

NSAnimationContext.runAnimationGroup({_ in
  self.graphPopup.alphaValue = 1.0
  
  //Indicate the duration of the animation
  NSAnimationContext.current().duration = 0.25
  NSAnimationContext.current().allowsImplicitAnimation = true
  self.view.updateConstraints()
  self.view.layoutSubtreeIfNeeded()
  
}, completionHandler:nil)
在这种情况下,
self
指的是保存
graphpoup
UITableViewCell

我已经在Mac端构建了同样的东西,但我正在尝试制作
graphpoup
动画,它现在是一个
NSView
。以下是迄今为止我在点击事件中所了解的内容:

self.popupConstraintX.constant = x
self.popupConstraintY.constant = y

UIView.animate(withDuration: 0.25 , delay: 0.0, options: .curveLinear, animations: {
  self.graphPopup.alpha = 1.0
  self.layoutIfNeeded()

}, completion:nil)
self.popupConstraintX.constant = x
self.popupConstraintY.constant = y

self.view.layoutSubtreeIfNeeded()

NSAnimationContext.runAnimationGroup({_ in
  self.graphPopup.alphaValue = 1.0
  
  //Indicate the duration of the animation
  NSAnimationContext.current().duration = 0.25
  NSAnimationContext.current().allowsImplicitAnimation = true
  self.view.updateConstraints()
  self.view.layoutSubtreeIfNeeded()
  
}, completionHandler:nil)
这里的
self
指的是包含
NSViewController
。没有任何动画——不是
graphpoup
的位置或
alpha
。它只是出现和消失,就像1985年在Atari上一样

你知道我的
NSView
动画有什么不对吗


更新

为了子孙后代的利益,以下是BJ建议的工作代码(稍微调整一下以使用隐式动画上下文):


在启用隐式动画之前,会对alpha值进行修改,因此不会对alpha设置动画。我不清楚这是否是故意的

视图未设置到
popupConstraint
s给定的位置的动画,因为您在动画块内没有实际执行任何会导致视图帧更改的操作。为了触发隐式动画,您不仅必须更新约束;还必须确保视图的
在动画块中发生更改。如果您使用的是AutoLayout,通常通过调用
layoutSubtreeIfNeeded
来完成

但是,因为您在动画块之前更新了约束并调用了
layoutSubtreeIfNeeded()
,所以块内没有其他的帧更改(除非
updateConstraints()
中发生了一些您没有显示的事情。)


您应该删除对
layoutSubtreeIfNeeded()
的第一个调用,或者如果仍然需要,将其置于
popupstraint
修改之上。然后,当您在动画块内调用
layoutSubtreeIfNeeded()
时,将根据这些更改的约束设置一个新帧,您应该会看到动画发生。

Swift 5

animator()
是关键

您可以这样做:

 NSAnimationContext.runAnimationGroup({ context in

    //Indicate the duration of the animation
    context.duration = 0.25
    self.popupConstraintX.animator().constant = x
    self.popupConstraintY.animator().constant = y
    self.graphPopup.animator().alphaValue = 1.0
   
   }, completionHandler:nil)

为什么要使用
NSAnimationContext.current()
设置持续时间?动画的上下文就是这样做的,在您的例子中,您在中使用的
\uuuuu应该是
中的
上下文,并且您正确设置了context.duration。感谢@marcelosarquis对上下文的更正。我已经更新了答案。