Mar*_*ark 5 cocoa autolayout nsanimationcontext nsanimation macos-high-sierra
我有一个基本的Mac应用程序,该应用程序具有通过自动版式完成的视图动画:
?动画将使其看起来好像视图从右侧滑入。
动画自动版式更改的推荐方法是:
NSAnimationContext.runAnimationGroup()allowsImplicitAnimation为true动画块内view.layoutSubtreeIfNeeded()在动画块内调用我遵循了此建议,并且在macOS Sierra上一切正常,但是在macOS High Sierra上,动画不再发生。取而代之的是,视图在没有动画的情况下显示在其最终位置。
我找到了一种解决方法:我使用将动画安排在下一个运行循环周期中DispatchQueue.main.async。但是,这似乎是一种hack,我想知道这里是否还缺少其他东西。
这是我的实际代码:
private func appendSlideViewControllerAnimated(_ viewController:NSViewController, to viewToTheLeft:NSView)
{
// Insert the new view on the very right, just outside the parent:
viewController.view.frame = self.view.bounds
viewController.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(viewController.view)
viewController.view.topAnchor.constraint( equalTo: view.topAnchor ).isActive = true
viewController.view.bottomAnchor.constraint( equalTo: view.bottomAnchor ).isActive = true
viewController.view.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
viewController.view.leadingAnchor.constraint(equalTo: viewToTheLeft.trailingAnchor).isActive = true
// Update the layout after we just added the view on the right:
view.layoutSubtreeIfNeeded()
// Starting with macOS High Sierra, animating constraint changes for the newly inserted view
// only works if scheduled on the next runloop:
//DispatchQueue.main.async {
// Update the constraints to pin the view to the left:
self.view.removeConstraint(self.activeSlideLeadingConstraint!)
self.activeSlideLeadingConstraint = viewController.view.leadingAnchor.constraint(equalTo: self.view.leadingAnchor)
self.activeSlideLeadingConstraint?.constant = 0
self.activeSlideLeadingConstraint?.isActive = true
NSAnimationContext.runAnimationGroup( { context in
self.isAnimating = true
context.duration = self.slidingAnimationDuration
context.allowsImplicitAnimation = true
self.view.layoutSubtreeIfNeeded()
}, completionHandler: {
viewToTheLeft.removeFromSuperview()
self.clearUndoHistory()
self.updateFirstResponder()
self.isAnimating = false
})
//}
}
Run Code Online (Sandbox Code Playgroud)
为您尝试设置动画的根视图启用核心动画支持。它可以在 Interface Builder 中或以编程方式完成:
override func viewDidLoad()
{
super.viewDidLoad()
view.wantsLayer = true
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
655 次 |
| 最近记录: |