【发布时间】:2012-08-16 13:31:56
【问题描述】:
我想在可可 MAC 应用程序开发中交换视图,例如 UINavigationController 以在可可触摸中实现推送/弹出视图。 它是应用程序对推送和弹出视图的要求,不知何故我可以做到这一点,但现在我正处于项目中间,我想要可可中的 viewWillAppear 之类的东西。
【问题讨论】:
标签: macos cocoa nsviewcontroller
我想在可可 MAC 应用程序开发中交换视图,例如 UINavigationController 以在可可触摸中实现推送/弹出视图。 它是应用程序对推送和弹出视图的要求,不知何故我可以做到这一点,但现在我正处于项目中间,我想要可可中的 viewWillAppear 之类的东西。
【问题讨论】:
标签: macos cocoa nsviewcontroller
仅出于提供信息的目的,iOS View 生命周期方法(viewDidLoad、viewWillAppear、viewDidAppear 等)从 OSX 10.10 Yosemite(可能更高版本)开始可用。
还有一个注意事项:如果您打算让应用程序在 10.10 之前的 OSX 版本上运行,请不要实现这些方法,因为它们不会被早期版本识别(因此其中的代码不会被执行)
【讨论】:
这种方法在 Mac 上不可用。 OSX UI 与 iOS UI 相比有很大不同。 使用 -(void)loadView 进行初始 UI 更新(或 -(void)awakeFromNib,如果您的 UI 是在 Interface Builder 中设计并从 xib 文件加载),然后在您调用时以编程方式发出特定的按需 UI 更新请求showWindow、makeKeyAndOrderFront、获取通知、获取委托回调等
【讨论】:
我想出了这样的东西:
标题:
@protocol GWViewExtensions <NSObject>
- (void) viewWasAddedToSuperview;
@end
@interface GWView : NSView
//set to the view controller managing this view to get NSResponder udpates,
//and GWViewExtension protocol method calls.
@property (weak,nonatomic) IBOutlet NSViewController * viewController;
@end
实施:
#import "GWView.h"
@implementation GWView
- (void) awakeFromNib {
[self setNeedsDisplay:TRUE];
}
- (void) addSubview:(NSView *)aView {
[super addSubview:aView];
if([aView isMemberOfClass:[GWView class]]) {
GWView * gview = (GWView *)aView;
if(gview.viewController && [gview.viewController conformsToProtocol:@protocol(GWViewExtensions)]) {
if([gview.viewController respondsToSelector:@selector(viewWasAddedToSuperview)]) {
[gview.viewController performSelectorOnMainThread:@selector(viewWasAddedToSuperview) withObject:nil waitUntilDone:FALSE];
}
}
}
}
- (void) setViewController:(NSViewController *) newController {
if(_viewController) {
NSResponder *controllerNextResponder = [_viewController nextResponder];
[super setNextResponder:controllerNextResponder];
[_viewController setNextResponder:nil];
}
_viewController = newController;
if(newController) {
NSResponder *ownNextResponder = [self nextResponder];
[super setNextResponder:_viewController];
[_viewController setNextResponder:ownNextResponder];
}
}
- (void)setNextResponder:(NSResponder *)newNextResponder {
if(self.viewController) {
[self.viewController setNextResponder:newNextResponder];
return;
}
[super setNextResponder:newNextResponder];
}
- (void) setBackgroundColor:(NSColor *)backgroundColor {
_backgroundColor = backgroundColor;
[self setNeedsDisplay:TRUE];
}
- (void) drawRect:(NSRect) dirtyRect {
[super drawRect:dirtyRect];
if(self.backgroundColor) {
NSGraphicsContext * theContext = [NSGraphicsContext currentContext];
[theContext saveGraphicsState];
[[NSGraphicsContext currentContext] setPatternPhase:NSMakePoint(0,[self frame].size.height)];
[self.backgroundColor set];
NSRectFill([self bounds]);
[theContext restoreGraphicsState];
}
}
- (void) dealloc {
self.backgroundColor = nil;
}
@end
使用:
#import <Cocoa/Cocoa.h>
#import "GWView.h"
@interface GWDribbbleShotDetailColumn : NSViewController <GWViewExtensions>
@end
#import "GWDribbbleShotDetailColumn.h"
@interface GWDribbbleShotDetailColumn ()
@end
@implementation GWDribbbleShotDetailColumn
- (void) viewWasAddedToSuperview {
NSRect svb = self.view.superview.bounds;
NSRect sf = self.view.frame;
sf.size.height = NSHeight(svb);
sf.size.width = NSWidth(svb);
self.view.frame = sf;
}
@end
【讨论】:
我为 NSViewController 使用了一个特殊的视图,它回调视图控制器。 您可以将代码扩展为具有 viewWillAppear 等方法。
- (void)viewWillMoveToWindow:(NSWindow *)newWindow {
[super viewWillMoveToWindow:newWindow];
if (self.installed && !newWindow) {
[self viewWillUninstall];
NSViewController<SMControllerViewDelegate> *viewController = self.viewController;
if (viewController) {
@autoreleasepool {
[viewController viewWillUninstall];
}
}
}
}
- (void)viewDidMoveToWindow {
[super viewDidMoveToWindow];
if (!self.installed && self.window) {
[self viewDidInstall];
NSViewController<SMControllerViewDelegate> *viewController = self.viewController;
if (viewController) {
@autoreleasepool {
[viewController viewDidInstall];
}
}
}
}
【讨论】:
我已经使用 NSViewController 来更改视图,例如根据需要在单击按钮时在窗口上设置 viewController,但我发现一旦为特定 viewController 调用 (id)init,它就再也不会为同一个 viewController 调用。出于这个原因,我的 UI(视图/MVC)没有更新。我再次强行调用(id)init,但视图没有刷新。
【讨论】: