根据需求,窗口内容需要切换,且要求带有动画效果。实现效果如下图所示:
思路:程序只有一个window,通过在window的contentview上添加和移除子视图实现页面内容切换,添加动画效果,使之具有视觉切换过程。
在mainMenu.xib中拖入NSView,与窗口通大小,然后在AppDelegate中添加IBOutlet属性,此处我们将该view命名为windowBackView。
在windowBackView上添加按钮,并将IBAction拖入AppDelegate.m, 按钮动作名为
- (IBAction)showViewController1:(id)sender;
新建ViewController类,继承自NSViewController。
添加控件,以示区别。
在AppDelegate.m中添加属性如下:
@interface AppDelegate () {
ViewController *_viewController;
}
@property (weak) IBOutlet NSView *windowBackView;
@property (weak) IBOutlet NSWindow *window;
@end
applicationDidFinishLaunching:(NSNotification *)aNotification方法中,添加如下代码
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
self.window.contentView.wantsLayer = YES;
self.window.contentView.layer.backgroundColor = [[NSColor blueColor] CGColor];
_viewController = [[ViewController alloc] initWithDelegate:self];
_viewController.delegate = self;//设置代理,返回按钮使用
}
实现按钮点击切换内容方法- (IBAction)showViewController1:(id)sender
- (IBAction)showViewController1:(id)sender {
//控制main Window中页面动画退出
NSRect windowFrame = [self.window contentView].frame;
NSRect rect = NSMakeRect(-windowFrame.size.width, 0, windowFrame.size.width, windowFrame.size.height);
[self moveAnimationWithView:self.windowBackView location:rect];
//控制viewController的view页面进入
NSRect viewFrame = NSMakeRect(windowFrame.size.width, 0, windowFrame.size.width, windowFrame.size.height);
[[self.window contentView] addSubview:_viewController.view];
[_viewController.view setFrame:viewFrame];
[self moveAnimationWithView:_viewController.view location:windowFrame];
}
其中,- (void)moveAnimationWithView:(NSView *)view location:(NSRect)rect
方法如下:
/**
* @brief 对view执行frame方面的动画,从原始位置移动到rect
* @param view 需要被执行动画的view
* @param rect view动画结束后的rect
*/
- (void)moveAnimationWithView:(NSView *)view location:(NSRect)rect{
[[NSAnimationContext currentContext] setDuration:0.75];
[[view animator] setFrame:rect];
[NSAnimationContext endGrouping];
}
Viewcontroller中返回按钮执行动作,通过动画方式移除Viewcontroller的view。Viewcontroller.m中代码如下:
- (instancetype)init {
return [self initWithDelegate:nil];
}
- (instancetype)initWithDelegate:(id)delegate {
if (self = [super initWithNibName:@"ViewController" bundle:nil]){
_delegate = delegate;
self.view.wantsLayer = YES;
[self.view.layer setBackgroundColor:[[NSColor cyanColor] CGColor]];
}
return self;
}
- (IBAction)backAction:(id)sender {
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(viewControllerWillClose:)]) {
[self.delegate viewControllerWillClose:self];
}
}
在AppDelegate.m中实现返回按钮点击的代理方法:
#pragma mark - ViewController1Delegate
- (void)viewControllerWillClose:(ViewController *)viewController {
NSLog(@"LOG_viewControllerWillClose");
NSRect windowFrame =self.window.contentView.frame;
NSRect viewNewFrame = NSMakeRect(windowFrame.size.width, 0, windowFrame.size.width, windowFrame.size.height);
[self moveAnimationWithView:_viewController.view location:viewNewFrame];
[self moveAnimationWithView:self.windowBackView location:windowFrame];
}
窗口动画切换demo