UITableView pushViewController On Selecting a Row

18,271

Solution 1

As others have said, the general idea is to have a property on FirstViewController that stores the URL it needs to load, and then load that URL into the UIWebView when the view appears.

Here's an example of what it might look like, starting with the header:

@interface FirstViewController : UIViewController {
  UIWebView *webView;
  NSURL *storyURL;
}
@property (nonatomic, retain) IBOutlet UIWebView *webView; // this is set up in your nib
@property (nonatomic, retain) NSURL *storyURL;
@end

Now for the implementation:

@implementation FirstViewController

@synthesize webView;
@synthesize storyURL;

- (void)dealloc;
{
  [storyURL release]; // don't forget to release this
  [super dealloc];
}

- (void)viewDidAppear:(BOOL)animated;
{
  // when the view appears, create a URL request from the storyURL
  // and load it into the web view
  NSURLRequest *request = [NSURLRequest requestWithURL:self.storyURL];
  [self.webView loadRequest:request];
}

- (void)viewWillDisappear:(BOOL)animated;
{
  // there is no point in continuing with the request load
  // if somebody leaves this screen before its finished
  [self.webView stopLoading];
}
@end

So now all you need to do in the controller for the previous view is get the story URL, pass it on to FirstViewController and push it.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath  {
  NSDictionary *story = [stories objectAtIndex:[indexPath row]]; 
  NSURL *storyURL = [NSURL URLWithString:[story objectForKey:@"link"]];
  FirstViewController *firstViewController = [[FirstViewController alloc] initWithNibName:@"FirstView" bundle:[NSBundle mainBundle]]; // I'm pretty sure you don't need to pass in the main bundle here
  firstViewController.storyURL = storyURL;
  [self.navigationController pushViewController:firstViewController animated:YES];
  [firstViewController release]; // don't leak memory
}

And that's about it. A few other points:

  • I assume the "link" value in your dictionary is already a string - the construction of a brand new string in your original example was unnecessary if this is the case. As you can see in my example, we can use this string directly to create the NSURL instance.

  • In your original code, when you alloc/init your FirstViewController, you pass this straight into pushViewController. This creates a memory leak as once UINavigationController is done with it (after it gets popped off the navigation stack), it's retain count will still be 1. At the least you should call autorelease but the most efficient thing to do here is simply alloc/init it, store it in a temp variable, then call release straight after we've pushed it. This ensures that once it gets popped off the navigation stack, it will get deallocated.

Solution 2

First off, do you have a nib named "FirstView" in your project?

Second, the way I've usually done this is to instantiate the ViewController and pass the parameters to it before pushing it onto the nav stack.

UIViewController *myViewController = [[FirstViewController alloc] initWithNibName:@"FirstView" bundle:[NSBundle mainBundle]];
myViewController.story = storyLink;
[[self navigationController] pushViewController:myViewController animated:YES];
Share:
18,271
Benji Barash
Author by

Benji Barash

Working on autonomous flying robots at Amazon Prime Air. Interested in machine learning, simulation and computer vision.

Updated on June 04, 2022

Comments

  • Benji Barash
    Benji Barash almost 2 years

    I'm building an iPhone app with a UITableView. On selecting a row, I'd like a UIWebView to be pushed in loading a specific URL.

    I currently have:

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath  {
    NSDictionary * story = [stories objectAtIndex:[indexPath row]]; 
    NSString * storyLink = [NSString stringWithFormat:[story objectForKey:@"link"]];
    
        [[self navigationController] pushViewController:[[FirstViewController alloc] initWithNibName:@"FirstView" bundle:[NSBundle mainBundle]] animated:YES];
    }
    

    How can I get the new view that slides in to contain a UIWebView and subsequently load story link into it via:

    loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:storyLink]]
    

    Thanks in advance,

    Benji