我想实现新方法,我在Google和Stack Overflow上搜索了很多,但没有找到示例。
- (void)presentViewController:(NSViewController *)viewController animator:(id <NSViewControllerPresentationAnimator>)animator
此方法在 OSX 10.10 中可用,此方法需要实现协议
NSViewControllerPresentationAnimator
,该协议有这两个方法
- (void)animatePresentationOfViewController:(NSViewController *)viewController fromViewController:(NSViewController *)fromViewController
- (void)animateDismissalOfViewController:(NSViewController *)viewController fromViewController:(NSViewController *)fromViewController
这些方法允许我们在两个 NSViewController 之间进行自定义动画 我需要一个实现的例子,我有这个代码:
- (IBAction)openTask:(id)sender {
NSStoryboard *storyboard = [NSStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
Tasks *task = [storyboard instantiateControllerWithIdentifier:@"tasks"];
[self presentViewController:task animator:self];
}
- (void)animatePresentationOfViewController:(NSViewController *)viewController
fromViewController:(NSViewController *)fromViewController
{
}
- (void)animateDismissalOfViewController:(NSViewController *)viewController
fromViewController:(NSViewController *)fromViewController
{
}
任何人都可以帮我举例说明如何实现此转变吗?
这是一个简单的版本(Swift),它在新视图控制器的视图中淡入淡出。 我相信你可以将其翻译成 Objective-C。
您将希望实际使用自动布局,而不仅仅是更改框架,但这会使示例更长一些(不是太难。只需在添加视图后添加约束即可)
我不确定您是否也需要视图控制器遏制。然后需要对 addChildViewController 等进行适当的调用。也许有人可以阐明何时需要这样做,或者在任何情况下这是否实际上是良好的做法。
class MyTransitionAnimator: NSObject, NSViewControllerPresentationAnimator {
func animatePresentationOfViewController(viewController: NSViewController, fromViewController: NSViewController) {
let bottomVC = fromViewController
let topVC = viewController
// make sure the view has a CA layer for smooth animation
topVC.view.wantsLayer = true
// set redraw policy
topVC.view.layerContentsRedrawPolicy = .OnSetNeedsDisplay
// start out invisible
topVC.view.alphaValue = 0
// add view of presented viewcontroller
bottomVC.view.addSubview(topVC.view)
// adjust size
topVC.view.frame = bottomVC.view.frame
// Do some CoreAnimation stuff to present view
NSAnimationContext.runAnimationGroup({ (context) -> Void in
// fade duration
context.duration = 2
// animate to alpha 1
topVC.view.animator().alphaValue = 1
}, completionHandler: nil)
}
func animateDismissalOfViewController(viewController: NSViewController, fromViewController: NSViewController) {
let bottomVC = fromViewController
let topVC = viewController
// make sure the view has a CA layer for smooth animation
topVC.view.wantsLayer = true
// set redraw policy
topVC.view.layerContentsRedrawPolicy = .OnSetNeedsDisplay
// Do some CoreAnimation stuff to present view
NSAnimationContext.runAnimationGroup({ (context) -> Void in
// fade duration
context.duration = 2
// animate view to alpha 0
topVC.view.animator().alphaValue = 0
}, completionHandler: {
// remove view
topVC.view.removeFromSuperview()
})
}
}
希望这能让您开始!
现在已经是 2023 年了,有一些小的更新。
.OnSetNeedsDisplay
现在是 .onSetNeedsDisplay
(注意大写),并且 animatePresentation 和 animateDismissal 的协议略有不同。
这是托马斯代码的当前版本:
import SwiftUI
class macOSTransitionAnimator: NSObject, NSViewControllerPresentationAnimator {
func animatePresentation(of viewController: NSViewController, from fromViewController: NSViewController) {
let bottomVC = fromViewController
let topVC = viewController
// make sure the view has a CA layer for smooth animation
topVC.view.wantsLayer = true
// set redraw policy
topVC.view.layerContentsRedrawPolicy = .onSetNeedsDisplay
// start out invisible
topVC.view.alphaValue = 0
// add view of presented viewcontroller
bottomVC.view.addSubview(topVC.view)
// adjust size
topVC.view.frame = bottomVC.view.frame
// Do some CoreAnimation stuff to present view
NSAnimationContext.runAnimationGroup({ (context) -> Void in
// fade duration
context.duration = 2
// animate to alpha 1
topVC.view.animator().alphaValue = 1
}, completionHandler: nil)
}
func animateDismissal(of viewController: NSViewController, from fromViewController: NSViewController) {
let bottomVC = fromViewController
let topVC = viewController
// make sure the view has a CA layer for smooth animation
topVC.view.wantsLayer = true
// set redraw policy
topVC.view.layerContentsRedrawPolicy = .onSetNeedsDisplay
// Do some CoreAnimation stuff to present view
NSAnimationContext.runAnimationGroup({ (context) -> Void in
// fade duration
context.duration = 2
// animate view to alpha 0
topVC.view.animator().alphaValue = 0
}, completionHandler: {
// remove view
topVC.view.removeFromSuperview()
})
}
}