Search code examples
iphoneiosxcodersswebview

RSS Reader not displaying selected Cell in WebView


I've been trying to make a simple RSS Reader app following this tutorial.

The tutorial had to be adapted a bit because I'm using Xcode 4.3.2. Everything works, it loads all the RSS feeds fine, but when i click on a article to view it, the detail view controller loads but its completely blank. Ive tried adding a label or a button to the DetailViewController on the storyboard but even these don't appear when it loads. The only thing that is visible is the navigation bar at the top. So my question is what am i doing wrong? I'm sure its a simple setup problem, rather than a problem with the code. The fact i can add any object to the view and there not displayed its almost like a completely different view controller is being loaded. Any help would be greatly appreciated. Heres the code I've been using:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
_webViewController.entry = entry;
[self.navigationController pushViewController:_webViewController animated:YES];

}


- (void)viewDidLoad
{

NSURL *url = [NSURL URLWithString:_entry.articleUrl];    
[self.webView loadRequest:[NSURLRequest requestWithURL:url]];
NSLog(@"The URL is %@",url);


}

Because this code was adapted from a older version of Xcode, has it got something to do with the storyboard instead of individual nib files?

Ok _webviewController is set in the RootViewController.h

@interface RootViewController : UITableViewController <UITableViewDelegate> {
NSOperationQueue *_queue;
NSArray *_feeds;
NSMutableArray *_allEntries;
DetailViewController *_webViewController;

}

@property (retain) NSOperationQueue *queue;
@property (retain) NSArray *feeds;
@property (retain) NSMutableArray *allEntries;
@property (retain) DetailViewController *webViewController;

didselectRowAtIndex is set in RootViewController & viewDidload is set in DetailViewController

Ive allready set up a push segue in the storyboard.

I have now replaced the tableView didSelectRowAtPath method with the one suggested below

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// test segue.identifier if needed
DetailViewController *viewController = segue.destinationViewController;
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
// set properties of viewController based on selection indexPath
RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
viewController.entry = entry;
}

Unfortunately even though this seems to work fine, I'm still getting a blank view.


Solution

  • There are multiple issues here.

    1. I don't see a place where you're setting _webViewController to anything before you attempt to push it on the navigation controller. This would be why you're seeing the "Application tried to push a nil view controller on target" error, and may be related to why you're seeing a blank view.

    2. Are the two methods you've quoted in your question both implemented in the same class? Presumably, didSelectRowAtIndexPath is in your table view controller (RootViewController in the Ray Wenderlich tutorial), and viewDidLoad is in the web view controller? If so, please include such information when asking questions. If not, that may be part of your problem.

    3. Most importantly, it sounds like you're trying to adapt the tutorial to use storyboards. On the plus side, this means you can do a lot of stuff in IB that you'd have to do in code otherwise. On the downside, this makes the program "flow" between view controllers a lot different, so it's a bit harder to interpret the tutorial.

    The main difference when using storyboards is that the storyboard is responsible for creating and pushing/presenting your view controllers. (Having the root view controller keep and reuse an instance of the web view controller was anti-pattern anyway.) Here's how you do things in the storyboard world:

    1. Assuming your storyboard already contains your root table view controller embedded in a navigation controller, put your web view controller on the storyboard by dragging a UIViewController out of the library and setting its class identity to your WebViewController.

    2. Control-drag from the prototype cell in your table view to the web view controller, and make it a Push segue:

      drag to create segue

    3. With the above, you can run your app and get from the table view to the web view (with no code -- yay!), but the web view doesn't know what URL to load. So, you'll need to put the following in your table view controller:

      - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
      {
          // test segue.identifier if needed
          WebViewController *viewController = segue.destinationViewController;
          NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
          // set properties of viewController based on selection indexPath
          RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
          viewController.entry = entry;
      }
      
    4. And then you'll need the web view controller to load the URL in its web view -- the viewDidLoad implementation you already have should be good for that.