views:

865

answers:

2

I've subclassed UIActionSheet, and in the -init method, I have to add the buttons individually after calling the super init (can't pass a var_args).

Right now, it looks like this:

if (self = [super initWithTitle:title delegate:self cancelButtonTitle:cancel destructiveButtonTile:destroy otherButtonTitles:firstButton,nil]) {
  if (firstButton) {
    id buttonTitle;
    va_list argList;
    va_start(argList, firstButtton);
    while (buttonTitle = va_arg(argList, id)) {
      [self addButtonWithTitle:buttonTitle]
    }
    va_end(argList);
  }
}
return self;

However, my specific use in this case has no destructive button, a cancel button, and four other buttons. When it shows up, the ordering is all off, showing up as

Button1
Cancel
Button2
Button3

Like they were simply added to the end of the list, which makes sense; however, I don't WANT it to look like this; so what do I do? Is there, in fact, any way to subclass UIActionSheet correctly and make this work?

+4  A: 

You can just add them in your correct order, and then set the cancelButtonIndex and destructiveButtonIndex manually.

For your code example:

if (self = [super initWithTitle:title delegate:self cancelButtonTitle:nil destructiveButtonTile:nil otherButtonTitles:nil]) {
  if (firstButton) {
    id buttonTitle;
    int idx = 0;
    va_list argList;
    va_start(argList, firstButtton);
    while (buttonTitle = va_arg(argList, id)) {
      [self addButtonWithTitle:buttonTitle]
      idx++;
    }
    va_end(argList);
    [self addButtonWithTitle:cancel];
    [self addButtonWithTitle:destroy];
    self.cancelButtonIndex = idx++;
    self.destructiveButtonIndex = idx++;
  }
}
return self;
Aviad Ben Dov
Ah, that makes it easier. I thought those were read-only
Ed Marty
Nice answer, but the counter is actually unnecessary. addButtonWithTitle: return the index it was added too.
Brad Smith
+1  A: 

Aviad Ben Dov's answer is correct, however the button index counter is not needed to set the index for the destroy and cancel indices. The addButtonWithTitle: method returns the index of the newly used button so we can use that value right away like so:

    if (self = [super initWithTitle:title delegate:self cancelButtonTitle:nil destructiveButtonTile:nil otherButtonTitles:nil]) {
  if (firstButton) {
    id buttonTitle;
    va_list argList;
    va_start(argList, firstButtton);
    while (buttonTitle = va_arg(argList, id)) {
      [self addButtonWithTitle:buttonTitle]
    }
    va_end(argList);
    self.cancelButtonIndex = [self addButtonWithTitle:cancel];
    self.destructiveButtonIndex = [self addButtonWithTitle:destroy];
  }
}
return self;
Brad Smith