开发者

Updating A Dynamically Created NSMenu with NSMenuItems

开发者 https://www.devze.com 2023-04-05 01:49 出处:网络
I have a NSMenu with 3 static NSMenuItems that I want to keep, and a bunch after that are dynamically generated and should be removed and reloaded each time the user clicks the menu icon.

I have a NSMenu with 3 static NSMenuItems that I want to keep, and a bunch after that are dynamically generated and should be removed and reloaded each time the user clicks the menu icon.

I'm trying to create a list of pr开发者_如何学编程ocesses that pop out, but each time I open the popout, the NSMenuItems don't clear. They just add on in some funky way. Logging the for loop shows that the loop isn't completing. Any ideas why?

-(void)menuNeedsUpdate:(NSMenu *)menu{

    //Keep Top 3 Menu Items
    if(dropDown.numberOfItems > 3){
        NSLog(@"-----------Removing Items");
        NSLog(@"%d",itemCount);
        for(int i = 2; i <= dropDown.numberOfItems; i++){
            NSLog(@"%d",i);
            [dropDown removeItemAtIndex:i];

        }
    }

    NSArray *appArray = [[NSWorkspace sharedWorkspace] runningApplications];


    for (NSRunningApplication *r in appArray){
        //NSLog(r.localizedName);
        //NSLog(@"------------");
        NSMenuItem *i = [[NSMenuItem alloc] initWithTitle:r.localizedName 
                                               action:@selector(fooClicked:) keyEquivalent:@""];
        [i setTarget:self];
        [dropDown addItem:i];

        [i release];
    }


}


your problem is with removal code. Consider this:

for(int i = 3; i <= dropDown.numberOfItems; i++){
    NSLog(@"%d",i);
    [dropDown removeItemAtIndex:i];
}

It should be i-- at the end. Also - if array has 3 items, the index of last item is 2, hence the declaration of the loop should be following:

for(int i = 2; i >= 0; i--){
    NSLog(@"%d",i);
    [dropDown removeItemAtIndex:i];
}

Update according to comment

Removing the items from your menu should be performed backwards or forward, but removing same item index right next after the 2nd item (i.e. removing always 3rd item):

for(int i = 2; i <= dropDown.numberOfItems; i++){
    NSLog(@"%d",i);
    [dropDown removeItemAtIndex:2];
}

or

for(int i = dropDown.numberOfItems; i >= 2; i--){
    NSLog(@"%d",i);
    [dropDown removeItemAtIndex:i];
}

This is needed because each time you remove ith item, the array of items shortens and sometimes you hit the object that is beyond array bounds. Consider this scenario:

  1. create array of 3 items
  2. iterate from 0 to 2 removing the ith item
    1. i = 0, check (i < 3 items) remove the first item, the array of items shortens to 2 (0, 1)
    2. i = 1, check (i < 2 items) remove the first item, the array of items shortens to 1 (0), but only second item is removed so the 0th item is left from previous iteration (which is 1st item from the original set).

This would explain the "funky way".

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号