2009-10-21 10 views
54

Il costruttore di UIAlertSheet assume un parametro otherButtonTitles come elenco di varg. Vorrei invece specificare gli altri titoli dei pulsanti da un NSArray. È possibile?Utilizzare NSArray per specificare otherButtonTitles?

cioè che devo fare questo:

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

Ma dal momento che sto generando l'elenco dei pulsanti disponibili in fase di runtime, voglio davvero qualcosa di simile:

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

In questo momento, mi Sto pensando che ho bisogno di avere una chiamata separata a initWithTitle: per 1 oggetto, 2 articoli e 3 articoli. Come questo:

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 
} 

Questo è un sacco di codice duplicato, ma potrebbe in realtà essere ragionevole dal momento che ho al massimo tre pulsanti. Come posso evitare questo?

risposta

72

Questo è un anno vecchio, ma la soluzione è abbastanza semplice ... fare come suggerito @Simon ma non specificare un titolo pulsante di annullamento, così:

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

Ma dopo aver aggiunto i tuoi normali pulsanti , aggiungere il pulsante annulla, come:

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

[alert addButtonWithTitle:cancelString]; 

Ora il passo fondamentale è quello di specificare quale pulsante è il pulsante di annullamento, come:

alert.cancelButtonIndex = [titles count]; 

Facciamo [titles count] e non [titles count] - 1 perché stiamo aggiungendo il pulsante Annulla come extra dall'elenco di pulsanti in titles.

Ora si specifica anche quale pulsante si desidera essere il pulsante distruttivo (ovvero il pulsante rosso) specificando il distructiveButtonIndex (in genere quello sarà il pulsante [titles count] - 1). Inoltre, se si mantiene il pulsante Annulla come ultimo pulsante, iOS aggiungerà quella piacevole spaziatura tra gli altri pulsanti e il pulsante Annulla.

Tutti questi sono compatibili con iOS 2.0 quindi divertiti.

+0

Non sono sicuro del motivo per cui ha funzionato per te, ma dovevo fare "[titoli count] - 1" perché funzioni per me, iOS 7. – Micah

+1

[alert numberOfButtons] -1 è un altro modo per impostare l'indice del pulsante di annullamento – Keith

+2

Minore nota: utilizzando i nomi che hai stabilito qui, penso che 'sheet.cancelButtonIndex' dovrebbe essere' alert.cancelButtonIndex', sì? – Matt

52

Invece di aggiungere i pulsanti quando si inizializza UIActionSheet, provare ad aggiungerli con il metodo addButtonWithTitle utilizzando un ciclo for che passa attraverso il proprio NSArray.

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

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

più semplice: 'for (NSString * titolo nei titoli) {[alert addButtonWithTitle: title]; } 'Non è necessario creare un enumeratore. –

+3

Questo fa apparire i pulsanti DOPO il pulsante Annulla. Qualche modo per sistemare questo @bent o @simon? (vedi modifica su http://stackoverflow.com/questions/7781022) –

+1

Prova ad usare la proprietà '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: restituisce l'indice del pulsante aggiunto. Impostare cancelButtonTitle a zero nel metodo init e dopo l'aggiunta di ulteriori pulsanti gestiscono questo:

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

È possibile aggiungere il pulsante Annulla e impostare in questo modo:

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

So che questo è un vecchio post, ma nel caso che qualcun altro, come me, stia cercando di capirlo.

(Questo è stato risposto da @kokemomuke. Questa è principalmente una spiegazione più dettagliata.Anche sulla base @Ephraim e @Simon)

Si scopre che il LAST ingresso di addButtonWithTitle: deve essere il pulsante Cancel. Vorrei usare:

// 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;