【问题标题】:Animate Auto Layout Constraints and Alpha on NSViewNSView 上的动画自动布局约束和 Alpha
【发布时间】:2021-02-07 20:49:03
【问题描述】:

Swift 3、iOS 10、macOS 10.12.4

我正在构建一个可在 iOS 和 Mac 上运行的应用程序。在 iOS 端,我成功地为 UIView 制作了动画。当用户点击某物时,会出现一个弹出窗口并动画到位。这是我在 tap 事件中的代码:

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 指的是一个拥有graphPopupUITableViewCell

我在 Mac 端构建了相同的东西,但我正在尝试为 graphPopup 制作动画,现在是 NSView。以下是我目前在 click 事件中的内容:

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。没有任何动画——不是graphPopup 的位置或alpha。它只是出现又消失,就像 1985 年在 Atari 上一样。

知道我的NSView 动画有什么问题吗?


更新

为了后代,这里是 BJ 建议的工作代码(稍作调整以使用隐式动画上下文):

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

NSAnimationContext.runAnimationGroup({context in
  context.duration = 0.25
  context.allowsImplicitAnimation = true
  
  self.graphPopup.alphaValue = 1.0
  self.view.layoutSubtreeIfNeeded()
  
}, completionHandler:nil)

【问题讨论】:

    标签: nsview nsviewanimation


    【解决方案1】:

    alphaValue 的修改是在您打开隐式动画之前发生的,因此不会对 alpha 进行动画处理。我不清楚这是否是故意的。

    视图没有动画到popupConstraints 给出的位置,因为你实际上并没有在动画块内做任何会导致视图框架改变的事情。为了触发一个隐式动画,你不仅要更新约束;您还必须确保视图的frame 在动画块内发生变化。如果您使用 AutoLayout,这通常通过调用 layoutSubtreeIfNeeded 来完成。

    然而,因为您在动画块之前更新了约束并调用了layoutSubtreeIfNeeded(),所以在动画块内没有其他需要进行的帧更改(除非updateConstraints() 中发生了什么事情你还没有给我们看。)

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

    【讨论】:

      【解决方案2】:

      斯威夫特 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()来设置持续时间?动画的上下文是为此完成的,在您的情况下,您使用的是_ in,应该是context in,并且您正确设置了 context.duration。
      • 感谢@marcelosarquis 的上下文更正。我已经更新了答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-02
      • 1970-01-01
      • 1970-01-01
      • 2013-12-04
      • 2019-06-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多