Как я могу отправить массив строк в метод инициализации UIActionSheet varargs? - PullRequest
7 голосов
/ 16 октября 2011

У меня есть лист действий с опциями, которые варьируются в зависимости от обстоятельств. Существует достаточно разных заголовков кнопок, которые я хотел бы сначала создать из этих заголовков, но я не могу понять, как преобразовать их в формат varargs.

Я хочу сделать что-то вроде этого:

NSMutableArray *buttonTitles = [NSMutableArray array];
if (condition1) {
    [buttonTitles addObject: @"Do action 1"];
}
if (condition2) {
    [buttonTitles addObject: @"Do action 2"];
}
if (condition3) {
    [buttonTitles addObject: @"Do action 3"];
}
if (condition4) {
    [buttonTitles addObject: @"Do action 4"];
}
UIActionSheet *actionSheet = [[[UIActionSheet alloc] initWithTitle: nil delegate: self cancelButtonTitle: @"Cancel" destructiveButtonTitle: nil otherButtonTitles: buttonTitles] autorelease];

Теперь, очевидно, если бы мне пришлось, я мог бы сделать что-то вроде этого:

UIActionSheet *actionSheet = nil;
if (condition1 && condition2 && condition3 && condition4) {
    actionSheet = [[[UIActionSheet alloc] initWithTitle: nil delegate: self cancelButtonTitle: @"Cancel" destructiveButtonTitle: nil otherButtonTitles: @"Do action1", @"Do action2", @"Do action3", @"Do action 4", nil] autorelease];    
} else if (condition1 && condition2 && condition3 && !condition4) {
    actionSheet = [[[UIActionSheet alloc] initWithTitle: nil delegate: self cancelButtonTitle: @"Cancel" destructiveButtonTitle: nil otherButtonTitles: @"Do action1", @"Do action2", @"Do action3", nil] autorelease];    
} 
// else ...
// about 14 other cases!

Но это было бы ужасно. Кто-нибудь знает какой-нибудь хороший синтаксический сахар, чтобы помочь мне?

EDIT: Было предложено использовать addButtonWithTitle, что на первый взгляд выглядит великолепно, к сожалению, это добавляет дополнительные кнопки после кнопки отмены, что нежелательно.

Я считаю, что это ошибка в коде Apple, поскольку их документация по addButtonWithTitle гласит:

// adds a button with the title. returns the index (0 based) of where it was added. buttons are displayed in the order added except for the
// destructive and cancel button which will be positioned based on HI requirements. buttons cannot be customized.

Требования HI (собственные рекомендации Apple по интерфейсу пользователя) предпочитают кнопку отмены ниже всех других параметров, поэтому я бы сказал, что Apple облажалась. Конечно, это не очень помогает мне, поэтому я снова пытаюсь конвертировать NSArray в varargs, что я до сих пор не знаю, как это сделать.

Ответы [ 4 ]

18 голосов
/ 16 октября 2011

Вы можете попробовать это

NSMutableArray *buttonTitles = [NSMutableArray array];
if (condition1) {
    [buttonTitles addObject: @"Do action 1"];
}
if (condition2) {
    [buttonTitles addObject: @"Do action 2"];
}
if (condition3) {
    [buttonTitles addObject: @"Do action 3"];
}
if (condition4) {
    [buttonTitles addObject: @"Do action 4"];
}
[buttonTitles addObject: @"Cancel"];
UIActionSheet *actionSheet = [[[UIActionSheet alloc] initWithTitle: nil delegate: self cancelButtonTitle: nil destructiveButtonTitle: nil otherButtonTitles: nil] autorelease];

for (NSString *title in buttonTitles) {
    [actionSheet addButtonWithTitle: title];
}

[actionSheet setCancelButtonIndex: [buttonTitles count] - 1];
5 голосов
/ 01 марта 2012

Вариант ответа Химаншу:

    UIActionSheet * as = [[UIActionSheet alloc] initWithTitle:@"Share" 
                                                 delegate:self 
                                        cancelButtonTitle:nil /* don't set Cancel title here! */
                                   destructiveButtonTitle:nil 
                                        otherButtonTitles:nil];
int cancelButtonIndex = 0; // will remain 0 if no other buttons besides "Cancel"
if ( canShareBySMS )
{
    [as addButtonWithTitle:kSMSButtonText];
    cancelButtonIndex++;
}
if ( canShareByMail )
{
    [as addButtonWithTitle:kEmailButtonText];
    cancelButtonIndex++;
}
/* etc. */

// after all other buttons have been added, include Cancel
[as addButtonWithTitle:@"Cancel"];
[as setCancelButtonIndex:cancelButtonIndex];

[as showInView:self.sharingViewController.view];
[as release];

Примечание: ваш метод UIActionSheetDelegate должен проверять заголовки кнопок вместо buttonIndex:

- (void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex {
    if ([[actionSheet buttonTitleAtIndex:buttonIndex] isEqualToString:kSMSButtonText]) {
    //share via sms
    }else if ([[actionSheet buttonTitleAtIndex:buttonIndex] isEqualToString:kEmailButtonText]) {
    //share via mail
    }
}

Я думаю, что ключевая деталь, которую пропускают люди, - это установка cancelButton в селекторе initWithTitle вместо добавления его после всех других кнопок и указание внешнего вида кнопки отмены путем вызова setCancelButtonIndex:.

4 голосов
/ 16 октября 2011

Почему бы просто не сделать что-то вроде этого:

for (Nstring *button in buttonTitles)
  [actionSheet addButtonWithTitle:button];
0 голосов
/ 14 февраля 2014

Вот метод, который я попробовал, который, кажется, работает просто отлично. Это работает, если вы хотите добавить дополнительную кнопку в конце кнопок, перед кнопкой «Отмена».

NSString * optionalButton = nil;
if (condition4) {
  optionalButton = @"Some Additional Option";
}

UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:@"Some Title" 
                                                          delegate:self 
                                                 cancelButtonTitle:@"Cancel" 
                                            destructiveButtonTitle:nil 
                                                 otherButtonTitles:@"Button 1",@"Button 2",@"Button 3",optionalButton, nil];


[actionSheet showInView:self.view];

Кажется, можно добавить дополнительный ноль в конец списка кнопок, если ваше условие (условие 4) не выполнено.

Я успешно проверил это на iOS7.

...