gpt4 book ai didi

cocoa - 为 Lion 的用户界面恢复功能编码 NSViewController

转载 作者:行者123 更新时间:2023-12-03 16:06:33 26 4
gpt4 key购买 nike

知道在 resume 窗口内存档 NSViewController 的最佳实践是什么吗? (用户界面保存)目的是什么?我尝试在窗口 Controller 的 encodeRestorableStateWithCoder: 方法中对其进行存档,结果发现调用 restoreStateWithCoder: 时 View Controller 不会取消存档。

// NSWindowController subclass

-(void)encodeRestorableStateWithCoder:(NSCoder *)coder
{
[super encodeRestorableStateWithCoder:coder];
NSViewController* contentViewController = self.contentViewController;
if (contentViewController) {
[coder encodeObject:contentViewController forKey:BSContentViewControllerResumeKey];
}
}

-(void)restoreStateWithCoder:(NSCoder *)coder
{
[super restoreStateWithCoder:coder];
NSViewController* contentViewController = [coder decodeObjectForKey:BSContentViewControllerResumeKey];
if (contentViewController) {
// somehow this never get executed since contentViewController always comes out nil
self.contentViewController = contentViewController;
}
}

请注意,此 View Controller 包含管理自己的 subview 的其他 View Controller ,因此需要在 NSCoder 实例中进行一些范围界定 - 只需向下传递提供的 coder 对象将导致存档中的名称冲突。

提前致谢!

最佳答案

状态恢复在NSView上免费工作,但在NSViewController上被忽略,即使它作为NSResponder的子类实现了方法。我想这是因为窗口不知道 NSViewControllers 可能拥有它包含的一些 View 。

在 OS X Yosemite 上它应该可以工作,因为 NSWindow 现在真正支持 NSViewControllers,但在我的测试用例中却没有。我猜这是因为人们需要使用新的 API 来“链接” NSViewController 来添加/删除它们,而不是在侧面创建它们,然后将它们的 View 直接添加到窗口中。如果您想让您的应用程序在 Yosemite 之前的系统上运行,后者实际上是必需的。

以下是让它始终正常工作的方法:只需代理 NSViewNSViewController 之间的恢复 API 调用即可。

子类NSView如下:

@interface GIView : NSView
@property(nonatomic, weak) GIViewController* viewController; // Avoid retain-loops!
@end

@implementation GIView

- (void)setViewController:(GIViewController*)viewController {
_viewController = viewController;
}

- (void)encodeRestorableStateWithCoder:(NSCoder*)coder {
[super encodeRestorableStateWithCoder:coder];

[_viewController encodeRestorableStateWithCoder:coder];
}

- (void)restoreStateWithCoder:(NSCoder*)coder {
[super restoreStateWithCoder:coder];

[_viewController restoreStateWithCoder:coder];
}

@end

NSViewController 像这样:

@interface GIViewController : NSViewController
@end

@implementation GIViewController

- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
self.view.viewController = self; // This loads the view immediately as a side-effect
}
return self;
}

- (void)dealloc {
self.view.viewController = nil; // In case someone is still retaining the view
}

- (void)invalidateRestorableState {
[self.view invalidateRestorableState];
}

@end

现在您可以从 NSViewController 子类调用 -invalidateRestorableState,Cocoa 认为它正在与 NSView 通信,因此会自动调用 根据需要在您的 NSViewController 子类上 -encodeRestorableStateWithCoder:-restoreStateWithCoder:

关于cocoa - 为 Lion 的用户界面恢复功能编码 NSViewController,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14844966/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com