2013-04-22 11 views
9

Sono in una situazione in cui penso di essere vicino a risolvere, ma forse no.Passare i parametri all'azione del selettore

Ho una vista tabella di celle tableview personalizzate.

Attualmente ogni tableviewcell ha 3 uibutton, accedervi e dare loro la funzionalità non è un problema.

Uno dei 3 pulsanti con cui ho problemi. Il pulsante spinge l'utente dal controller di navigazione corrente a un controller webview, ma voglio che il controller webview sia l'indirizzo http che la cella corrente della tabella mostra.

Ecco un piccolo snippit del codice che sto utilizzando.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *cellIdentifier = @"Identifier"; 

    SearchTableCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 

    if (cell == nil) { 
     NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"SearchTableCell" owner:nil options:nil]; 
     //cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:reuseIdentifier]; 
     for(id currentObject in topLevelObjects) 
     { 
      if([currentObject isKindOfClass:[SearchTableCell class]]) 
      { 
       cell = (SearchTableCell *)currentObject; 
       break; 
      } 
     } 
    } 


    Player *event = [_party.events objectAtIndex:indexPath.row]; 
    cell.EventTitle.text = event.name; 
    cell.EventDescription.text = event.description; 
    cell.EventStartTime.text = event.start_date; 
    cell.EventEndTime.text = event.end_date; 
    cell.EventTicketURL = event.ticketURL; 

    NSString *string = event.ticketURL; 

    [cell.buyTicketOutlet addTarget:self action:@selector(pushToTicketURL:string) forControlEvents:UIControlEventTouchUpInside]; 
    //[cell.AddEventOutlet addTarget:self action:@selector(:) forControlEvents:UIControlEventTouchUpInside]; 
    //cell.textLabel.numberOfLines = 2; 
    return cell; 
} 




- (void) pushToTicketURL:(NSString *)string 
{ 

    UIViewController *webViewController = [[UIViewController alloc] init]; 
    webViewController.title = @"Tickets"; 
    UIWebView *uiWebView = [[UIWebView alloc] initWithFrame: CGRectMake(0,0,320,370)]; 

    [uiWebView loadRequest:[NSURLRequest requestWithURL: [NSURL URLWithString:string]]]; 

    [webViewController.view addSubview:uiWebView]; 
    [uiWebView release]; 

    [self.navigationController pushViewController:webViewController animated:YES]; 
    NSLog(@"Button pressed"); 
} 

Ho visto alcune altre recensioni sulla stessa domanda, ma come ho detto, ho solo bisogno di passare un parametro ad un selettore, ho capito che non è possibile, ma quali altri modi posso andare su questo problema ?

Forse la mia domanda è mal formulata: /.

Qualsiasi aiuto sarà grande :)

EDIT: ho capito [cell.buyTicketOutlet addTarget:self action:@selector(pushToTicketURL:string) forControlEvents:UIControlEventTouchUpInside]; dà errori. Ma cosa può aggirare il codice per fare ciò che voglio?

risposta

14

Mentre non è possibile passare l'URL direttamente al selettore, è possibile passare il pulsante stesso. Quindi il mio suggerimento sarebbe pulsante per contrassegnare in base alla tua linea cellulare e creare l'azione come questo:

void goToAddress: (id) sender { 
    UIButton *button = (UIButton*) sender; 
    if (button.tag == ..) { 
    ... 
    } 
} 

Allora, in quel metodo è possibile "guardare in alto" URL dalla cella con il numero pari al tag del pulsante .

Oltre a ciò, sono abbastanza sicuro che è impossibile passare parametri personalizzati o più di un parametro nel selettore di pulsanti. Per favore correggimi se sbaglio.

Spero che questo aiuti.

+1

Fammi sapere se hai bisogno di aiuto per scrivere quel codice. – dmee3

+0

Ho seguito il tuo consiglio e ho trovato un link diretto al codice per fare esattamente quello che hai detto. Ha funzionato :) – jsetting32

+2

Sfortunatamente, la mia reputazione non mi consente di commentare altre risposte. jsetting32, lo snippet del codice che hai fornito è davvero ottimo ed è anche un modo migliore di farlo, piuttosto che fare tag. Ottimo lavoro ^^ Per quanto riguarda l'argomento qui sotto, Rob Napier ha fatto un buon punto. In realtà utilizzerei il suo approccio con grandi strutture di dati, in quanto è molto più organizzato. Ma dal momento che hai finito con l'utilizzo di superview anziché tag, direi di non cambiare nulla. È fantastico così com'è! – dmee3

4

Per passare un parametro a un selettore è necessario solo il : se è necessario passare un parametro.

[cell.buyTicketOutlet addTarget:self action:@selector(pushToTicketURL:) forControlEvents:UIControlEventTouchUpInside]; 

