【问题标题】:How to pin NSViewController to top of NSPopover during NSViewController.transition?如何在 NSViewController.transition 期间将 NSViewController 固定到 NSPopover 的顶部?
【发布时间】:2020-06-13 02:18:22
【问题描述】:

我一直在尝试在 NSPopover 中创建从一个子视图控制器到另一个子视图控制器的滑动过渡。

我的问题是子视图控制器在过渡期间不会粘在 NSPopover 的顶部。它们从底部或顶部动画:

预期行为:两个子视图控制器在过渡期间都应该粘在顶部,并且应该简单地水平滑过。

这是我编写的触发转换的函数:

func loadViewController(_ childViewController: NSViewController, withTransition transitionOptions: NSViewController.TransitionOptions?) {
        addChild(childViewController)
        view.addSubview(childViewController.view)

        childViewController.view.layer?.borderColor = NSColor(calibratedRed: 0, green: 255, blue: 0, alpha: 1).cgColor
        childViewController.view.layer?.borderWidth = 2

        childViewController.view.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        view.layout()

        let oldViewController = currentViewController
        currentViewController = childViewController

        oldViewController?.view.layer?.borderColor = NSColor(calibratedRed: 255, green: 0, blue: 0, alpha: 1).cgColor
        oldViewController?.view.layer?.borderWidth = 2

        if let oldViewController = oldViewController  {
            transition(from: oldViewController, to: currentViewController!, options: transitionOptions ?? .slideLeft, completionHandler: { [weak oldViewController] in
                oldViewController?.removeFromParent()
                oldViewController?.view.removeFromSuperview()
            })
        }

        NSAnimationContext.runAnimationGroup({ (context) -> Void in
            context.duration = 0.5
            context.allowsImplicitAnimation = true

            self.parentPopover?.contentSize = NSSize(width: childViewController.preferredContentSize.width, height: childViewController.preferredContentSize.height)
        })
    }

知道是什么导致了这个问题吗?我试过玩弄子视图控制器和父视图控制器的约束以及它们的帧大小。我就是想不通我做错了什么。

我在这里上传了完整的可重现示例:https://github.com/maximilianschmitt/DebugPopoverAnimation

非常感谢您的帮助!

【问题讨论】:

    标签: objective-c swift macos cocoa appkit


    【解决方案1】:

    如果你期待下面的动画

    然后只需从动画块中删除内容大小的更新,如下所示

    self.parentPopover?.contentSize = NSSize(width: childViewController.preferredContentSize.width, height: childViewController.preferredContentSize.height)
    NSAnimationContext.runAnimationGroup({ (context) -> Void in
        context.duration = 0.5
        context.allowsImplicitAnimation = true
    
    }) {
        oldViewController?.removeFromParent()
        oldViewController?.view.removeFromSuperview()
    }
    

    更新:保持弹出框内容可动画化(不需要上述更改)

    对于这种情况,您唯一需要的是翻转弹出内容视图的坐标系(这是 MasterViewController 的视图)

    class PopoverContentView: NSView {
        override var isFlipped: Bool { true }
    }
    
    class MasterViewController: NSViewController {
        ...
        override func loadView() {
            self.view = PopoverContentView()
        }
    

    【讨论】:

    • 是的,但我希望弹出框的大小能够平滑动画...
    • 非常感谢@Asperi!这真的很好用。 :) :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多