Remove (or customize) 'Search' from help menu
Asked Answered
E

7

7

My app has the default 'Help' menu. I have removed the 'Help' entry and added a Support entry that links to a forum on my website.

The help menu nib looks like this:

Menu in nib

But once I have the app up and running a new menu item has been suck in:

Menu with search

How can I make the search go away? (Or even better, how could I make it launch a url with params such as http://mywebsite.com/support?search=XXXXX).

Estovers answered 27/2, 2014 at 17:8 Comment(0)
A
4

You're looking for NSUserInterfaceItemSearching protocol. Return a single search result item and use it to open your custom URL.

- (void)searchForItemsWithSearchString:(NSString *)searchString resultLimit:(NSInteger)resultLimit matchedItemHandler:(void (^)(NSArray *items))handleMatchedItems
{
    handleMatchedItems(@[searchString]);
}

- (NSArray *)localizedTitlesForItem:(id)item
{
    return @[[NSString stringWithFormat:@"Search for '%@' on my website", [item description]]];
}

- (void)performActionForItem:(id)item
{
    // Open your custom url assuming item is actually searchString
}
Achilles answered 1/3, 2014 at 17:12 Comment(1)
For those coming to Mac development via Mac Catalyst: this is not supported in Mac Catalyst apps.Abortifacient
R
5

I have found the way to remove the search bar (but not to customize it).

Just assign a menu that is not used to the help menu:

NSMenu *unusedMenu;
unusedMenu = [[NSMenu alloc] initWithTitle:@"Unused"];

NSApplication *theApp;
theApp = [NSApplication sharedApplication];
theApp.helpMenu = unusedMenu;

The documentation mentions this in the helpMenu property of the NSApplication class.

Risinger answered 12/1, 2017 at 11:18 Comment(0)
A
4

You're looking for NSUserInterfaceItemSearching protocol. Return a single search result item and use it to open your custom URL.

- (void)searchForItemsWithSearchString:(NSString *)searchString resultLimit:(NSInteger)resultLimit matchedItemHandler:(void (^)(NSArray *items))handleMatchedItems
{
    handleMatchedItems(@[searchString]);
}

- (NSArray *)localizedTitlesForItem:(id)item
{
    return @[[NSString stringWithFormat:@"Search for '%@' on my website", [item description]]];
}

- (void)performActionForItem:(id)item
{
    // Open your custom url assuming item is actually searchString
}
Achilles answered 1/3, 2014 at 17:12 Comment(1)
For those coming to Mac development via Mac Catalyst: this is not supported in Mac Catalyst apps.Abortifacient
A
3

You probably don't want to get rid of that search bar, since you can still use it to search for menu items!

Searching for Menu Items

As I'm sure you know, this search box will only show Help Topics if your app comes with an Apple Help Book, which can be made by following Apple's documentation.

I'm afraid I don't know of a way to override the search bar's behaviour, but if you don't want to write documentation for your app, I think it would be better to keep the search bar, even if you can't search your forum for help.

Acidfast answered 27/2, 2014 at 20:14 Comment(2)
It's only briefly mentioned in NSApplication as a spotlight help or something.Dray
The current phrase in the docs is Spotlight for Help.Fidel
J
3

@zhoudu's answer worked for me. I translated it into Swift 5.0:

let unusedMenu = NSMenu(title: "Unused")
NSApplication.shared.helpMenu = unusedMenu

Put it into your AppDelegate.

Jada answered 26/2, 2020 at 20:41 Comment(0)
B
2

I remove the Search bar from the Help menu in mac development by entering a single space after Help like "Help ". It looks funny but works properly.

screenshot

Betoken answered 10/4, 2019 at 12:53 Comment(1)
My app is written in Java. So, this trick is the only solution I can apply. And it works.Obedient
A
2

The answers from @pointum and @zhoudu aren't supported on Mac Catalyst apps, so here's an option for that.

According to this answer, the search field is added by macOS. I looked for a plist key to disable it, but didn't find anything. Then I started messing with the buildMenuWithBuilder method. I had to change my AppDelegate class to be a subclass of UIResponder instead of NSObject and then I could override that method in my AppDelegate. Once that was running, it took a few tries to do something useful with it.

Attempt 1: I tried removing the first element of the Help menu, which was the search field.

- (void)buildMenuWithBuilder:(id<UIMenuBuilder>)builder {
    [super buildMenuWithBuilder:builder];
    [builder replaceChildrenOfMenuForIdentifier:UIMenuHelp fromChildrenBlock:^(NSArray<UIMenuElement *> *currentChildren) {
        NSMutableArray *newChildren = [NSMutableArray arrayWithArray:currentChildren];
        [newChildren removeObjectAtIndex:0 withSafeChecks:TRUE];
        return newChildren;
    }];
}

But the search field is added after this method runs, so this code only removed the "[app name] Help" element that I wanted to keep.

Attempt 2: I tried taking the "[app name] Help" menu element from the default menu, then adding it to a new menu and replacing the default help menu with that:

- (void)buildMenuWithBuilder:(id<UIMenuBuilder>)builder {
    [super buildMenuWithBuilder:builder];
    UIMenuElement *helpItem = [[builder menuForIdentifier:UIMenuHelp].children objectAtIndex:0];
    UIMenu *helpMenu = [UIMenu menuWithTitle:@"Help " children:[NSArray arrayWithObject:helpItem]];
    [builder replaceMenuForIdentifier:UIMenuHelp withMenu:helpMenu];
}

But macOS is not so easily tricked; it still identified this as a help menu and added the search field. Even when I changed the menu name to "Help " as shown here, I got the same result.

Attempt 3: Finally I had to make a new help action, add it to a new help menu, AND name the help menu with an extra space. Only when I did all three things did macOS stop adding the search field:

- (void)buildMenuWithBuilder:(id<UIMenuBuilder>)builder {
    [super buildMenuWithBuilder:builder];
    UIAction *helpAction = [UIAction actionWithTitle:@"[app name] Help" image:nil identifier:@"simpleHelp" handler:^(__kindof UIAction *action) {
        // my help code
    }];
    UIMenu *helpMenu = [UIMenu menuWithTitle:@"Help " children:[NSArray arrayWithObject:helpAction]];
    [builder replaceMenuForIdentifier:UIMenuHelp withMenu:helpMenu];
}
Abortifacient answered 10/3, 2020 at 1:14 Comment(0)
F
0

Inspired by @arlomedia's answer, and using Swift 5.x, Xcode 11.x, I created an extension to appDelegate that works in Mac Catalyst and does both things the OP wanted:

  1. Create a custom Help menu without the Search item and with a Support item.
  2. Point the custom Support menu item to a web page.
import UIKit

extension AppDelegate {
    
    /// selector function to open the desired web page
    @objc func openSupportPage() {
        if let url = URL(string: "https://mywebsite.com/support?search=XXXXX") {
            UIApplication.shared.open(url)
        }
    }
    
    /// buildMenu override to customize the default menu
    override func buildMenu(with builder: UIMenuBuilder) {
        
        // ensure we're working with the main menu; and, if so, run `super`!
        guard builder.system == .main else { return }
        super.buildMenu(with: builder)
        
        // remove the "stock" help menu
        builder.remove(menu: .help)
        
        // create the Support help item; gave it a shortcut key of "s" (Command-S)
        let supportHelpItem = UIKeyCommand(
            title: "Support",
            action: #selector(openSupportPage),
            input: "s",
            modifierFlags: [.command])
        
        // create a custom menu to appear as *Help* menu on menu bar
        let myHelpMenu = UIMenu(
            title: "Help ",                 // note the space after "Help"
            children: [supportHelpItem])    // add the *Support* item to the menu
        
        // insert the *Help* menu at the end of the existing menu bar items
        // (after the Window item) where the Help menu would've appeared
        builder.insertSibling(myHelpMenu, afterMenu: .window)
    }
}
Fidel answered 28/7, 2020 at 21:19 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.