Fondamentalmente : significa che sta passando un arguement al selettore e sul lato di ricezione è possibile definire il metodo selettore con l'oggetto.

+1

Non lo sapevo. È pulito Grazie per il consiglio. –

+2

come risponde la domanda? – newacct

+2

Cosa ti fa pensare che non abbia lo scopo di risolvere il problema? Questo posto è di aiuto nei problemi di non scrivere tutto il codice, OP ha avuto problemi nel passare il parametro a un selettore se hai letto attentamente la domanda. – nsgulliver

1

L'approccio di fDmitry non è male, ma ci sono modi migliori nel moderno ObjC. Usando oggetti associati, puoi allegare oggetti arbitrari (ad es. Il tuo URL) ad altri oggetti (ad esempio il tuo pulsante). Puoi chiedere al mittente (il pulsante) l'URL e elaborarlo. Ecco un modo per farlo:

// Create a category. The "MY" is just a prefix for your namespace 
@interface UIButton (MYURLAdditions) 
@property (nonatomic, readwrite, strong) NSURL *MYURL; 
@end 

// Add the information with a associated object 

#import <objc/runtime.h> 
@implementation (MYURLAdditions) 

static char MYURLKey; 
- (NSURL *)MYURL { 
    return objc_getAssociatedObject(self, &MYURLKey); 
} 

- (void)setMYURL:(NSURL *)URL { 
    objc_setAssociatedObject(obj, &MYURLKey, URL, OBJC_ASSOCIATION_RETAIN); 
} 

Con questo, dopo aver importato la categoria, è possibile chiamare [button setMYURL:] per impostare l'URL sul pulsante. È quindi possibile utilizzare [sender MYURL] per recuperarlo in IBAction.

+0

Quale strada è BETTER? In realtà ho appena completato l'operazione utilizzando l'idea di fDmitry e trovato diversi collegamenti che mi hanno permesso di implementare il suo pseudo commento :). Ma la tua soluzione è più efficiente? Mi piacerebbe provare a fare anche tu la tua strada ma è necessario, per seguire il percorso che stai suggerendo? E quando intendi qualcosa di più moderno, intendi che gli sviluppatori Apple di solito vanno dalla tua parte? Grazie per la tua comprensione :) – jsetting32

+1

Il giudice di "migliore" è manutenibilità e leggibilità qui. Farlo con un tag mette la lista di URL in IBAction. L'utilizzo di oggetti associati mette la logica nel punto in cui si crea la vista. Gli oggetti associati rimuovono la necessità di una mappatura del "numero casuale" (tag) all'URL perché collegano direttamente la vista all'URL. Nella maggior parte dei casi è più facile da leggere e mantenere. Ma questo non significa che i tag siano sbagliati se funzionano bene (i tag hanno il vantaggio di essere configurabili in IB). L'efficienza a questo livello è irrilevante; fai ciò che rende il tuo codice facile da capire. –

+1

Quando dico "moderno" intendo "dal 10.6 e iPhoneOS 3.1". Quindi, negli ultimi 4 anni circa. Se mantieni cose più vecchie (come faccio io), allora gli oggetti associati potrebbero non essere disponibili. –

4

Facendo riferimento alla risposta di fDmitry,

Ecco il codice completo che ho usato per la sua spiegazione. Funziona fenomenalmente :).Grazie alla Omar Abdelhafith, il cui link mi ha aiutato, e fDmitry per me ottenere sulla strada giusta :)

-(void)pushToTicketURL:(id)sender{ 
    UIButton *button = (UIButton*)sender; 
    UIView *view = button.superview; //Cell contentView 
    SearchTableCell *cell = (SearchTableCell *)view.superview; 
    NSLog(@"%@",cell.EventTitle.text); //Cell Text 

    UIViewController *webViewController = [[UIViewController alloc] init]; 
    webViewController.title = cell.EventTitle.text; 
    [webViewController.title sizeWithFont:10]; 
    UIWebView *uiWebView = [[UIWebView alloc] initWithFrame: CGRectMake(0,0,320,370)]; 

    [uiWebView loadRequest:[NSURLRequest requestWithURL: [NSURL URLWithString:cell.EventTicketURL]]]; 

    [webViewController.view addSubview:uiWebView]; 
    [uiWebView release]; 

    [self.navigationController pushViewController:webViewController animated:YES]; 
} 

questo frammento di codice mi ha aiutato tanto e spero che aiuta chiunque altro la cui cade lo stesso problema :).

+1

Ah, hai bloccato i dati sulla cella stessa. Mi ero messo in mente che ogni pulsante necessitava di un URL separato. Il tuo approccio qui è perfetto e molto semplice da mantenere. –

+1

questo è un po 'fragile - si basa sulla gerarchia della vista del pulsante – newacct