Создайте UIActionSheet 'otherButtons', передав массив, а не список переменных

110

У меня есть массив строк, которые я хочу использовать для заголовков кнопок в UIActionSheet. К сожалению, аргумент otherButtonTitles: при вызове метода принимает список строк переменной длины, а не массив.

Итак, как я могу передать эти заголовки в UIActionSheet? Предложенный мной обходной путь - передать nil в otherButtonTitles :, а затем указать заголовки кнопок индивидуально с помощью addButtonWithTitle :. Но при этом возникает проблема перемещения кнопки «Отмена» на первую позицию в UIActionSheet, а не на последнюю; Я хочу, чтобы он был последним.

Есть ли способ 1) передать массив вместо списка переменных строк или 2) переместить кнопку отмены в нижнюю часть таблицы UIActionSheet?

Спасибо.

Грег Малетик
источник
не уверен, что это сработает, но свойство cancelButtonIndex UIActionSheet не доступно только для чтения. Попробуйте установить его и посмотрите, изменится ли при этом порядок кнопок?
lostInTransit 05

Ответы:

248

Я заставил это работать (вам просто нужно, быть в порядке с обычной кнопкой, и просто добавьте ее после:

NSArray *array = @[@"1st Button",@"2nd Button",@"3rd Button",@"4th Button"];

    UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"Title Here"
                                                             delegate:self
                                                    cancelButtonTitle:nil
                                               destructiveButtonTitle:nil
                                                    otherButtonTitles:nil];

    // ObjC Fast Enumeration
    for (NSString *title in array) {
        [actionSheet addButtonWithTitle:title];
    }

    actionSheet.cancelButtonIndex = [actionSheet addButtonWithTitle:@"Cancel"];

    [actionSheet showInView:self.view];
прививка
источник
19
Это работает; Спасибо. Не понимал, что можно установить свойство cancelButtonIndex. В одном, я думаю, мы все можем согласиться: API Apple для этого - отстой.
Грег Малетик, 05
11
Я поддерживаю это! И 99,99% их документации тоже отстой. Это все равно, что пытаться изучить операцию на головном мозге по книге, написанной на архаичном иврите, не зная этого языка.
Duck
4
Я очень хотел бы проголосовать так много раз. Потрясающий ответ, и я не могу поверить, что так долго не знал об этом!
mattjgalloway
1
@JimThio cancelButtonне красный. destructiveButtonКрасный.
Armin
1
К сожалению, это решение страдает ошибкой в ​​UIActionSheet, [UIActionSheet addButtonWithTitle]которая, похоже, неправильно установлена firstOtherButtonIndex(которую следует использовать в делегате, actionSheet:clickedButtonAtIndex:а не в жестком кодировании 0 или подобном). Неприязнь с преобразованием NSArrayв va_listне звучит как хорошее решение. :-( Этот API чертовски уродлив.
Дэниел Ринсер
78

Одно небольшое примечание: [actionSheet addButtonWithTitle:] возвращает индекс этой кнопки, поэтому для безопасности и «чистоты» вы можете сделать следующее:

actionSheet.cancelButtonIndex = [actionSheet addButtonWithTitle:@"Cancel"];
Ник
источник
При этом кнопка отмены станет красной?
user4951
1
@JimThio Нет, красная кнопка называется «destructiveButton», и есть соответствующее свойство destructiveButtonIndexдля него
Ник
3

Взяв ответы Джабы и Ника и расширив их немного дальше. Чтобы включить в это решение кнопку разрушения:

// Create action sheet
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:title
                                                         delegate:self
                                                cancelButtonTitle:nil
                                           destructiveButtonTitle:nil
                                                otherButtonTitles:nil];
// Action Buttons
for (NSString *actionName in actionNames){
    [actionSheet addButtonWithTitle: actionName];
}

// Destruction Button
if (destructiveName.length > 0){
    [actionSheet setDestructiveButtonIndex:[actionSheet addButtonWithTitle: destructiveName]];
}

// Cancel Button
[actionSheet setCancelButtonIndex: [actionSheet addButtonWithTitle:@"Cancel"]];

// Present Action Sheet
[actionSheet showInView: self.view];
Стивен Доннелл
источник
1

Есть быстрый вариант ответа:

//array with button titles
private var values = ["Value 1", "Value 2", "Value 3"]

//create action sheet
let actionSheet = UIActionSheet(title: nil, delegate: self, cancelButtonTitle: nil, destructiveButtonTitle: nil)
//for each value in array
for value in values{
    //add a button
    actionSheet.addButtonWithTitle(value as String)
}
//display action sheet
actionSheet.showInView(self.view)

Чтобы выбрать значение, добавьте делегата в ViewController:

class MyViewController: UIViewController, UIActionSheetDelegate

И реализуем метод clickedButtonAtIndex

func actionSheet(actionSheet: UIActionSheet, clickedButtonAtIndex buttonIndex: Int) {
    let selectedValue : String = values[buttonIndex]
}
Кевин АБРИОУКС
источник
Для будущих пользователей ... Это сработало ... но устарело ... используйте stackoverflow.com/a/41322537/884674
jeet.chanchawat