2013-04-22 17 views
9

Jestem w sytuacji, w której myślę, że jestem bliski rozwiązania, ale może nie.Przekazywanie parametrów do akcji Selektora

Mam widok tabeli niestandardowych komórek widoku tabeli.

Obecnie każdy plik tableviewcell ma 3 uybuttons, dostęp do nich i nadawanie im funkcjonalności nie stanowi problemu.

Jeden z 3 przycisków, z którymi mam problemy. Przycisk przesuwa użytkownika z bieżącego kontrolera nawigacyjnego do kontrolera podglądu strony internetowej, ale chcę, aby kontroler podglądu strony był adresem http, w którym aktualnie znajduje się komórka widoku tabeli.

Oto mała snippit kodu, którego używam.

- (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"); 
} 

Widziałem kilka innych opinii na to samo pytanie, ale jak powiedziałem, po prostu trzeba przekazać jeden parametr do selektora, rozumiem, że nie jest to możliwe, ale jakie inne sposoby mogę iść o tym problemie ?

Może moje pytanie jest źle sformułowane: /.

Każda pomoc będzie wielki :)

EDIT: Rozumiem [cell.buyTicketOutlet addTarget:self action:@selector(pushToTicketURL:string) forControlEvents:UIControlEventTouchUpInside]; daje błędy. Ale co mogę zrobić, by kodować, aby robić to, co chcę?

Odpowiedz

14

Chociaż nie można przekazać adresu URL bezpośrednio do selektora, można przekazać sam przycisk. Więc moja propozycja będzie przycisk, aby oznaczyć zależności od wiersza komórki i tworzyć działania takiego:

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

wtedy, w tej metodzie można „patrzeć” URL z komórki o numerze równym tagu przycisku .

Poza tym jestem prawie pewien, że nie można przekazać parametrów niestandardowych lub więcej niż jednego parametru w selektorze przycisku. Proszę popraw mnie jeżeli się mylę.

Nadzieję, że pomaga.

+1

Daj mi znać, jeśli potrzebujesz pomocy w pisaniu tego kodu. – dmee3

+0

Wziąłem twoją radę i znalazłem link do kodu, żeby zrobić dokładnie to, co powiedziałeś. Działało :) – jsetting32

+2

Niestety, moja reputacja nie pozwala mi komentować innych odpowiedzi. jsetting32, fragment kodu, który podałeś jest naprawdę świetny i jest jeszcze lepszy sposób robienia tego niż robienie tagów. Świetna robota ^^ Odnosząc się do poniższego argumentu, Rob Napier miał rację. Właściwie wykorzystałbym jego podejście do dużych struktur danych, ponieważ jest znacznie bardziej zorganizowany. Ale ponieważ korzystałeś z superview zamiast tagów, powiedziałbym, żeby niczego nie zmieniać. Jest świetny tak jak jest! – dmee3

4

Potrzebujesz tylko : podczas przekazywania parametru do selektora, jeśli potrzebujesz przekazać jeden parametr.

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

Zasadniczo : oznacza, że ​​przechodzą arguement do selektora i na końcu odbierającym można określić metodę wyboru z obiektem.

+1

Nie wiedziałem o tym. To jest miłe. Dzięki za wskazówkę. –

+2

jak ta odpowiedź na pytanie? – newacct

+2

Co sprawia, że ​​myślisz, że nie służy to rozwiązaniu problemu? To miejsce jest pomocne w problemach, aby nie pisać całego kodu, OP miał problem z przekazaniem parametru do selektora, jeśli przeczytałeś dokładnie to pytanie. – nsgulliver

1

@ Podejście fDmitry'ego nie jest złe, ale są lepsze sposoby w nowoczesnym ObjC. Za pomocą powiązanych obiektów można dołączać dowolne obiekty (np. Adres URL) do innych obiektów (np. Przycisku). Możesz poprosić nadawcę (przycisk) o URL i przetworzyć go. Oto jeden ze sposobów, aby to zrobić:

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

z tym, po zaimportowaniu kategorię, możesz zadzwonić [button setMYURL:] ustawić adres na przycisku. Następnie możesz użyć [sender MYURL], aby pobrać go w IBAction.

+0

Która droga jest LEPSZA? Właśnie ukończyłem zadanie, wykorzystując pomysł fDmitry'ego i znalazłem kilka linków, które pozwoliły mi zaimplementować jego pseudo komentarz :). Ale czy twoje rozwiązanie jest bardziej wydajne? Chciałbym spróbować zrobić to samo, ale czy jest to konieczne, aby pójść ścieżką, którą sugerujesz? A jeśli masz na myśli nowocześniejsze, masz na myśli, że programiści Apple zazwyczaj podążają swoją drogą? Dzięki za twój wgląd :) – jsetting32

+1

Sędzią "lepszego" jest łatwość utrzymania i czytelność tutaj. Wykonanie tego za pomocą znacznika powoduje umieszczenie listy adresów URL w IBAction. Korzystanie z powiązanych obiektów umieszcza logikę w punkcie, w którym tworzy się widok. Powiązane obiekty usuwają potrzebę mapowania "losowej liczby" (tagu) na adres URL, ponieważ bezpośrednio wiążą widok z adresem URL. W większości przypadków jest to łatwiejsze do odczytania i utrzymywania. Ale nie oznacza to, że znaczniki są błędne, jeśli działają dobrze (znaczniki mają tę zaletę, że można je ustawiać w IB). Wydajność na tym poziomie jest nieistotna; rób to, co sprawia, że ​​twój kod jest łatwy do zrozumienia. –

+1

Kiedy mówię "nowoczesny", mam na myśli "od 10.6 i iPhoneOS 3.1." Tak więc w ciągu ostatnich 4 lat. Jeśli zachowujesz starsze rzeczy (tak jak ja), wtedy powiązane obiekty mogą być niedostępne. –

4

Odnosząc się do odpowiedzi fDmitry, w

Oto pełny kod użyłem do jego wyjaśnienia. Działa fenomenalnie :).Dziękuję Omar Abdelhafith, którego związek pomógł mi i fDmitry uzyskiwania mnie na właściwe tory :)

-(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]; 
} 

Ten fragment kodu pomógł mi tak bardzo i mam nadzieję, że ktoś pomaga którego przypada na ten sam problem :).

+1

Ah, utknąłeś dane na samej komórce. Przypuszczałem, że każdy przycisk wymaga osobnego adresu URL. Twoje podejście tutaj jest w porządku i bardzo łatwe w utrzymaniu. –

+1

jest to trochę niestabilne - polega na hierarchii widoku przycisku – newacct

Powiązane problemy