使用NSView.layoutSubtreeIfNeeded()动画自动布局约束不适用于macOS High Sierra

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用NSView.layoutSubtreeIfNeeded()动画自动布局约束不适用于macOS High Sierra相关的知识,希望对你有一定的参考价值。

我有一个基本的Mac应用程序,通过自动布局完成视图动画:

  • 我在当前视图的右侧添加了一个新视图
  • 我更新约束,以便新视图最终填满窗口

→动画将使其看起来好像视图从右侧滑入。

动画自动布局更改的推荐方法是:

  1. 更新约束
  2. 使用NSAnimationContext.runAnimationGroup()
  3. allowsImplicitAnimation设置为动画块内的true
  4. 在动画块中调用view.layoutSubtreeIfNeeded()

我遵循了这个建议,在macOS Sierra上一切正常,但在macOS High Sierra上,动画不再发生了。相反,视图显示在没有动画的最终位置。

我找到了一个解决方法:我使用DispatchQueue.main.async在下一个runloop循环中安排动画。然而,这似乎是一个黑客,我想知道是否还有其他我在这里失踪的东西。

这是我的实际代码:

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
        })
    //}
}
答案

为您尝试设置动画的根视图启用核心动画支持。它可以在Interface Builder中或以编程方式完成:

override func viewDidLoad()
{
    super.viewDidLoad()
    view.wantsLayer = true
}

以上是关于使用NSView.layoutSubtreeIfNeeded()动画自动布局约束不适用于macOS High Sierra的主要内容,如果未能解决你的问题,请参考以下文章

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份

Kettle java脚本组件的使用说明(简单使用升级使用)