1

I would like to solve the problem of array from URLs. I use JSON in my app and I have an array of cells. My goal: if you click in any cell, page will open in Safari with URL from JSON array.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellIdentifier =@"LocationCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: cellIdentifier];
    Location *location = [_locations objectAtIndex:indexPath.row];

    //...

    myCell.userInteractionEnabled = YES;
    UITapGestureRecognizer *gestureRec = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(openUrl:)];
    gestureRec.numberOfTouchesRequired = 1;
    gestureRec.numberOfTapsRequired = 1;
    [myCell addGestureRecognizer:gestureRec];

    return cell;
}

- (void) openUrl: (id)sender: (Location *) location {
    UIGestureRecognizer *rec = (UIGestureRecognizer *)sender;
    id hitLabel = [self.view hitTest:[rec locationInView:self.view] withEvent:UIEventTypeTouches];

    if ([hitLabel isKindOfClass:[UILabel class]]) {
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString: location.url]];
    }
}

Something wrong, because the app crashes with this error:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ViewController openUrl:]: unrecognized selector sent to instance 0x7fd3a850ad40'

But if I write in UITableViewCell this:

[[UIApplication sharedApplication] openURL:[NSURL URLWithString: location.url]];

links will open in Safari immediately when the application starts. So I think that JSON parsing is correct.

2
  • Somewhere, you're managing to send the openURL: message to whatever class is your ViewController class rather than to your UIApplication. Commented May 26, 2015 at 21:09
  • I think it's worth mentioning that the syntax of -openURL:sender:location is... well, strange to say the least. It generates the following warning: 'sender used as the name of the previous parameter rather than as part of the selector'. Commented May 26, 2015 at 21:14

1 Answer 1

3

You have implemented this method in your ViewController

- (void) openUrl:(id) sender:(Location *)location

but you are assigning

@selector(openUrl:)

as the target of the gesture recognizers. This is another method, because the sender parameter is missing.

That said, you don't need the gesture recognizers; just implement the didSelectRowAtIndexPath: method of UITableViewDelegate:

- (void)tableView:(UITableView)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
     Location *location = [_locations objectAtIndex:indexPath.row];
     [[UIApplication sharedApplication] openURL:[NSURL URLWithString: location.url]];
}

(If you really want the URL to open only if the user taps the label, not the rest of the cell, you do need the gesture recognizers. This is very bad UX, though.)

Sign up to request clarification or add additional context in comments.

1 Comment

Wow, it really works! Awesome! Thank you so much, Glorfindel!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.