一尘不染

在OS X的视图控制器之间过渡

swift

我正在尝试编写一个单一的窗口计时器应用程序,当用户按下开始按钮时,我希望它显示具有倒数的另一个视图控制器等。我也在Xcode中使用故事板,在这里我有一个segue可以连接开始按钮和第二个视图控制器。但是,只有三种不同的样式,即模式样式,工作表样式和弹出样式。我想将第一个视图控制器替换为窗口中的第二个视图控制器。我找不到办法。我尝试为segue使用自定义样式,在该样式中使用presentViewController:animator:方法,但是我无法弄清楚要发送的内容作为animator:的参数。

从一个视图控制器在一个窗口中切换到另一个视图控制器,反之亦然的最简单/正确的方法是什么?

同样在情节提要中,当我选择一个视图控制器时,它会显示一个名为“ Presentation”的属性,该属性可以是多个和单个,这些代表什么?


阅读 359

收藏
2020-07-07

共1个答案

一尘不染

我认为,最简单的方法就是交换contentViewControllerNSWindow

// in NSViewController's subclass
@IBAction func someAction(sender: AnyObject) {
    let nextViewController = ... // instantiate from storyboard or elsewhere

    if let window = view.window where window.styleMask & NSFullScreenWindowMask > 0 {
        // adjust view size to current window
        nextViewController.view.frame = CGRectMake(0, 0, window.frame.width, window.frame.height)
    }

    view.window?.contentViewController = nextViewController
}

这是选项1。

如果要使用segue,请创建自定义选项,并将其设置为IB中带有标识符的segue类。

class ReplaceSegue: NSStoryboardSegue {
    override func perform() {
        if let fromViewController = sourceController as? NSViewController {
            if let toViewController = destinationController as? NSViewController {
                // no animation.
                fromViewController.view.window?.contentViewController = toViewController
            }
        }
    }
}

这是选项2。

最后一个选项是使用presentViewController:animator:NSViewController。以下代码是NSViewControllerPresentationAnimator用于溶解动画的自定义代码。

class ReplacePresentationAnimator: NSObject, NSViewControllerPresentationAnimator {
    func animatePresentationOfViewController(viewController: NSViewController, fromViewController: NSViewController) {
        if let window = fromViewController.view.window {
            NSAnimationContext.runAnimationGroup({ (context) -> Void in
                fromViewController.view.animator().alphaValue = 0
            }, completionHandler: { () -> Void in
                viewController.view.alphaValue = 0
                window.contentViewController = viewController
                viewController.view.animator().alphaValue = 1.0
            })
        }
    }

    func animateDismissalOfViewController(viewController: NSViewController, fromViewController: NSViewController) {
        if let window = viewController.view.window {
            NSAnimationContext.runAnimationGroup({ (context) -> Void in
                viewController.view.animator().alphaValue = 0
                }, completionHandler: { () -> Void in
                    fromViewController.view.alphaValue = 0
                    window.contentViewController = fromViewController
                    fromViewController.view.animator().alphaValue = 1.0
            })
        }        
    }
}

然后像这样呈现VC。

@IBAction func replaceAction(sender: AnyObject) {
    let nextViewController = ... // instantiate from storyboard or elsewhere
    presentViewController(nextViewController, animator: ReplacePresentationAnimator())
}

对于解雇,呼叫presentingViewControllerdismissViewController:所呈现的VC。

@IBAction func dismissAction(sender: AnyObject) {
    presentingViewController?.dismissViewController(self)    
}

Swift4版本

class ReplacePresentationAnimator: NSObject, NSViewControllerPresentationAnimator {
func animatePresentation(of viewController: NSViewController, from fromViewController: NSViewController) {
    if let window = fromViewController.view.window {
        NSAnimationContext.runAnimationGroup({ (context) -> Void in
            fromViewController.view.animator().alphaValue = 0
        }, completionHandler: { () -> Void in
            viewController.view.alphaValue = 0
            window.contentViewController = viewController
            viewController.view.animator().alphaValue = 1.0
        })
    }
}

func animateDismissal(of viewController: NSViewController, from fromViewController: NSViewController) {
    if let window = viewController.view.window {
        NSAnimationContext.runAnimationGroup({ (context) -> Void in
            viewController.view.animator().alphaValue = 0
        }, completionHandler: { () -> Void in
            fromViewController.view.alphaValue = 0
            window.contentViewController = fromViewController
            fromViewController.view.animator().alphaValue = 1.0
        })
    }
}

}

希望能有所帮助。

2020-07-07