2013-04-22 63 views
9

我處於一種我認爲自己接近解決的情況,但也許不是。將參數傳遞給選擇器動作

我有一個自定義tableview單元格的tableview。

當前每個tableviewcell有3個uibuttons,訪問它們並賦予它們功能是沒有問題的。

我遇到問題的3個按鈕之一。該按鈕將用戶從當前導航控制器推送到一個webview控制器,但我希望webview控制器成爲當前tableview單元格所持有的http地址。

繼承人我正在使用的代碼的小snippit。

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

我看到的同樣的問題,其他一些評論,但就像我說的,我只需要一個參數傳遞給一個選擇,我知道那是不可能的,但我可以去對這個問題有什麼其他的方法?

也許我的問題措辭不妙:/。

任何幫助將是巨大的:)

編輯:據我所知[cell.buyTicketOutlet addTarget:self action:@selector(pushToTicketURL:string) forControlEvents:UIControlEventTouchUpInside];給出錯誤。但是我可以編寫什麼工作來做我想做的事?

回答

14

雖然您無法直接將URL傳遞給選擇器,但您可以傳遞按鈕本身。所以我的建議是根據你的行標記按鈕,創建這樣的動作:

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

然後,在方法,你可以從等於按鈕的標籤數量的細胞「查找」網址。

除此之外,我相當確定無法在按鈕的選擇器中傳遞自定義參數或多個參數。如果我錯了,請糾正我。

希望有所幫助。

+1

如果您需要編寫該代碼的幫助,請告訴我。 – dmee3 2013-04-22 20:07:48

+0

我接受了你的建議,並找到了一個正確的代碼鏈接來完成你所說的話。它的工作:) – jsetting32 2013-04-22 20:45:36

+2

不幸的是,我的聲譽不允許我評論其他答案。 jsetting32,你提供的代碼片段確實很棒,甚至比做標籤更好。偉大的工作^^ 關於下面的論點,羅布納皮爾提出了一個很好的觀點。我實際上使用他的方法處理大量的數據結構,因爲它更加有組織。但既然你最終使用超級景觀而不是標籤,我會說不改變任何東西。這是偉大的! – dmee3 2013-04-22 21:52:15

4

如果您需要傳遞一個參數,那麼在將參數傳遞給選擇器時,您只需要:

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

基本上:意味着要傳遞一個arguement到選擇器和在接收端可以定義與該對象的選擇方法。

+1

我不知道。那很整齊。謝謝你的提示。 – 2013-04-22 20:57:06

+2

這是如何回答這個問題的? – newacct 2013-04-22 22:40:02

+2

是什麼讓你認爲它不能達到解決問題的目的?這個地方是爲了幫助你解決問題,而不是寫所有的代碼,如果你仔細閱讀了這個問題,OP在傳遞參數的時候會遇到問題。 – nsgulliver 2013-04-22 22:52:07

1

@ fDmitry的方法並不差,但現代的ObjC有更好的方法。使用關聯對象,您可以將任意對象(即您的URL)附加到其他對象(即您的按鈕)。您可以向發件人(按鈕)詢問URL並處理它。下面是做這件事:

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

就這樣,輸入你的類別後,你可以調用[button setMYURL:]設置URL上的按鈕。然後您可以使用[sender MYURL]在IBAction中獲取它。

+0

哪種方式更好?我其實剛剛通過使用fDmitry的想法完成了任務,發現了幾個允許我實現他的僞註釋的鏈接:)。但是您的解決方案更高效嗎?我想嘗試做你自己的方式,但有必要走你的建議路徑嗎?而當你的意思更現代化時,你的意思是蘋果開發者通常會用你的方式?感謝您的洞察力:) – jsetting32 2013-04-22 20:49:04

+1

「更好」的判斷是可維護性和可讀性。使用標籤進行處理將URL列表放入IBAction中。使用關聯的對象會將邏輯置於創建視圖的位置。關聯對象消除了將「隨機數」(標記)映射到URL的需求,因爲它們直接將視圖綁定到URL。在大多數情況下,這更容易閱讀和維護。但這並不意味着如果標籤運行良好(標籤具有可在IB中設置的優勢)就不會出錯。這個層面的效率是無關緊要的;做你的代碼容易理解的地方。 – 2013-04-22 20:54:40

+1

當我說「現代」時,我的意思是「從10.6和iPhoneOS 3.1開始」。所以,在過去的4年左右。如果你維護比這更早的東西(和我一樣),那麼關聯的對象可能不可用。 – 2013-04-22 20:59:52

4

指的fDmitry的迴應,

下面是我用他的解釋的全部代碼。它工作正常:)。謝謝奧馬爾Abdelhafith,其鏈接幫助我,併爲fDmitry讓我在正確的軌道:)

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

上的這段代碼幫助了我這麼多,希望它可以幫助其他人,其落入了同樣的問題:)。

+1

啊,你把數據粘貼到單元格本身上。我記得每個按鈕都需要一個單獨的URL。你的方法很好,而且很容易維護。 – 2013-04-22 21:03:06

+1

這是一種脆弱的 - 它依賴於按鈕的視圖層次結構 – newacct 2013-04-22 22:41:41