我有一个带有偏好设置窗口的Mac应用。首选项窗口以模态方式打开
-(IBAction)displayPreferencesWindow:(id)sender{
if (!pc) {
pc = [[PreferencesController alloc] initWithWindowNibName:@"PreferencesController"];
pc.delegate = self;
}
NSWindow *pcWindow = [pc window];
[NSApp runModalForWindow: pcWindow];
[NSApp endSheet: pcWindow];
[pcWindow orderOut: self];
}
在首选项窗口中,我有一个用于打开帐户首选项面板的按钮
- (IBAction)openSystemPrefs:(id)sender {
[[NSWorkspace sharedWorkspace] openFile:@"/System/Library/PreferencePanes/Accounts.prefPane"];
}
问题是帐户首选项面板无法在实际窗口前打开。我怎样才能做到这一点?
答案 0 :(得分:0)
这有点奇怪,并且反对标题中的注释,但请尝试使用它:
- (BOOL)openFile:(NSString *)fullPath withApplication:(NSString *)appName andDeactivate:(BOOL)flag;
来自那里的评论:
在某个路径上打开文件。如果你使用没有的变体 withApplication:参数,或者如果为此参数传递nil,则为 使用默认应用程序。 appName参数可以是完整路径 应用程序,或只是应用程序的名称,有或没有 .app扩展名。如果您为andDeactivate:传递YES,或调用变体 如果没有此参数,调用应用程序将在新的之前停用 应用程序启动,以便新的应用程序可能会出现在前台,除非 用户在此期间切换到另一个应用程序。通过是 for andDeactivate:通常建议使用。
所以听起来你的应用应该停用(因为你正在调用没有andDeactivate:
参数的变体)但是我会尝试使用该参数显式使用变体,只是为了一定不会。
答案 1 :(得分:0)
根据经验,如果启动应用程序呈现模态UI,则启动的应用程序似乎不会激活,至少在使用NSWorkspace
API时不会。我能够使用似乎可以达到预期效果的AppleScript来解决问题:
- (IBAction)doStuff:(id)sender
{
[[NSWorkspace sharedWorkspace] openFile:@"/System/Library/PreferencePanes/Accounts.prefPane"];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSString* s = @"tell application \"System Preferences\" to activate";
NSAppleScript* as = [[[NSAppleScript alloc] initWithSource: s] autorelease];
NSDictionary* error = nil;
if ([as compileAndReturnError: &error])
{
(void)[as executeAndReturnError: &error];
}
});
}
我将它发送到后台队列,因为编译和运行AppleScript需要几百毫秒,如果同步完成它会有点显眼(按钮保持突出显示的时间超出预期)。
如果你感觉真的很自虐,你可能会通过编造等效的AppleEvents并直接发送它来让脚本编译阶段(即更快),但这似乎达到了预期的效果,即使在呈现模态UI时也是如此在启动应用程序中。