1

I want subclass a UIActionSheet to use a block approach instead of delegate. My problem is when I call the super initialization on UIActionSheet the variadic ... at the end of the method aren't recognized as a va_list and the action sheet only show the first button.

Here class implementation .m

@interface FLActionSheet ()
@property (nonatomic,strong) actionClickedBlock clickedBlock;
@end

@implementation FLActionSheet

+ (id)actionSheetWithTitle:(NSString *)title
              clickedBlock:(actionClickedBlock)clickedBlock
         cancelButtonTitle:(NSString *)cancelButtonTitle
    destructiveButtonTitle:(NSString *)destructiveButtonTitle
         otherButtonTitles:(NSString *)otherButtonTitles, ...
{
    return [[self alloc] initWithTitle:title
                          clickedBlock:clickedBlock
                     cancelButtonTitle:cancelButtonTitle
                destructiveButtonTitle:destructiveButtonTitle
                     otherButtonTitles:otherButtonTitles];
}

- (id)initWithTitle:(NSString *)title
       clickedBlock:(actionClickedBlock)clickedBlock
  cancelButtonTitle:(NSString *)cancelButtonTitle
destructiveButtonTitle:(NSString *)destructiveButtonTitle
  otherButtonTitles:(NSString *)otherButtonTitles, ...
{
    self = [super initWithTitle:title
                       delegate:self
              cancelButtonTitle:cancelButtonTitle
         destructiveButtonTitle:destructiveButtonTitle
              otherButtonTitles:otherButtonTitles,nil];

    if (self)
    {
        self.clickedBlock = [clickedBlock copy];
    }
    return self;
}

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    self.clickedBlock(buttonIndex);
}

@end

And here how I initialize the action sheet:

[[[FLActionSheet alloc] initWithTitle:@"Ordina per..."
                            clickedBlock:^(NSInteger buttonIndex) {

                                switch (buttonIndex)
                                {
                                    case 0:

                                        break;

                                    default:
                                        break;
                                }
                            }
                       cancelButtonTitle:nil
                  destructiveButtonTitle:@"Annulla"
                       otherButtonTitles:@"Data crescente", @"Data decrescente", @"Mittente crescente", @"Mittente decrescente"]
     showFromBarButtonItem:myBarButtonItem
     animated:YES];

And here the result:

enter image description here

I'm definitely doing something wrong but I do not understand what. Ideas ?

Fry
  • 6,235
  • 8
  • 54
  • 93
  • 1
    possible duplicate of [Objective-C passing around ... nil terminated argument lists](http://stackoverflow.com/questions/2345196/objective-c-passing-around-nil-terminated-argument-lists) – Martin R Mar 04 '14 at 09:49
  • @MartinR This not really a duplicate. Here the question is _How to properly subclass UIActionSheet?_ The answer is _You better not._ – Tricertops Mar 04 '14 at 09:52

2 Answers2

3
  1. UIActionSheet is not designed to be subclassed.

  2. There are other ways how to use it with blocks. Best is to create a category, that implements delegate protocol and store the block using associated ojects mechanism. Implementation here.

  3. I think initWithTitle:delegate:cancelButtonTitle:... is not the designated initializer and it is implemented using [self init] with following setTitle: and addButtonWithTitle: calls. You should do it similarily.

  4. In fact, with variadic method, you have no other option. To collect all arguments, you have to use va_list and related functions. Implementation here. Then on each of them you call addButtonWithTitle: as I mentioned.

Tricertops
  • 8,492
  • 1
  • 39
  • 41
0

Please pass nil at the last of your otherButtonTitles parameter.

[[FLActionSheet alloc] initWithTitle:@"Ordina per..."
                            clickedBlock:^(NSInteger buttonIndex) {

                                switch (buttonIndex)
                                {
                                    case 0:

                                        break;

                                    default:
                                        break;
                                }
                            }
                       cancelButtonTitle:nil
                  destructiveButtonTitle:@"Annulla"
                       otherButtonTitles:@"Data crescente", @"Data decrescente", @"Mittente crescente", @"Mittente decrescente", nil]
     showFromBarButtonItem:myBarButtonItem
     animated:YES];
Sunil Pandey
  • 7,042
  • 7
  • 35
  • 48
  • - (id)initWithTitle:(NSString *)title message:(NSString *)message delegate:(id /**/)delegate cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION; – Sunil Pandey Mar 04 '14 at 09:50