Search code examples
objective-ciosuialertviewnullsubclassing

Subclassing UIAlertView


Am attempting to subclass UIAlertView to better handle error states in my app. The trouble am having is with the otherButtonTitles nil terminated parameter, when I create my subclass it is only picking up the first string in the list rather than all the strings

+ (ErrorAlertView *)displayErrorAlertViewWithTitle:(NSString *)title 
                                           message:(NSString *)message 
                                          delegate:(id<UIAlertViewDelegate>)delegate 
                                     errorDelegate:(id<ErrorAlertViewDelegate>)errorDelegate
                                 cancelButtonTitle:(NSString *)cancelButtonTitle 
                                        displayNow:(BOOL)displayNow
                                               tag:(NSUInteger)tag
                                 otherButtonTitles:(NSString *)otherButtonTitles, ...;

{

  ErrorAlertView *errorAlertView = [[ErrorAlertView alloc]  initWithTitle:title 
                                                                  message:message 
                                                                 delegate:delegate 
                                                        cancelButtonTitle:cancelButtonTitle 
                                                        otherButtonTitles:otherButtonTitles, nil];


  errorAlertView.errorDelegate = errorDelegate;
  errorAlertView.tag = tag;

  if (displayNow) {

    [errorAlertView show];

  }

  return [errorAlertView autorelease];


}

If I make the following call the above method:

[ErrorAlertView displayErrorAlertViewWithTitle:[self noInternetConnectionAlertViewTitle] 
                                           message:[self noInternetConnectionAlertViewMessage] 
                                          delegate:self 
                                     errorDelegate:errorDelegate 
                                 cancelButtonTitle:@"OK" 
                                        displayNow:YES 
                                               tag:ErrorAlertTagInternetConnectionError 
                                 @"Try again",@"Setting", nil];

The UIAlertView is being shown with only the @"Try again" button being shown.


Solution

  • You can't send a variable set of parameters like that.

    When I subclassed UIAlertView I did this:

    va_list args;
    va_start(args, otherButtonTitles);
    for (NSString *anOtherButtonTitle = otherButtonTitles; anOtherButtonTitle != nil; anOtherButtonTitle = va_arg(args, NSString*)) {
        [self addButtonWithTitle:anOtherButtonTitle];
    }
    

    Alternatively, you could create a variant of your function that accepts a va_list as a (single) parameter, and then runs the above code.

    Generally, when writing a variadic function, you should include an alternative for handling this eventuality. Apple supply the addButtonWithTitle: method in this case.