Pergunta

I'm trying to implement a system that changes a label based on the state of an NSPopUpButton.
So far I've tried to do what's displayed in the code below, but whenever I run it, the code just jumps into the else clause, throwing an alert

- (IBAction)itemChanged:(id)sender {
    if([typePopUp.stringValue isEqualToString: @"Price per character"]) {
        _currency = [currencyField stringValue];
        [additionalLabel setStringValue: _currency];

    }
    else if([typePopUp.stringValue isEqualToString: @"Percent saved"]) {
        _currency = additionalLabel.stringValue = @"%";
    }

    else alert(@"Error", @"Please select a calculation type!");
}

So does anyone here know what to do to fix this?

Foi útil?

Solução

@hamstergene is on the right track, but is comparing the title of the menu item rather than, say, the tag, which is wrong for the following reasons:

  1. It means you cannot internationalize the app.
  2. It introduces the possibility of spelling mistakes.
  3. It's an inefficient comparison; comparing every character in a string takes way longer than comparing a single integer value.

Having said all that, NSPopUpButton makes it difficult to insert tags into the menu items, so you need to use the index of the selected item:

Assume you create the menu items using:

[typePopUp removeAllItems];
[typePopUp addItemsWithTitles: [NSArray arrayWithObjects: @"Choose one...", @"Price per character", @"Percent saved", nil]];

Then create an enum that matches the order of the titles in the array:

typedef enum {
    ItemChooseOne,
    ItemPricePerCharacter,
    ItemPercentSaved
} ItemIndexes;

And then compare the selected item index, as follows:

- (IBAction)itemChanged:(id)sender {
    NSInteger index = [(NSPopUpButton *)sender indexOfSelectedItem];
    switch (index) {
    case ItemChooseOne:
        // something here
        break;
    case ItemPricePerCharacter:
        _currency = [currencyField stringValue];
        [additionalLabel setStringValue: _currency];
        break;
    case ItemPercentSaved:
        _currency = @"%";               // See NOTE, below
        additionalLabel.stringValue = @"%";
        break;
    default:
        alert(@"Error", @"Please select a calculation type!");
    }
}

NOTE the following line was incorrect in your code:

_currency = additionalLabel.stringValue = @"%";

Multiple assignment works because the result of x = y is y. This is not the case when a setter is involved. The corrected code is above.

EDIT This answer was heavily edited following more info from the OP.

Outras dicas

To query the title of currently selected item in NSPopUpButton:

NSMenuItem* selectedItem = [typePopUp selectedItem];
NSString* selectedItemTitle = [selectedItem title];

if ([selectedItemTitle isEqualTo: ... ]) { ... }

Note that comparing UI strings is a very bad idea. A slightest change in UI will immediately break your code, and you are preventing future localization. You should assign numeric or object values to each item using -[NSMenuItem setTag:] or -[NSMenuItem setRepresentedObject:] and use them to identify items instead.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top