2009-10-21 12 views
54

El constructor de UIAlertSheet toma un parámetro otherButtonTitles como una lista varg. Me gustaría especificar los otros títulos de botones de un NSArray en su lugar. es posible?¿Utiliza NSArray para especificar otherButtonTitles?

es decir, que tengo que hacer esto:

id alert = [[UIActionSheet alloc] initWithTitle: titleString 
            delegate: self 
            cancelButtonTitle: cancelString 
            destructiveButtonTitle: nil 
            otherButtonTitles: button1Title, button2Title, nil]; 

Pero ya que estoy generando la lista de botones disponibles en tiempo de ejecución, lo que realmente quiero algo como esto:

id alert = [[UIActionSheet alloc] initWithTitle: titleString 
             delegate: self 
           cancelButtonTitle: cancelString 
         destructiveButtonTitle: nil 
           otherButtonTitles: otherButtonTitles]; 

En este momento, Estoy pensando que necesito tener una llamada separada a initWithTitle: para 1 artículo, 2 artículos y 3 artículos. De esta manera:

if ([titles count] == 1) { 
    alert = [[UIActionSheet alloc] initWithTitle: titleString 
             delegate: self 
           cancelButtonTitle: cancelString 
          destructiveButtonTitle: nil 
           otherButtonTitles: [titles objectAtIndex: 0], nil]; 
} else if ([titles count] == 2) { 
    alert = [[UIActionSheet alloc] initWithTitle: titleString 
             delegate: self 
           cancelButtonTitle: cancelString 
          destructiveButtonTitle: nil 
           otherButtonTitles: [titles objectAtIndex: 0], [titles objectAtIndex: 1], nil]; 
} else { 
    // and so on 
} 

Eso es un montón de código duplicado, pero en realidad podría ser razonable ya que tengo un máximo de tres botones. ¿Cómo puedo evitar esto?

Respuesta

72

Este es un año de edad, pero la solución es bastante simple ... hacer lo que sugirió @Simon pero no especifica un título botón de cancelación, por lo que:

UIActionSheet *alert = [[UIActionSheet alloc] initWithTitle: titleString 
           delegate: self 
           cancelButtonTitle: nil 
           destructiveButtonTitle: nil 
           otherButtonTitles: nil]; 

Pero después de la adición de los botones normales , agregue el botón de cancelación, como:

for(NSString *title in titles) { 
    [alert addButtonWithTitle:title]; 
} 

[alert addButtonWithTitle:cancelString]; 

Ahora el paso clave es especificar qué botón es el botón de cancelación, como:

alert.cancelButtonIndex = [titles count]; 

Hacemos [titles count] y no [titles count] - 1 porque estamos agregando el botón cancelar como extra de la lista de botones en titles.

Ahora también especifica qué botón quiere que sea el botón destructivo (es decir, el botón rojo) especificando el destructiveButtonIndex (normalmente ese será el botón [titles count] - 1). Además, si mantiene el botón de cancelar como el último botón, iOS agregará ese espacio agradable entre los otros botones y el botón cancelar.

Todos estos son compatibles con iOS 2.0, así que disfruta.

+0

No estoy seguro de por qué funcionó para usted, pero tuve que hacer "[número de títulos] - 1" para que funcione para mí, iOS 7. – Micah

+1

[número de alerta de botones] -1 es otra forma de establecer el índice del botón cancelar – Keith

+2

Menor Nota: Usando los nombres que ha establecido aquí, creo que 'sheet.cancelButtonIndex' debería ser' alert.cancelButtonIndex', ¿sí? – Matt

52

En lugar de agregar los botones al inicializar UIActionSheet, intente agregarlos con el método addButtonWithTitle usando un ciclo for que pasa por su NSArray.

UIActionSheet *alert = [[UIActionSheet alloc] initWithTitle: titleString 
           delegate: self 
           cancelButtonTitle: cancelString 
           destructiveButtonTitle: nil 
           otherButtonTitles: nil]; 

for(NSString *title in titles) 
    [alert addButtonWithTitle:title]; 
+12

más fácil que eso: 'para (título de NSString * en títulos) {[alert addButtonWithTitle: title]; } 'No hay necesidad de crear un enumerador. –

+3

Esto hace que los botones aparezcan DESPUÉS del botón cancelar. ¿Alguna manera de arreglar esto @bent o @simon? (ver edición en http://stackoverflow.com/questions/7781022) –

+1

Intenta usar la propiedad 'cancelButtonIndex'. – Simon

4
- (void)showActionSheetWithButtons:(NSArray *)buttons withTitle:(NSString *)title { 

    UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle: title 
                  delegate: self 
                cancelButtonTitle: nil 
               destructiveButtonTitle: nil 
                otherButtonTitles: nil]; 

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

    [actionSheet addButtonWithTitle: @"Cancel"]; 
    [actionSheet setCancelButtonIndex: [buttons count]]; 
    [actionSheet showInView:self.view]; 
} 
6

addButtonWithTitle: devuelve el índice del botón agregado. Establecer cancelButtonTitle a cero en el método init y después de añadir botones adicionales ejecutar este:

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

Puedes añadir el botón de cancelación y establecer de esta manera:

[actionSheet setCancelButtonIndex: [actionSheet addButtonWithTitle: @"Cancel"]]; 
1

Sé que esto es una entrada antigua, pero en caso de que alguien más, como yo, intente resolver esto.

(Esto fue respondido por @kokemomuke. Esta es una explicación más detallada.Basándose también en @Ephraim y @Simon)

Resulta que el ÚLTIMO entrada de addButtonWithTitle: es necesario que haya el botón Cancel. Usaría:

// All titles EXCLUDING Cancel button 
for(NSString *title in titles) 
    [sheet addButtonWithTitle:title]; 


// The next two line MUST be set correctly: 
// 1. Cancel button must be added as the last entry 
// 2. Index of the Cancel button must be set to the last entry 

[sheet addButtonWithTitle:@"Cancel"]; 

sheet.cancelButtonIndex = titles.count - 1;