【问题标题】:how to temporarily hide the main menu (NSMenu)?如何暂时隐藏主菜单(NSMenu)?
【发布时间】:2013-04-19 20:32:30
【问题描述】:

我正在尝试实现一项功能来保护我的可可应用程序的密码。因此,在我的 AppDelegate 中,如果在窗口中输入正确的密码,我将通过调用 NSApp runModelforWindow 方法调出主应用程序窗口。

它工作正常,除了在首选项中我允许用户更改密码。所以这意味着为了防止用户黑客攻击,我必须隐藏主菜单,直到密码输入正确。

我不想通过使用 removeItemAtIndex 删除某些菜单项或以编程方式设置目标操作以调用该方法来调出首选项窗口。相反,我想暂时隐藏 [NSApp mainMenu]。我搜索了它,似乎找不到任何方法,比如 setHidden:YES 来隐藏它。

我已经尝试过 [[NSApp mainMenu] cancelTracking] 但它不起作用

有什么简单的方法吗?

【问题讨论】:

    标签: objective-c cocoa nsmenu


    【解决方案1】:

    您可以在 NSApp 上使用 -setPresentationOptions: 方法来隐藏和显示标准 OS UI 的许多部分,包括菜单栏和 Dock。请注意,您必须同时隐藏 both 菜单栏和 Dock:

    /* Hide */
    [NSApp setPresentationOptions:[NSApp presentationOptions] |
                                   NSApplicationPresentationHideMenuBar |
                                   NSApplicationPresentationHideDock];
    
    /* Show */
    [NSApp setPresentationOptions:[NSApp presentationOptions] ^
                                   NSApplicationPresentationHideMenuBar ^ 
                                   NSApplicationPresentationHideDock];
    

    不过,这是一种非常具有破坏性的 UI 体验。考虑在屏幕上显示密码对话框时禁用您不希望用户访问的任何菜单项或 UI 元素。

    【讨论】:

    • 感谢您的建议,但我想我会找到另一种方法来处理这个问题。
    【解决方案2】:

    不幸的是,没有简单的方法可以隐藏主菜单 - 它总是显示或隐藏(取决于 info.plist 标志)。以及 Dock 图标。请参阅 LSUIElement 了解这一点。 最初隐藏时显示此菜单有一个技巧,但在运行时没有隐藏/显示它的好方法。

    【讨论】:

      【解决方案3】:

      如果您认真对待使用密码保护(使用)您的应用程序,隐藏菜单栏将无济于事,正如您已经得出的结论。

      为了防止匿名用户执行需要身份验证的操作,您实际上需要在代码中创建逻辑来保护这些操作并检查用户是否确实正确地进行了身份验证,每次他们尝试做某事(选择一个菜单项或按一个按钮)。

      话虽如此,您可以通过禁用相关菜单项来阻止匿名用户打开首选项窗口。就我个人而言,我更喜欢在首选项窗口中实际禁用相关控件,以便用户可以探索不同的选项,但也了解他们需要进行身份验证。您可以遵循 Apple 用于 macOS 系统偏好设置窗口的模型,该模型将锁定许多(但不是全部)偏好设置窗格,具体取决于特定窗格以及用户是否进行了身份验证。

      一个好的起点可能是 Apple 开发者网站上的相关文档。例如:https://developer.apple.com/documentation/securityfoundation

      如果您仍然只想隐藏菜单栏,您可以随时这样做:

      [NSMenu setMenuBarVisible:(BOOL)onOff];
      

      但我相信最好使用@jatoben 的答案中的解决方案,如NSApplicationpresentationOptions,因为这可以让您真正禁用功能性。仅使用 [NSMenu setMenuBarVisible:(BOOL)onOff] 隐藏菜单栏不会禁用 menuItems 的快捷方式,因此您仍然可以使用 ⌘, 显示首选项窗口。

      在旁注中,我相信如果您只需使用显示密码对话框,您就可以省去所有这些麻烦

      NSModalSession session = [NSApp beginModalSessionForWindow:passwordDialog];
      [NSApp runModalSession:session];
      

      这会以模态方式显示应用程序的对话框,这意味着所有其他窗口以及几乎所有菜单项都会自动禁用……

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-19
        • 2016-04-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多