Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing Parameters to Selector action

I am in a situation where I think I am close to solving, but maybe not.

I have a tableview of custom tableview cells.

Currently each tableviewcell has 3 uibuttons, accessing them and giving them functionality is no problem.

One of the 3 buttons I'm having problems with. The button pushes the user from the current navigation controller to a webview controller, but I want the webview controller to be the http address the current tableview cell is holding.

Heres a small snippit of the code I'm using.

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

I have seen some other reviews on the same question but like I said, I just need to pass one parameter to a selector, I understand that is not possible, but what other ways can I go about this problem?

Maybe my question is badly worded :/.

Any help will be great :)

EDIT: I understand [cell.buyTicketOutlet addTarget:self action:@selector(pushToTicketURL:string) forControlEvents:UIControlEventTouchUpInside]; gives errors. But what work around can I code to do what I want?

like image 216
jsetting32 Avatar asked Apr 22 '13 19:04

jsetting32


4 Answers

While you can not pass the URL directly to the selector, you can pass the button itself. So my suggestion would be to tag button according to your cell row and create action like this:

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

Then, in that method you can "look up" URL from the cell with the number equal to tag of the button.

Other than that, I am fairly sure it's impossible to pass custom parameters or more than one parameter in button's selector. Please correct me if I'm wrong.

Hope that helps.

like image 188
dmee3 Avatar answered Oct 09 '22 19:10

dmee3


You just need : when passing parameter to a selector if you need to pass one parameter.

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

Basically : means you are passing an arguement to the selector and on the receiving end you could define your selector method with the object.

like image 30
nsgulliver Avatar answered Oct 09 '22 20:10

nsgulliver


Refering to fDmitry's response,

Here's the full code I used for his explanation. It works phenomally :). Thank you to the Omar Abdelhafith, whose link helped me, and fDmitry for getting me on the right track :)

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

This snippet of code helped me so much and hope it helps anyone else whose falls into the same problem :).

like image 31
jsetting32 Avatar answered Oct 09 '22 19:10

jsetting32


@fDmitry's approach isn't bad, and but there are better ways in modern ObjC. Using associated objects, you can attach arbitrary objects (i.e. your URL) to other objects (i.e. your button). You can the ask the sender (the button) for the URL and process it. Here's one way to do it:

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

With that, after importing your category, you can call [button setMYURL:] to set the URL on the button. You can then use [sender MYURL] to fetch it in the IBAction.

like image 38
Rob Napier Avatar answered Oct 09 '22 20:10

Rob Napier